Merge "SELinuxNeverallowTestFrame: account for split sepolicy." into pi-dev
diff --git a/apps/CameraITS/pymodules/its/caps.py b/apps/CameraITS/pymodules/its/caps.py
index a0e704c..61ec7e1 100644
--- a/apps/CameraITS/pymodules/its/caps.py
+++ b/apps/CameraITS/pymodules/its/caps.py
@@ -470,9 +470,7 @@
     """
     physicalIdsList = []
     if logical_multi_camera(props):
-        physicalIds = props['android.logicalMultiCamera.physicalIds'];
-        physicalIdsString = ''.join(chr(e) for e in physicalIds);
-        physicalIdsList = filter(None, physicalIdsString.split('\x00'));
+        physicalIdsList = props['camera.characteristics.physicalCamIds'];
     return physicalIdsList
 
 def mono_camera(props):
diff --git a/apps/CameraITS/pymodules/its/cv2image.py b/apps/CameraITS/pymodules/its/cv2image.py
index 3020548..8cd7ca9 100644
--- a/apps/CameraITS/pymodules/its/cv2image.py
+++ b/apps/CameraITS/pymodules/its/cv2image.py
@@ -19,6 +19,7 @@
 import its.caps
 import its.device
 import its.error
+import its.image
 import numpy
 
 VGA_HEIGHT = 480
@@ -195,6 +196,112 @@
             self.ynorm = float(top_left[1]) / scene.shape[0]
 
 
+def get_angle(input_img):
+    """Computes anglular inclination of chessboard in input_img.
+
+    Angle estimation algoritm description:
+        Input: 2D grayscale image of chessboard.
+        Output: Angle of rotation of chessboard perpendicular to
+            chessboard. Assumes chessboard and camera are parallel to
+            each other.
+
+        1) Use adaptive threshold to make image binary
+        2) Find countours
+        3) Filter out small contours
+        4) Filter out all non-square contours
+        5) Compute most common square shape.
+            The assumption here is that the most common square instances
+            are the chessboard squares. We've shown that with our current
+            tuning, we can robustly identify the squares on the sensor fusion
+            chessboard.
+        6) Return median angle of most common square shape.
+
+    USAGE NOTE: This function has been tuned to work for the chessboard used in
+    the sensor_fusion tests. See images in test_images/rotated_chessboard/ for
+    sample captures. If this function is used with other chessboards, it may not
+    work as expected.
+
+    TODO: Make algorithm more robust so it works on any type of
+    chessboard.
+
+    Args:
+        input_img (2D numpy.ndarray): Grayscale image stored as a 2D
+            numpy array.
+
+    Returns:
+        Median angle of squares in degrees identified in the image.
+    """
+    # Tuning parameters
+    min_square_area = (float)(input_img.shape[1] * 0.05)
+
+    # Creates copy of image to avoid modifying original.
+    img = numpy.array(input_img, copy=True)
+
+    # Scale pixel values from 0-1 to 0-255
+    img *= 255
+    img = img.astype(numpy.uint8)
+
+    thresh = cv2.adaptiveThreshold(
+            img, 255, cv2.ADAPTIVE_THRESH_MEAN_C, cv2.THRESH_BINARY, 201, 2)
+
+    # Find all contours
+    contours = []
+    cv2_version = cv2.__version__
+    if cv2_version.startswith('2.4.'):
+        contours, _ = cv2.findContours(
+                thresh, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)
+    elif cv2_version.startswith('3.2.'):
+        _, contours, _ = cv2.findContours(
+                thresh, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)
+
+    # Filter contours to squares only.
+    square_contours = []
+
+    for contour in contours:
+        rect = cv2.minAreaRect(contour)
+        _, (width, height), angle = rect
+
+        # Skip non-squares (with 0.1 tolerance)
+        tolerance = 0.1
+        if width < height * (1 - tolerance) or width > height * (1 + tolerance):
+            continue
+
+        # Remove very small contours.
+        # These are usually just tiny dots due to noise.
+        area = cv2.contourArea(contour)
+        if area < min_square_area:
+            continue
+
+        if cv2_version.startswith('2.4.'):
+            box = numpy.int0(cv2.cv.BoxPoints(rect))
+        elif cv2_version.startswith('3.2.'):
+            box = numpy.int0(cv2.boxPoints(rect))
+        square_contours.append(contour)
+
+    areas = []
+    for contour in square_contours:
+        area = cv2.contourArea(contour)
+        areas.append(area)
+
+    median_area = numpy.median(areas)
+
+    filtered_squares = []
+    filtered_angles = []
+    for square in square_contours:
+        area = cv2.contourArea(square)
+        if area < median_area * 0.90 or area > median_area * 1.10:
+            continue
+
+        filtered_squares.append(square)
+        _, (width, height), angle = cv2.minAreaRect(square)
+        filtered_angles.append(angle)
+
+    if len(filtered_angles) < 10:
+        return None
+
+    return numpy.median(filtered_angles)
+
+
 class __UnitTest(unittest.TestCase):
     """Run a suite of unit tests on this module.
     """
@@ -224,6 +331,56 @@
         self.assertTrue(numpy.isclose(sharpness[4]/sharpness[8],
                                       numpy.sqrt(2), atol=0.1))
 
+    def test_get_angle_identify_unrotated_chessboard_angle(self):
+        basedir = os.path.join(
+                os.path.dirname(__file__), 'test_images/rotated_chessboards/')
+
+        normal_img_path = os.path.join(basedir, 'normal.jpg')
+        wide_img_path = os.path.join(basedir, 'wide.jpg')
+
+        normal_img = cv2.cvtColor(
+                cv2.imread(normal_img_path), cv2.COLOR_BGR2GRAY)
+        wide_img = cv2.cvtColor(
+                cv2.imread(wide_img_path), cv2.COLOR_BGR2GRAY)
+
+        assert get_angle(normal_img) == 0
+        assert get_angle(wide_img) == 0
+
+    def test_get_angle_identify_rotated_chessboard_angle(self):
+        basedir = os.path.join(
+                os.path.dirname(__file__), 'test_images/rotated_chessboards/')
+
+        # Array of the image files and angles containing rotated chessboards.
+        test_cases = [
+                ('_15_ccw', 15),
+                ('_30_ccw', 30),
+                ('_45_ccw', 45),
+                ('_60_ccw', 60),
+                ('_75_ccw', 75),
+                ('_90_ccw', 90)
+        ]
+
+        # For each rotated image pair (normal, wide). Check if angle is
+        # identified as expected.
+        for suffix, angle in test_cases:
+            # Define image paths
+            normal_img_path = os.path.join(
+                    basedir, 'normal{}.jpg'.format(suffix))
+            wide_img_path = os.path.join(
+                    basedir, 'wide{}.jpg'.format(suffix))
+
+            # Load and color convert images
+            normal_img = cv2.cvtColor(
+                    cv2.imread(normal_img_path), cv2.COLOR_BGR2GRAY)
+            wide_img = cv2.cvtColor(
+                    cv2.imread(wide_img_path), cv2.COLOR_BGR2GRAY)
+
+            # Assert angle is as expected up to 2.0 degrees of accuracy.
+            assert numpy.isclose(
+                    abs(get_angle(normal_img)), angle, 2.0)
+            assert numpy.isclose(
+                    abs(get_angle(wide_img)), angle, 2.0)
+
 
 if __name__ == '__main__':
     unittest.main()
diff --git a/apps/CameraITS/pymodules/its/device.py b/apps/CameraITS/pymodules/its/device.py
index cb3f51a..1c3c2c1 100644
--- a/apps/CameraITS/pymodules/its/device.py
+++ b/apps/CameraITS/pymodules/its/device.py
@@ -216,7 +216,7 @@
                 break
         proc.kill()
 
-    def __init__(self):
+    def __enter__(self):
         # Initialize device id and adb command.
         self.device_id = get_device_id()
         self.adb = "adb -s " + self.device_id
@@ -226,16 +226,12 @@
 
         self.__close_camera()
         self.__open_camera()
-
-    def __del__(self):
-        if hasattr(self, 'sock') and self.sock:
-            self.__close_camera()
-            self.sock.close()
-
-    def __enter__(self):
         return self
 
     def __exit__(self, type, value, traceback):
+        if hasattr(self, 'sock') and self.sock:
+            self.__close_camera()
+            self.sock.close()
         return False
 
     def __read_response_from_socket(self):
diff --git a/apps/CameraITS/pymodules/its/objects.py b/apps/CameraITS/pymodules/its/objects.py
index be9c4f59..9652bde 100644
--- a/apps/CameraITS/pymodules/its/objects.py
+++ b/apps/CameraITS/pymodules/its/objects.py
@@ -115,9 +115,10 @@
         #CONTRAST_CURVE mode
         if 0 in props["android.tonemap.availableToneMapModes"]:
             req["android.tonemap.mode"] = 0
-            req["android.tonemap.curveRed"] = [0.0,0.0, 1.0,1.0]
-            req["android.tonemap.curveGreen"] = [0.0,0.0, 1.0,1.0]
-            req["android.tonemap.curveBlue"] = [0.0,0.0, 1.0,1.0]
+            req["android.tonemap.curve"] = {
+                "red": [0.0,0.0, 1.0,1.0],
+                "green": [0.0,0.0, 1.0,1.0],
+                "blue": [0.0,0.0, 1.0,1.0]}
         #GAMMA_VALUE mode
         elif 3 in props["android.tonemap.availableToneMapModes"]:
             req["android.tonemap.mode"] = 3
@@ -228,12 +229,15 @@
     set_filter_off_or_fast_if_possible(props, req,
         "android.colorCorrection.availableAberrationModes",
         "android.colorCorrection.aberrationMode")
-    if props.has_key("android.request.availableCharacteristicsKeys"):
-        hot_pixel_modes = 393217 in props["android.request.availableCharacteristicsKeys"]
-        edge_modes = 196610 in props["android.request.availableCharacteristicsKeys"]
-    if props.has_key("android.request.availableRequestKeys"):
-        hot_pixel_mode = 393216 in props["android.request.availableRequestKeys"]
-        edge_mode = 196608 in props["android.request.availableRequestKeys"]
+    if props.has_key("camera.characteristics.keys"):
+        chars_keys = props["camera.characteristics.keys"]
+        hot_pixel_modes = \
+                "android.hotPixel.availableHotPixelModes" in chars_keys
+        edge_modes = "android.edge.availableEdgeModes" in chars_keys
+    if props.has_key("camera.characteristics.requestKeys"):
+        req_keys = props["camera.characteristics.requestKeys"]
+        hot_pixel_mode = "android.hotPixel.mode" in req_keys
+        edge_mode = "android.edge.mode" in req_keys
     if hot_pixel_modes and hot_pixel_mode:
         set_filter_off_or_fast_if_possible(props, req,
             "android.hotPixel.availableHotPixelModes",
diff --git a/apps/CameraITS/pymodules/its/target.py b/apps/CameraITS/pymodules/its/target.py
index 3715f34..01d3c5f 100644
--- a/apps/CameraITS/pymodules/its/target.py
+++ b/apps/CameraITS/pymodules/its/target.py
@@ -69,9 +69,8 @@
     # Use the gains+transform returned by the AWB pass.
     req = its.objects.manual_capture_request(sens, exp_time)
     req["android.tonemap.mode"] = 0
-    req["android.tonemap.curveRed"] = tmap
-    req["android.tonemap.curveGreen"] = tmap
-    req["android.tonemap.curveBlue"] = tmap
+    req["android.tonemap.curve"] = {
+        "red": tmap, "green": tmap, "blue": tmap}
     req["android.colorCorrection.transform"] = xform_rat
     req["android.colorCorrection.gains"] = gains
     cap = its_session.do_capture(req)
diff --git a/apps/CameraITS/pymodules/its/test_images/rotated_chessboards/normal.jpg b/apps/CameraITS/pymodules/its/test_images/rotated_chessboards/normal.jpg
new file mode 100644
index 0000000..e6418be
--- /dev/null
+++ b/apps/CameraITS/pymodules/its/test_images/rotated_chessboards/normal.jpg
Binary files differ
diff --git a/apps/CameraITS/pymodules/its/test_images/rotated_chessboards/normal_15_ccw.jpg b/apps/CameraITS/pymodules/its/test_images/rotated_chessboards/normal_15_ccw.jpg
new file mode 100644
index 0000000..fa921c2
--- /dev/null
+++ b/apps/CameraITS/pymodules/its/test_images/rotated_chessboards/normal_15_ccw.jpg
Binary files differ
diff --git a/apps/CameraITS/pymodules/its/test_images/rotated_chessboards/normal_30_ccw.jpg b/apps/CameraITS/pymodules/its/test_images/rotated_chessboards/normal_30_ccw.jpg
new file mode 100644
index 0000000..907f0d2
--- /dev/null
+++ b/apps/CameraITS/pymodules/its/test_images/rotated_chessboards/normal_30_ccw.jpg
Binary files differ
diff --git a/apps/CameraITS/pymodules/its/test_images/rotated_chessboards/normal_45_ccw.jpg b/apps/CameraITS/pymodules/its/test_images/rotated_chessboards/normal_45_ccw.jpg
new file mode 100644
index 0000000..59dc939
--- /dev/null
+++ b/apps/CameraITS/pymodules/its/test_images/rotated_chessboards/normal_45_ccw.jpg
Binary files differ
diff --git a/apps/CameraITS/pymodules/its/test_images/rotated_chessboards/normal_60_ccw.jpg b/apps/CameraITS/pymodules/its/test_images/rotated_chessboards/normal_60_ccw.jpg
new file mode 100644
index 0000000..7d11c40
--- /dev/null
+++ b/apps/CameraITS/pymodules/its/test_images/rotated_chessboards/normal_60_ccw.jpg
Binary files differ
diff --git a/apps/CameraITS/pymodules/its/test_images/rotated_chessboards/normal_75_ccw.jpg b/apps/CameraITS/pymodules/its/test_images/rotated_chessboards/normal_75_ccw.jpg
new file mode 100644
index 0000000..1193bb1
--- /dev/null
+++ b/apps/CameraITS/pymodules/its/test_images/rotated_chessboards/normal_75_ccw.jpg
Binary files differ
diff --git a/apps/CameraITS/pymodules/its/test_images/rotated_chessboards/normal_90_ccw.jpg b/apps/CameraITS/pymodules/its/test_images/rotated_chessboards/normal_90_ccw.jpg
new file mode 100644
index 0000000..ea233ae
--- /dev/null
+++ b/apps/CameraITS/pymodules/its/test_images/rotated_chessboards/normal_90_ccw.jpg
Binary files differ
diff --git a/apps/CameraITS/pymodules/its/test_images/rotated_chessboards/wide.jpg b/apps/CameraITS/pymodules/its/test_images/rotated_chessboards/wide.jpg
new file mode 100644
index 0000000..a790506
--- /dev/null
+++ b/apps/CameraITS/pymodules/its/test_images/rotated_chessboards/wide.jpg
Binary files differ
diff --git a/apps/CameraITS/pymodules/its/test_images/rotated_chessboards/wide_15_ccw.jpg b/apps/CameraITS/pymodules/its/test_images/rotated_chessboards/wide_15_ccw.jpg
new file mode 100644
index 0000000..1871bab
--- /dev/null
+++ b/apps/CameraITS/pymodules/its/test_images/rotated_chessboards/wide_15_ccw.jpg
Binary files differ
diff --git a/apps/CameraITS/pymodules/its/test_images/rotated_chessboards/wide_30_ccw.jpg b/apps/CameraITS/pymodules/its/test_images/rotated_chessboards/wide_30_ccw.jpg
new file mode 100644
index 0000000..d3bff2a
--- /dev/null
+++ b/apps/CameraITS/pymodules/its/test_images/rotated_chessboards/wide_30_ccw.jpg
Binary files differ
diff --git a/apps/CameraITS/pymodules/its/test_images/rotated_chessboards/wide_45_ccw.jpg b/apps/CameraITS/pymodules/its/test_images/rotated_chessboards/wide_45_ccw.jpg
new file mode 100644
index 0000000..1298752
--- /dev/null
+++ b/apps/CameraITS/pymodules/its/test_images/rotated_chessboards/wide_45_ccw.jpg
Binary files differ
diff --git a/apps/CameraITS/pymodules/its/test_images/rotated_chessboards/wide_60_ccw.jpg b/apps/CameraITS/pymodules/its/test_images/rotated_chessboards/wide_60_ccw.jpg
new file mode 100644
index 0000000..642aeea
--- /dev/null
+++ b/apps/CameraITS/pymodules/its/test_images/rotated_chessboards/wide_60_ccw.jpg
Binary files differ
diff --git a/apps/CameraITS/pymodules/its/test_images/rotated_chessboards/wide_75_ccw.jpg b/apps/CameraITS/pymodules/its/test_images/rotated_chessboards/wide_75_ccw.jpg
new file mode 100644
index 0000000..b224ae4
--- /dev/null
+++ b/apps/CameraITS/pymodules/its/test_images/rotated_chessboards/wide_75_ccw.jpg
Binary files differ
diff --git a/apps/CameraITS/pymodules/its/test_images/rotated_chessboards/wide_90_ccw.jpg b/apps/CameraITS/pymodules/its/test_images/rotated_chessboards/wide_90_ccw.jpg
new file mode 100644
index 0000000..c2ad401
--- /dev/null
+++ b/apps/CameraITS/pymodules/its/test_images/rotated_chessboards/wide_90_ccw.jpg
Binary files differ
diff --git a/apps/CameraITS/tests/inprog/test_3a_remote.py b/apps/CameraITS/tests/inprog/test_3a_remote.py
index c76ff6d..1efc1aa 100644
--- a/apps/CameraITS/tests/inprog/test_3a_remote.py
+++ b/apps/CameraITS/tests/inprog/test_3a_remote.py
@@ -29,8 +29,6 @@
 
     with its.device.ItsSession() as cam:
         props = cam.get_camera_properties()
-        w_map = props["android.lens.info.shadingMapSize"]["width"]
-        h_map = props["android.lens.info.shadingMapSize"]["height"]
 
         # TODO: Test for 3A convergence, and exit this test once converged.
 
@@ -50,7 +48,10 @@
             gains = cap["metadata"]["android.colorCorrection.gains"]
             transform = cap["metadata"]["android.colorCorrection.transform"]
             exp_time = cap["metadata"]['android.sensor.exposureTime']
-            lsc_map = cap["metadata"]["android.statistics.lensShadingMap"]
+            lsc_obj = cap_res["android.statistics.lensShadingCorrectionMap"]
+            lsc_map = lsc_obj["map"]
+            w_map = lsc_obj["width"]
+            h_map = lsc_obj["height"]
             foc_dist = cap["metadata"]['android.lens.focusDistance']
             foc_range = cap["metadata"]['android.lens.focusRange']
 
diff --git a/apps/CameraITS/tests/inprog/test_blc_lsc.py b/apps/CameraITS/tests/inprog/test_blc_lsc.py
index 32c0c49..1e417c1 100644
--- a/apps/CameraITS/tests/inprog/test_blc_lsc.py
+++ b/apps/CameraITS/tests/inprog/test_blc_lsc.py
@@ -63,9 +63,8 @@
         for e in exposures:
             req = its.objects.manual_capture_request(ae_sen,e)
             req["android.tonemap.mode"] = 0
-            req["android.tonemap.curveRed"] = tmap
-            req["android.tonemap.curveGreen"] = tmap
-            req["android.tonemap.curveBlue"] = tmap
+            req["android.tonemap.curve"] = {
+                "red": tmap, "green": tmap, "blue": tmap}
             req["android.colorCorrection.transform"] = awb_transform_rat
             req["android.colorCorrection.gains"] = awb_gains
             reqs.append(req)
diff --git a/apps/CameraITS/tests/scene1/test_auto_vs_manual.py b/apps/CameraITS/tests/scene1/test_auto_vs_manual.py
index 4393fe6..9c49575 100644
--- a/apps/CameraITS/tests/scene1/test_auto_vs_manual.py
+++ b/apps/CameraITS/tests/scene1/test_auto_vs_manual.py
@@ -80,9 +80,8 @@
         # Manual capture 2: WB + tonemap
         gamma = sum([[i/63.0,math.pow(i/63.0,1/2.2)] for i in xrange(64)],[])
         req["android.tonemap.mode"] = 0
-        req["android.tonemap.curveRed"] = gamma
-        req["android.tonemap.curveGreen"] = gamma
-        req["android.tonemap.curveBlue"] = gamma
+        req["android.tonemap.curve"] = {
+            "red": gamma, "green": gamma, "blue": gamma}
         cap_man2 = cam.do_capture(req, fmt)
         img_man2 = its.image.convert_capture_to_rgb_image(cap_man2)
         its.image.write_image(img_man2, "%s_manual_wb_tm.jpg" % (NAME))
diff --git a/apps/CameraITS/tests/scene1/test_capture_result.py b/apps/CameraITS/tests/scene1/test_capture_result.py
index 31490d6..a3b81fa 100644
--- a/apps/CameraITS/tests/scene1/test_capture_result.py
+++ b/apps/CameraITS/tests/scene1/test_capture_result.py
@@ -63,24 +63,21 @@
             "android.colorCorrection.transform": manual_transform,
             "android.colorCorrection.gains": manual_gains,
             "android.tonemap.mode": 0,
-            "android.tonemap.curveRed": manual_tonemap,
-            "android.tonemap.curveGreen": manual_tonemap,
-            "android.tonemap.curveBlue": manual_tonemap,
+            "android.tonemap.curve": {"red": manual_tonemap,
+                                      "green": manual_tonemap,
+                                      "blue": manual_tonemap},
             "android.control.aeRegions": manual_region,
             "android.control.afRegions": manual_region,
             "android.control.awbRegions": manual_region,
             "android.statistics.lensShadingMapMode":1
             }
 
-        w_map = props["android.lens.info.shadingMapSize"]["width"]
-        h_map = props["android.lens.info.shadingMapSize"]["height"]
-
         print "Testing auto capture results"
-        lsc_map_auto = test_auto(cam, w_map, h_map, props)
+        lsc_map_auto = test_auto(cam, props)
         print "Testing manual capture results"
-        test_manual(cam, w_map, h_map, lsc_map_auto, props)
+        test_manual(cam, lsc_map_auto, props)
         print "Testing auto capture results again"
-        test_auto(cam, w_map, h_map, props)
+        test_auto(cam, props)
 
 # A very loose definition for two floats being close to each other;
 # there may be different interpolation and rounding used to get the
@@ -104,7 +101,7 @@
         ax.plot_wireframe(xs, ys, zs)
         matplotlib.pyplot.savefig("%s_plot_lsc_%s_ch%d.png"%(NAME,name,ch))
 
-def test_auto(cam, w_map, h_map, props):
+def test_auto(cam, props):
     # Get 3A lock first, so the auto values in the capture result are
     # populated properly.
     rect = [[0,0,1,1,1]]
@@ -117,7 +114,10 @@
     gains = cap_res["android.colorCorrection.gains"]
     transform = cap_res["android.colorCorrection.transform"]
     exp_time = cap_res['android.sensor.exposureTime']
-    lsc_map = cap_res["android.statistics.lensShadingMap"]
+    lsc_obj = cap_res["android.statistics.lensShadingCorrectionMap"]
+    lsc_map = lsc_obj["map"]
+    w_map = lsc_obj["width"]
+    h_map = lsc_obj["height"]
     ctrl_mode = cap_res["android.control.mode"]
 
     print "Control mode:", ctrl_mode
@@ -157,17 +157,20 @@
 
     return lsc_map
 
-def test_manual(cam, w_map, h_map, lsc_map_auto, props):
+def test_manual(cam, lsc_map_auto, props):
     cap = cam.do_capture(manual_req)
     cap_res = cap["metadata"]
 
     gains = cap_res["android.colorCorrection.gains"]
     transform = cap_res["android.colorCorrection.transform"]
-    curves = [cap_res["android.tonemap.curveRed"],
-              cap_res["android.tonemap.curveGreen"],
-              cap_res["android.tonemap.curveBlue"]]
+    curves = [cap_res["android.tonemap.curve"]["red"],
+              cap_res["android.tonemap.curve"]["green"],
+              cap_res["android.tonemap.curve"]["blue"]]
     exp_time = cap_res['android.sensor.exposureTime']
-    lsc_map = cap_res["android.statistics.lensShadingMap"]
+    lsc_obj = cap_res["android.statistics.lensShadingCorrectionMap"]
+    lsc_map = lsc_obj["map"]
+    w_map = lsc_obj["width"]
+    h_map = lsc_obj["height"]
     ctrl_mode = cap_res["android.control.mode"]
 
     print "Control mode:", ctrl_mode
diff --git a/apps/CameraITS/tests/scene1/test_ev_compensation_advanced.py b/apps/CameraITS/tests/scene1/test_ev_compensation_advanced.py
index c1588fd..d087ab1 100644
--- a/apps/CameraITS/tests/scene1/test_ev_compensation_advanced.py
+++ b/apps/CameraITS/tests/scene1/test_ev_compensation_advanced.py
@@ -71,13 +71,14 @@
             # Capture a single shot with the same EV comp and locked AE.
             req = its.objects.auto_capture_request()
             req['android.control.aeExposureCompensation'] = ev
-            req["android.control.aeLock"] = True
+            req['android.control.aeLock'] = True
             # Use linear tone curve to avoid brightness being impacted
             # by tone curves.
-            req["android.tonemap.mode"] = 0
-            req["android.tonemap.curveRed"] = [0.0,0.0, 1.0,1.0]
-            req["android.tonemap.curveGreen"] = [0.0,0.0, 1.0,1.0]
-            req["android.tonemap.curveBlue"] = [0.0,0.0, 1.0,1.0]
+            req['android.tonemap.mode'] = 0
+            req['android.tonemap.curve'] = {
+                'red': [0.0,0.0, 1.0,1.0],
+                'green': [0.0,0.0, 1.0,1.0],
+                'blue': [0.0,0.0, 1.0,1.0]}
             caps = cam.do_capture([req]*THREASH_CONVERGE_FOR_EV, fmt)
 
             for cap in caps:
diff --git a/apps/CameraITS/tests/scene1/test_linearity.py b/apps/CameraITS/tests/scene1/test_linearity.py
index 35068a8..1f4aa14 100644
--- a/apps/CameraITS/tests/scene1/test_linearity.py
+++ b/apps/CameraITS/tests/scene1/test_linearity.py
@@ -67,9 +67,10 @@
         req = its.objects.manual_capture_request(0, e)
         req['android.blackLevel.lock'] = True
         req['android.tonemap.mode'] = 0
-        req['android.tonemap.curveRed'] = gamma_lut.tolist()
-        req['android.tonemap.curveGreen'] = gamma_lut.tolist()
-        req['android.tonemap.curveBlue'] = gamma_lut.tolist()
+        req['android.tonemap.curve'] = {
+            'red': gamma_lut.tolist(),
+            'green': gamma_lut.tolist(),
+            'blue': gamma_lut.tolist()}
 
         r_means = []
         g_means = []
diff --git a/apps/CameraITS/tests/scene1/test_param_shading_mode.py b/apps/CameraITS/tests/scene1/test_param_shading_mode.py
index 33ed2f6..45c9a12 100644
--- a/apps/CameraITS/tests/scene1/test_param_shading_mode.py
+++ b/apps/CameraITS/tests/scene1/test_param_shading_mode.py
@@ -42,16 +42,10 @@
 
         mono_camera = its.caps.mono_camera(props)
 
-        assert(props.has_key("android.lens.info.shadingMapSize") and
-               props["android.lens.info.shadingMapSize"] != None)
-
         # lsc_off devices should always support OFF(0), FAST(1), and HQ(2)
         assert(props.has_key("android.shading.availableModes") and
                set(props["android.shading.availableModes"]) == set([0, 1, 2]))
 
-        num_map_gains = props["android.lens.info.shadingMapSize"]["width"] * \
-                        props["android.lens.info.shadingMapSize"]["height"] * 4
-
         # Test 1: Switching shading modes several times and verify:
         #   1. Lens shading maps with mode OFF are all 1.0
         #   2. Lens shading maps with mode FAST are similar after switching
@@ -64,13 +58,20 @@
         # in different sessions.
         # reference_maps[mode]
         reference_maps = [[] for mode in range(3)]
-        reference_maps[0] = [1.0] * num_map_gains
+        num_map_gains = 0
         for mode in range(1, 3):
             req = its.objects.auto_capture_request();
             req["android.statistics.lensShadingMapMode"] = 1
             req["android.shading.mode"] = mode
-            reference_maps[mode] = cam.do_capture(req)["metadata"] \
-                    ["android.statistics.lensShadingMap"]
+            cap_res = cam.do_capture(req)["metadata"]
+            lsc_map = cap_res["android.statistics.lensShadingCorrectionMap"]
+            assert(lsc_map.has_key("width") and
+                   lsc_map.has_key("height") and
+                   lsc_map["width"] != None and lsc_map["height"] != None)
+            if mode == 1:
+                num_map_gains = lsc_map["width"] * lsc_map["height"] * 4
+                reference_maps[0] = [1.0] * num_map_gains
+            reference_maps[mode] = lsc_map["map"]
 
         # Get the lens shading maps while switching modes in one session.
         reqs = []
@@ -90,7 +91,8 @@
         # Get the shading maps out of capture results
         for i in range(len(caps)):
             shading_maps[i % 3][i / 3] = \
-                    caps[i]["metadata"]["android.statistics.lensShadingMap"]
+                    caps[i]["metadata"] \
+                    ["android.statistics.lensShadingCorrectionMap"]["map"]
 
         # Draw the maps
         for mode in range(3):
diff --git a/apps/CameraITS/tests/scene1/test_param_tonemap_mode.py b/apps/CameraITS/tests/scene1/test_param_tonemap_mode.py
index 1229f90..45a5b13 100644
--- a/apps/CameraITS/tests/scene1/test_param_tonemap_mode.py
+++ b/apps/CameraITS/tests/scene1/test_param_tonemap_mode.py
@@ -62,12 +62,13 @@
         for n in [0,1]:
             req = its.objects.manual_capture_request(s,e)
             req["android.tonemap.mode"] = 0
-            req["android.tonemap.curveRed"] = (
-                    sum([[i/LM1, min(1.0,(1+0.5*n)*i/LM1)] for i in range(L)], []))
-            req["android.tonemap.curveGreen"] = (
-                    sum([[i/LM1, min(1.0,(1+1.0*n)*i/LM1)] for i in range(L)], []))
-            req["android.tonemap.curveBlue"] = (
-                    sum([[i/LM1, min(1.0,(1+1.5*n)*i/LM1)] for i in range(L)], []))
+            req["android.tonemap.curve"] = {
+                "red": (sum([[i/LM1, min(1.0,(1+0.5*n)*i/LM1)]
+                    for i in range(L)], [])),
+                "green": (sum([[i/LM1, min(1.0,(1+1.0*n)*i/LM1)]
+                    for i in range(L)], [])),
+                "blue": (sum([[i/LM1, min(1.0,(1+1.5*n)*i/LM1)]
+                    for i in range(L)], []))}
             cap = cam.do_capture(req, fmt)
             img = its.image.convert_capture_to_rgb_image(cap)
             its.image.write_image(
@@ -90,9 +91,8 @@
             curve = sum([[i/m, i/m] for i in range(size)], [])
             req = its.objects.manual_capture_request(s,e)
             req["android.tonemap.mode"] = 0
-            req["android.tonemap.curveRed"] = curve
-            req["android.tonemap.curveGreen"] = curve
-            req["android.tonemap.curveBlue"] = curve
+            req["android.tonemap.curve"] = {
+                "red": curve, "green": curve, "blue": curve}
             cap = cam.do_capture(req)
             img = its.image.convert_capture_to_rgb_image(cap)
             its.image.write_image(
diff --git a/apps/CameraITS/tests/sensor_fusion/test_multi_camera_frame_sync.py b/apps/CameraITS/tests/sensor_fusion/test_multi_camera_frame_sync.py
new file mode 100644
index 0000000..2998c88
--- /dev/null
+++ b/apps/CameraITS/tests/sensor_fusion/test_multi_camera_frame_sync.py
@@ -0,0 +1,182 @@
+# Copyright 2018 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+import its.caps
+from its.cv2image import get_angle
+import its.device
+import its.image
+import its.objects
+import its.target
+
+import cv2
+import matplotlib
+from matplotlib import pylab
+import numpy
+import os
+
+ANGLE_MASK = 10  # degrees
+ANGULAR_DIFF_THRESHOLD = 5  # degrees
+ANGULAR_MOVEMENT_THRESHOLD = 45  # degrees
+NAME = os.path.basename(__file__).split(".")[0]
+NUM_CAPTURES = 100
+W = 640
+H = 480
+
+
+def _check_available_capabilities(props):
+    """Returns True if all required test capabilities are present."""
+    return all([
+            its.caps.compute_target_exposure(props),
+            its.caps.per_frame_control(props),
+            its.caps.logical_multi_camera(props),
+            its.caps.raw16(props),
+            its.caps.manual_sensor(props),
+            its.caps.sensor_fusion(props)])
+
+
+def _assert_camera_movement(frame_pairs_angles):
+    """Assert the angles between each frame pair are sufficiently different.
+
+    Different angles is an indication of camera movement.
+    """
+    angles = [i for i, j in frame_pairs_angles]
+    max_angle = numpy.amax(angles)
+    min_angle = numpy.amin(angles)
+    emsg = "Not enough phone movement!\n"
+    emsg += "min angle: %.2f, max angle: %.2f deg, THRESH: %d deg" % (
+            min_angle, max_angle, ANGULAR_MOVEMENT_THRESHOLD)
+    assert max_angle - min_angle > ANGULAR_MOVEMENT_THRESHOLD, emsg
+
+
+def _assert_angular_difference(angle_1, angle_2):
+    """Assert angular difference is within threshold."""
+    diff = abs(angle_2 - angle_1)
+
+    # Assert difference is less than threshold
+    emsg = "Diff between frame pair: %.1f. Threshold: %d deg." % (
+            diff, ANGULAR_DIFF_THRESHOLD)
+    assert diff < ANGULAR_DIFF_THRESHOLD, emsg
+
+
+def _mask_angles_near_extremes(frame_pairs_angles):
+    """Mask out the data near the top and bottom of angle range."""
+    masked_pairs_angles = [[i, j] for i, j in frame_pairs_angles
+                           if ANGLE_MASK <= abs(i) <= 90-ANGLE_MASK]
+    return masked_pairs_angles
+
+
+def _plot_frame_pairs_angles(frame_pairs_angles, ids):
+    """Plot the extracted angles."""
+    matplotlib.pyplot.figure("Camera Rotation Angle")
+    cam0_angles = [i for i, j in frame_pairs_angles]
+    cam1_angles = [j for i, j in frame_pairs_angles]
+    pylab.plot(range(len(cam0_angles)), cam0_angles, "r", label="%s" % ids[0])
+    pylab.plot(range(len(cam1_angles)), cam1_angles, "g", label="%s" % ids[1])
+    pylab.legend()
+    pylab.xlabel("Camera frame number")
+    pylab.ylabel("Rotation angle (degrees)")
+    matplotlib.pyplot.savefig("%s_angles_plot.png" % (NAME))
+
+    matplotlib.pyplot.figure("Angle Diffs")
+    angle_diffs = [j-i for i, j in frame_pairs_angles]
+    pylab.plot(range(len(angle_diffs)), angle_diffs, "b",
+               label="cam%s-%s" % (ids[1], ids[0]))
+    pylab.legend()
+    pylab.xlabel("Camera frame number")
+    pylab.ylabel("Rotation angle difference (degrees)")
+    matplotlib.pyplot.savefig("%s_angle_diffs_plot.png" % (NAME))
+
+def _collect_data():
+    """Returns list of pair of gray frames and camera ids used for captures."""
+    yuv_sizes = {}
+    with its.device.ItsSession() as cam:
+        props = cam.get_camera_properties()
+
+        # If capabilities not present, skip.
+        its.caps.skip_unless(_check_available_capabilities(props))
+
+        # Determine return parameters
+        debug = its.caps.debug_mode()
+        ids = its.caps.logical_multi_camera_physical_ids(props)
+
+        # Define capture request
+        s, e, _, _, f = cam.do_3a(get_results=True)
+        req = its.objects.manual_capture_request(s, e, f)
+
+        # capture YUVs
+        out_surfaces = [{"format": "yuv", "width": W, "height": H,
+                         "physicalCamera": ids[0]},
+                        {"format": "yuv", "width": W, "height": H,
+                         "physicalCamera": ids[1]}]
+
+        capture_1_list, capture_2_list = cam.do_capture(
+            [req]*NUM_CAPTURES, out_surfaces)
+
+        # Create list of capture pairs. [[cap1A, cap1B], [cap2A, cap2B], ...]
+        frame_pairs = zip(capture_1_list, capture_2_list)
+
+        # Convert captures to grayscale
+        frame_pairs_gray = [
+            [
+                cv2.cvtColor(its.image.convert_capture_to_rgb_image(f, props=props), cv2.COLOR_RGB2GRAY) for f in pair
+            ] for pair in frame_pairs]
+
+        # Save images for debugging
+        if debug:
+            for i, imgs in enumerate(frame_pairs_gray):
+                for j in [0, 1]:
+                    file_name = "%s_%s_%03d.png" % (NAME, ids[j], i)
+                    cv2.imwrite(file_name, imgs[j]*255)
+
+        return frame_pairs_gray, ids
+
+def main():
+    """Test frame timestamps captured by logical camera are within 10ms."""
+    frame_pairs_gray, ids = _collect_data()
+
+    # Compute angles in frame pairs
+    frame_pairs_angles = [
+            [get_angle(p[0]), get_angle(p[1])] for p in frame_pairs_gray]
+
+    # Remove frames where not enough squares were detected.
+    filtered_pairs_angles = []
+    for angle_1, angle_2 in frame_pairs_angles:
+        if angle_1 == None or angle_2 == None:
+            continue
+        filtered_pairs_angles.append([angle_1, angle_2])
+
+    print 'Using {} image pairs to compute angular difference.'.format(
+        len(filtered_pairs_angles))
+
+    assert len(filtered_pairs_angles) > 20, (
+        "Unable to identify enough frames with detected squares.")
+
+    # Mask out data near 90 degrees.
+    # The chessboard angles we compute go from 0 to 89. Meaning,
+    # 90 degrees equals to 0 degrees.
+    # In order to avoid this jump, we ignore any frames at these extremeties.
+    masked_pairs_angles = _mask_angles_near_extremes(filtered_pairs_angles)
+
+    # Plot angles and differences
+    _plot_frame_pairs_angles(filtered_pairs_angles, ids)
+
+    # Ensure camera moved
+    _assert_camera_movement(filtered_pairs_angles)
+
+    # Ensure angle between images from each camera does not change appreciably
+    for cam_1_angle, cam_2_angle in masked_pairs_angles:
+        _assert_angular_difference(cam_1_angle, cam_2_angle)
+
+if __name__ == "__main__":
+    main()
diff --git a/apps/CameraITS/tools/run_all_tests.py b/apps/CameraITS/tools/run_all_tests.py
index 61c4917..c9acc20 100644
--- a/apps/CameraITS/tools/run_all_tests.py
+++ b/apps/CameraITS/tools/run_all_tests.py
@@ -63,7 +63,6 @@
                 "test_num_faces",
         ],
         "scene3": [
-                "test_3a_consistency",
                 "test_flip_mirror",
                 "test_lens_movement_reporting",
                 "test_lens_position"
diff --git a/apps/CtsVerifier/AndroidManifest.xml b/apps/CtsVerifier/AndroidManifest.xml
index 5642bbf..597dece 100644
--- a/apps/CtsVerifier/AndroidManifest.xml
+++ b/apps/CtsVerifier/AndroidManifest.xml
@@ -18,9 +18,9 @@
 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
       package="com.android.cts.verifier"
       android:versionCode="5"
-      android:versionName="8.1_r1">
+      android:versionName="9.0_r1">
 
-    <uses-sdk android:minSdkVersion="19" android:targetSdkVersion="27"/>
+    <uses-sdk android:minSdkVersion="19" android:targetSdkVersion="28"/>
 
     <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
     <uses-permission android:name="android.permission.ACCESS_LOCATION_EXTRA_COMMANDS"/>
@@ -125,6 +125,8 @@
                 <category android:name="android.cts.intent.category.MANUAL_TEST" />
             </intent-filter>
             <meta-data android:name="test_category" android:value="@string/test_category_device_admin" />
+            <meta-data android:name="test_excluded_features"
+                       android:value="android.software.lockscreen_disabled" />
             <meta-data android:name="test_required_features"
                     android:value="android.software.device_admin" />
         </activity>
@@ -195,6 +197,8 @@
                 <category android:name="android.cts.intent.category.MANUAL_TEST" />
             </intent-filter>
             <meta-data android:name="test_category" android:value="@string/test_category_device_admin" />
+            <meta-data android:name="test_excluded_features"
+                       android:value="android.software.lockscreen_disabled" />
             <meta-data android:name="test_required_features"
                     android:value="android.software.device_admin" />
         </activity>
@@ -221,7 +225,7 @@
                 <category android:name="android.cts.intent.category.MANUAL_TEST" />
             </intent-filter>
             <meta-data android:name="test_category" android:value="@string/test_category_device_admin" />
-            <meta-data android:name="test_excluded_features" android:value="android.hardware.type.automotive" />
+            <meta-data android:name="test_excluded_features" android:value="android.hardware.type.automotive:android.software.lockscreen_disabled" />
             <meta-data android:name="test_required_features"
                     android:value="android.software.device_admin" />
         </activity>
@@ -1069,6 +1073,8 @@
                 <category android:name="android.cts.intent.category.MANUAL_TEST" />
             </intent-filter>
             <meta-data android:name="test_category" android:value="@string/test_category_security" />
+            <meta-data android:name="test_excluded_features"
+                       android:value="android.software.lockscreen_disabled" />
             <meta-data android:name="test_required_features"
                     android:value="android.software.device_admin" />
         </activity>
@@ -1081,6 +1087,8 @@
                 <category android:name="android.cts.intent.category.MANUAL_TEST" />
             </intent-filter>
             <meta-data android:name="test_category" android:value="@string/test_category_security" />
+            <meta-data android:name="test_excluded_features"
+                       android:value="android.software.lockscreen_disabled" />
             <meta-data android:name="test_required_features"
                     android:value="android.software.device_admin" />
         </activity>
@@ -2350,6 +2358,8 @@
                 <category android:name="android.cts.intent.category.MANUAL_TEST" />
             </intent-filter>
             <meta-data android:name="test_category" android:value="@string/test_category_managed_provisioning" />
+            <meta-data android:name="test_excluded_features"
+                       android:value="android.software.lockscreen_disabled" />
             <meta-data android:name="test_required_features" android:value="android.software.device_admin" />
         </activity>
 
@@ -2372,6 +2382,8 @@
                 <category android:name="android.cts.intent.category.MANUAL_TEST" />
             </intent-filter>
             <meta-data android:name="test_category" android:value="@string/test_category_managed_provisioning" />
+            <meta-data android:name="test_excluded_features"
+                       android:value="android.software.lockscreen_disabled" />
             <meta-data android:name="test_required_features" android:value="android.software.device_admin" />
         </activity>
 
diff --git a/apps/CtsVerifier/create_test_certs.sh b/apps/CtsVerifier/create_test_certs.sh
index b59974a..93fa377 100755
--- a/apps/CtsVerifier/create_test_certs.sh
+++ b/apps/CtsVerifier/create_test_certs.sh
@@ -20,11 +20,15 @@
 '/O=Android'\
 '/CN=localhost'
 PASSWORD='androidtest'
+SAN=\
+'DNS:localhost'
 
 echo "Creating directory '$CA_DIR'..."
 mkdir -p "$tmpdir"/"$CA_DIR"/newcerts \
     && echo '01' > "$tmpdir"/"$CA_DIR"/serial \
     && touch "$tmpdir"/"$CA_DIR"/index.txt
+cat /etc/ssl/openssl.cnf <(printf "\n[SAN]\nsubjectAltName=$SAN") \
+    > "$tmpdir"/openssl.conf
 
 echo "Generating CA certificate..."
 (cd "$tmpdir" \
@@ -52,6 +56,8 @@
         -days 3650 \
         -out 'userkey.req' \
         -subj "$SUBJECT" \
+        -extensions SAN \
+        -config openssl.conf \
     && openssl pkcs8 \
         -topk8 \
         -outform DER \
@@ -68,6 +74,8 @@
         -keyfile 'cakey.pem' \
         -days 3650 \
         -passin 'pass:'"$PASSWORD" \
+        -extensions SAN \
+        -config openssl.conf \
         -batch \
     && openssl x509 \
         -outform DER \
diff --git a/apps/CtsVerifier/res/raw/cacert.der b/apps/CtsVerifier/res/raw/cacert.der
index 3934e1b..9acf82a 100644
--- a/apps/CtsVerifier/res/raw/cacert.der
+++ b/apps/CtsVerifier/res/raw/cacert.der
Binary files differ
diff --git a/apps/CtsVerifier/res/raw/usercert.der b/apps/CtsVerifier/res/raw/usercert.der
index cdfb8f7..cb48852 100644
--- a/apps/CtsVerifier/res/raw/usercert.der
+++ b/apps/CtsVerifier/res/raw/usercert.der
Binary files differ
diff --git a/apps/CtsVerifier/res/raw/userkey.der b/apps/CtsVerifier/res/raw/userkey.der
index 31f1f8c..9216bb8 100644
--- a/apps/CtsVerifier/res/raw/userkey.der
+++ b/apps/CtsVerifier/res/raw/userkey.der
Binary files differ
diff --git a/apps/CtsVerifier/res/values/strings.xml b/apps/CtsVerifier/res/values/strings.xml
index 8a5b66f..751766c 100755
--- a/apps/CtsVerifier/res/values/strings.xml
+++ b/apps/CtsVerifier/res/values/strings.xml
@@ -1482,6 +1482,7 @@
     <string name="aware_status_publish_timeout">Publish failure - timed out!</string>
     <string name="aware_status_publish_null_session">Publish failure - null session!</string>
     <string name="aware_status_discovery">Service discovered ...</string>
+    <string name="aware_status_discovery_with_info">Service discovered ... peer MAC : %1$s</string>
     <string name="aware_status_discovery_timeout">Service discovery failure - timed out!</string>
     <string name="aware_status_discovery_fail">Service discovery failure - parameter mismatch!</string>
     <string name="aware_status_send_success">Sent message successfully ...</string>
@@ -1489,6 +1490,9 @@
     <string name="aware_status_send_timeout">Send message failure - timed out!</string>
     <string name="aware_status_send_fail_parameter">Send message failure - mismatched ids!</string>
     <string name="aware_status_received">Received message ...</string>
+    <string name="aware_status_starting_rtt">Starting RTT operations ...</string>
+    <string name="aware_status_waiting_for_peer_rtt">Pausing to let other device perform RTT ...</string>
+    <string name="aware_status_received_peer_rtt_done">Other device done with RTT ...</string>
     <string name="aware_status_received_mac">Received peer MAC address: %1$s ...</string>
     <string name="aware_status_receive_timeout">Receive message failure - timed out!</string>
     <string name="aware_status_receive_failure">Receive message failure - didn\'t receive expected message!</string>
@@ -1500,6 +1504,7 @@
     <string name="aware_status_ranging_mac_failure">Ranging to MAC address failure: %1$d failures of %2$d attempts!</string>
     <string name="aware_status_ranging_peer_success">Ranging to PeerHandle success: %1$d successes of %2$d attempts!</string>
     <string name="aware_status_ranging_mac_success">Ranging to MAC address success: %1$d successes of %2$d attempts!</string>
+    <string name="aware_status_lifecycle_failed">Discovery lifecycle FAILURE!</string>
     <string name="aware_status_lifecycle_ok">Discovery lifecycle validated!</string>
 
     <string name="aware_data_path_open_unsolicited_publish">Data Path: Open: Unsolicited Publish</string>
@@ -3179,7 +3184,7 @@
     <string name="disallow_config_date_time">Disallow config date and time settings</string>
     <string name="disallow_config_date_time_action">Configuring auto time, time, auto date or date</string>
     <string name="disallow_config_location">Disallow config location</string>
-    <string name="disallow_config_location_action">Enabling or disabling location in settings or quick settings, changing location accuracy</string>
+    <string name="disallow_config_location_action">Enabling or disabling location in settings or quick settings</string>
     <string name="disallow_airplane_mode">Disallow airplane mode</string>
     <string name="disallow_airplane_mode_action">Toggling airplane mode switch bar or changing airplane mode state in quick settings</string>
     <string name="disallow_config_screen_timeout">Disallow config sleep options settings</string>
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/camera/its/ItsSerializer.java b/apps/CtsVerifier/src/com/android/cts/verifier/camera/its/ItsSerializer.java
index 2a6c146..fbd7522 100644
--- a/apps/CtsVerifier/src/com/android/cts/verifier/camera/its/ItsSerializer.java
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/camera/its/ItsSerializer.java
@@ -52,6 +52,7 @@
 import java.util.Arrays;
 import java.util.LinkedList;
 import java.util.List;
+import java.util.Set;
 
 /**
  * Class to deal with serializing and deserializing between JSON and Camera2 objects.
@@ -262,14 +263,18 @@
     @SuppressWarnings("unchecked")
     private static Object serializeLensShadingMap(LensShadingMap map)
             throws org.json.JSONException {
-        JSONArray mapObj = new JSONArray();
+        JSONObject mapObj = new JSONObject();
+        JSONArray mapArr = new JSONArray();
         for (int row = 0; row < map.getRowCount(); row++) {
             for (int col = 0; col < map.getColumnCount(); col++) {
                 for (int ch = 0; ch < 4; ch++) {
-                    mapObj.put(map.getGainFactor(ch, col, row));
+                    mapArr.put(map.getGainFactor(ch, col, row));
                 }
             }
         }
+        mapObj.put("width", map.getColumnCount());
+        mapObj.put("height", map.getRowCount());
+        mapObj.put("map", mapArr);
         return mapObj;
     }
 
@@ -473,6 +478,37 @@
         if (md.getClass() == TotalCaptureResult.class) {
             allFields = CaptureResult.class.getDeclaredFields();
         }
+        if (md.getClass() == CameraCharacteristics.class) {
+            // Special handling for information not stored in metadata keys
+            CameraCharacteristics chars = (CameraCharacteristics) md;
+            List<CameraCharacteristics.Key<?>> charsKeys = chars.getKeys();
+            List<CaptureRequest.Key<?>> requestKeys = chars.getAvailableCaptureRequestKeys();
+            Set<String> physicalCamIds = chars.getPhysicalCameraIds();
+
+            try {
+                JSONArray charKeysArr = new JSONArray();
+                for (CameraCharacteristics.Key<?> k : charsKeys) {
+                    charKeysArr.put(k.getName());
+                }
+                JSONArray reqKeysArr = new JSONArray();
+                for (CaptureRequest.Key<?> k : requestKeys) {
+                    reqKeysArr.put(k.getName());
+                }
+                // Avoid using the hidden metadata key name here to prevent confliction
+                jsonObj.put("camera.characteristics.keys", charKeysArr);
+                jsonObj.put("camera.characteristics.requestKeys", reqKeysArr);
+
+                if (!physicalCamIds.isEmpty()) {
+                    JSONArray physCamIdsArr = new JSONArray();
+                    for (String id : physicalCamIds) {
+                        physCamIdsArr.put(id);
+                    }
+                    jsonObj.put("camera.characteristics.physicalCamIds", physCamIdsArr);
+                }
+            } catch (org.json.JSONException e) {
+                throw new ItsException("JSON error for CameraCharacteristics:", e);
+            }
+        }
         for (Field field : allFields) {
             if (Modifier.isPublic(field.getModifiers()) &&
                     Modifier.isStatic(field.getModifiers()) &&
@@ -673,6 +709,18 @@
                                                 arr.getJSONObject(i).getInt("denominator"));
                                     }
                                     val = new ColorSpaceTransform(a);
+                                } else if (keyType == TonemapCurve.class) {
+                                    JSONObject obj = jsonReq.optJSONObject(keyName);
+                                    String names[] = {"red", "green", "blue"};
+                                    float[][] curves = new float[3][];
+                                    for (int ch = 0; ch < 3; ch++) {
+                                        JSONArray ja = obj.getJSONArray(names[ch]);
+                                        curves[ch] = new float[ja.length()];
+                                        for (int i = 0; i < ja.length(); i++) {
+                                            Array.set(curves[ch], i, (float)ja.getDouble(i));
+                                        }
+                                    }
+                                    val = new TonemapCurve(curves[0], curves[1], curves[2]);
                                 } else if (keyType instanceof ParameterizedType &&
                                         ((ParameterizedType)keyType).getRawType() == Range.class &&
                                         ((ParameterizedType)keyType).getActualTypeArguments().length == 1 &&
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/managedprovisioning/CommandReceiverActivity.java b/apps/CtsVerifier/src/com/android/cts/verifier/managedprovisioning/CommandReceiverActivity.java
index d4d2d0e..e807d29 100644
--- a/apps/CtsVerifier/src/com/android/cts/verifier/managedprovisioning/CommandReceiverActivity.java
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/managedprovisioning/CommandReceiverActivity.java
@@ -16,6 +16,8 @@
 
 package com.android.cts.verifier.managedprovisioning;
 
+import static android.app.admin.DevicePolicyManager.LOCK_TASK_FEATURE_HOME;
+import static android.app.admin.DevicePolicyManager.LOCK_TASK_FEATURE_OVERVIEW;
 import static android.app.admin.DevicePolicyManager.MAKE_USER_EPHEMERAL;
 import static android.app.admin.DevicePolicyManager.SKIP_SETUP_WIZARD;
 
@@ -30,6 +32,7 @@
 import android.content.IntentFilter;
 import android.content.pm.PackageInstaller;
 import android.content.pm.PackageManager;
+import android.content.pm.ResolveInfo;
 import android.graphics.BitmapFactory;
 import android.net.ProxyInfo;
 import android.os.Bundle;
@@ -238,6 +241,13 @@
                     int flags = intent.getIntExtra(EXTRA_VALUE,
                             DevicePolicyManager.LOCK_TASK_FEATURE_NONE);
                     mDpm.setLockTaskFeatures(mAdmin, flags);
+                    // If feature HOME is used, we need to whitelist the current launcher
+                    if ((flags & LOCK_TASK_FEATURE_HOME) != 0) {
+                        mDpm.setLockTaskPackages(mAdmin,
+                                new String[] {getPackageName(), getCurrentLauncherPackage()});
+                    } else {
+                        mDpm.setLockTaskPackages(mAdmin, new String[] {getPackageName()});
+                    }
                 } break;
                 case COMMAND_ALLOW_ONLY_SYSTEM_INPUT_METHODS: {
                     boolean enforced = intent.getBooleanExtra(EXTRA_ENFORCED, false);
@@ -664,4 +674,15 @@
                 SKIP_SETUP_WIZARD | MAKE_USER_EPHEMERAL);
         mDpm.switchUser(mAdmin, userHandle);
     }
+
+    private String getCurrentLauncherPackage() {
+        ResolveInfo resolveInfo = getPackageManager()
+            .resolveActivity(new Intent(Intent.ACTION_MAIN)
+                .addCategory(Intent.CATEGORY_HOME), PackageManager.MATCH_DEFAULT_ONLY);
+        if (resolveInfo == null || resolveInfo.activityInfo == null) {
+            return null;
+        }
+
+        return resolveInfo.activityInfo.packageName;
+    }
 }
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/managedprovisioning/IntentFiltersTestHelper.java b/apps/CtsVerifier/src/com/android/cts/verifier/managedprovisioning/IntentFiltersTestHelper.java
index d8fa2eb..9a33320 100644
--- a/apps/CtsVerifier/src/com/android/cts/verifier/managedprovisioning/IntentFiltersTestHelper.java
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/managedprovisioning/IntentFiltersTestHelper.java
@@ -76,10 +76,8 @@
                 new Intent(Settings.ACTION_PRIVACY_SETTINGS),
                 new Intent(Settings.ACTION_SETTINGS),
                 new Intent(Settings.ACTION_WIRELESS_SETTINGS),
-                new Intent(DevicePolicyManager.ACTION_SET_NEW_PASSWORD),
                 new Intent("android.net.vpn.SETTINGS"),
                 new Intent(Settings.ACTION_VPN_SETTINGS),
-                new Intent("android.settings.ACCOUNT_SYNC_SETTINGS"),
                 new Intent(Settings.ACTION_BATTERY_SAVER_SETTINGS),
                 new Intent("android.settings.LICENSE"),
                 new Intent("android.settings.NOTIFICATION_SETTINGS"),
@@ -101,7 +99,9 @@
                 new Intent(Settings.ACTION_ADD_ACCOUNT),
                 new Intent(Settings.ACTION_MANAGE_APPLICATIONS_SETTINGS),
                 new Intent(Settings.ACTION_MANAGE_ALL_APPLICATIONS_SETTINGS),
-                new Intent(Settings.ACTION_APPLICATION_SETTINGS)
+                new Intent(Settings.ACTION_APPLICATION_SETTINGS),
+                new Intent(DevicePolicyManager.ACTION_SET_NEW_PASSWORD),
+                new Intent("android.settings.ACCOUNT_SYNC_SETTINGS")
             ));
 
     // These are the intents which cannot be forwarded to the primary profile.
@@ -246,7 +246,7 @@
         }
 
         if (pm.hasSystemFeature(PackageManager.FEATURE_HOME_SCREEN)) {
-            forwardedIntentsFromManaged.add(
+            forwardingOptionalIntentsFromManaged.add(
                     new Intent(Settings.ACTION_HOME_SETTINGS));
         }
 
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/wifiaware/TestListActivity.java b/apps/CtsVerifier/src/com/android/cts/verifier/wifiaware/TestListActivity.java
index 4e88565..35770f0 100644
--- a/apps/CtsVerifier/src/com/android/cts/verifier/wifiaware/TestListActivity.java
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/wifiaware/TestListActivity.java
@@ -55,6 +55,8 @@
 
         boolean isRttSupported = getPackageManager().hasSystemFeature(
                 PackageManager.FEATURE_WIFI_RTT);
+        // TODO: revert when b/78645795 fixed (underlying cause of b/78568180)
+        isRttSupported = false;
 
         setContentView(R.layout.pass_fail_list);
         setInfoResources(R.string.aware_test, R.string.aware_test_info, 0);
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/wifiaware/testcase/DiscoveryBaseTestCase.java b/apps/CtsVerifier/src/com/android/cts/verifier/wifiaware/testcase/DiscoveryBaseTestCase.java
index 88ab5d6..77785b5 100644
--- a/apps/CtsVerifier/src/com/android/cts/verifier/wifiaware/testcase/DiscoveryBaseTestCase.java
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/wifiaware/testcase/DiscoveryBaseTestCase.java
@@ -196,8 +196,15 @@
                 return false;
         }
         mPeerHandle = callbackData.peerHandle;
-        mListener.onTestMsgReceived(mContext.getString(R.string.aware_status_discovery));
-        if (DBG) Log.d(TAG, "executeTestSubscriber: discovery");
+        if (!mIsRangingRequired) {
+            mListener.onTestMsgReceived(mContext.getString(R.string.aware_status_discovery));
+            if (DBG) Log.d(TAG, "executeTestSubscriber: discovery");
+        } else {
+            if (DBG) {
+                Log.d(TAG, "executeTestSubscriber: discovery with range="
+                        + callbackData.distanceMm);
+            }
+        }
 
         //    validate discovery parameters match
         if (mIsRangingRequired) {
@@ -209,8 +216,9 @@
                         callbackData.serviceSpecificInfo) + "'");
                 return false;
             }
-            mListener.onTestMsgReceived(mResources.getString(R.string.aware_status_received_mac,
-                    mPeerMacAddress));
+            mListener.onTestMsgReceived(
+                    mResources.getString(R.string.aware_status_discovery_with_info,
+                            mPeerMacAddress));
         } else {
             if (!Arrays.equals(PUB_SSI, callbackData.serviceSpecificInfo)) {
                 setFailureReason(mContext.getString(R.string.aware_status_discovery_fail));
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/wifiaware/testcase/DiscoveryWithRangingTestCase.java b/apps/CtsVerifier/src/com/android/cts/verifier/wifiaware/testcase/DiscoveryWithRangingTestCase.java
index 566cc90..209bedc 100644
--- a/apps/CtsVerifier/src/com/android/cts/verifier/wifiaware/testcase/DiscoveryWithRangingTestCase.java
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/wifiaware/testcase/DiscoveryWithRangingTestCase.java
@@ -28,7 +28,6 @@
 
 import java.util.Arrays;
 import java.util.List;
-import java.util.concurrent.Executor;
 
 /**
  * Test case for Discovery + Ranging:
@@ -118,62 +117,73 @@
         }
 
         if (!mIsPublish) {
+            mListener.onTestMsgReceived(
+                    mContext.getString(R.string.aware_status_waiting_for_peer_rtt));
+
             // pausing to let Publisher perform its RTT operations (however long)
-            CallbackUtils.DiscoveryCb.CallbackData callbackData = mDiscoveryCb.waitForCallbacks(
-                    CallbackUtils.DiscoveryCb.ON_MESSAGE_RECEIVED);
+            CallbackUtils.DiscoveryCb.CallbackData callbackData =
+                    mDiscoveryCb.waitForCallbacksNoTimeout(
+                            CallbackUtils.DiscoveryCb.ON_MESSAGE_RECEIVED);
             if (!Arrays.equals(MSG_RTT, callbackData.serviceSpecificInfo)) {
                 setFailureReason(mContext.getString(R.string.aware_status_receive_failure));
-                Log.e(TAG, "executeTest: receive RTT message content mismatch: rx='"
-                        + new String(callbackData.serviceSpecificInfo) + "'");
+                Log.e(TAG, "executeTest: receive RTT message content mismatch: rx=" + (
+                    (callbackData.serviceSpecificInfo == null) ? "<null>"
+                        : ("'" + new String(callbackData.serviceSpecificInfo) + "'")));
                 return false;
             }
 
-            // wait a few seconds to allow the previous RTT session to teardown, arbitrary 3 seconds
-            Thread.sleep(3000);
+            mListener.onTestMsgReceived(
+                    mContext.getString(R.string.aware_status_received_peer_rtt_done));
 
-            mListener.onTestMsgReceived(mContext.getString(R.string.aware_status_received));
+            // wait a few seconds to allow the previous RTT session to teardown, semi-arbitrary
+            Thread.sleep(5000);
+
             if (DBG) Log.d(TAG, "executeTest: subscriber received message - can proceed with RTT");
         }
 
+        mListener.onTestMsgReceived(mContext.getString(R.string.aware_status_starting_rtt));
+
         // Directed range to peer with PeerHandler
-        int numFailures = 0;
+        int numFailuresToPeerHandle = 0;
         RangingRequest rangeToPeerHandle = new RangingRequest.Builder().addWifiAwarePeer(
                 mPeerHandle).build();
         for (int i = 0; i < NUM_RTT_ITERATIONS; ++i) {
             if (!executeRanging(rangeToPeerHandle)) {
-                numFailures++;
+                numFailuresToPeerHandle++;
             }
         }
-        Log.d(TAG, "executeTest: Direct RTT to PeerHandle " + numFailures + " of "
+        Log.d(TAG, "executeTest: Direct RTT to PeerHandle " + numFailuresToPeerHandle + " of "
                 + NUM_RTT_ITERATIONS + " FAIL");
-        if (numFailures > MAX_RTT_RANGING_SUCCESS) {
-            setFailureReason(
-                    mContext.getString(R.string.aware_status_ranging_peer_failure, numFailures,
-                            NUM_RTT_ITERATIONS));
-            return false;
+        if (numFailuresToPeerHandle > MAX_RTT_RANGING_SUCCESS) {
+            mListener.onTestMsgReceived(
+                    mContext.getString(R.string.aware_status_ranging_peer_failure,
+                            numFailuresToPeerHandle, NUM_RTT_ITERATIONS));
+        } else {
+            mListener.onTestMsgReceived(
+                    mContext.getString(R.string.aware_status_ranging_peer_success,
+                            NUM_RTT_ITERATIONS - numFailuresToPeerHandle, NUM_RTT_ITERATIONS));
         }
-        mListener.onTestMsgReceived(mContext.getString(R.string.aware_status_ranging_peer_success,
-                NUM_RTT_ITERATIONS - numFailures, NUM_RTT_ITERATIONS));
 
         // Directed range to peer with MAC address
-        numFailures = 0;
+        int numFailuresToPeerMac = 0;
         RangingRequest rangeToMAC = new RangingRequest.Builder().addWifiAwarePeer(
                 mPeerMacAddress).build();
         for (int i = 0; i < NUM_RTT_ITERATIONS; ++i) {
             if (!executeRanging(rangeToMAC)) {
-                numFailures++;
+                numFailuresToPeerMac++;
             }
         }
-        Log.d(TAG, "executeTest: Direct RTT to MAC " + numFailures + " of " + NUM_RTT_ITERATIONS
-                + " FAIL");
-        if (numFailures > MAX_RTT_RANGING_SUCCESS) {
-            setFailureReason(
-                    mContext.getString(R.string.aware_status_ranging_mac_failure, numFailures,
-                            NUM_RTT_ITERATIONS));
-            return false;
+        Log.e(TAG, "executeTest: Direct RTT to MAC " + numFailuresToPeerMac + " of "
+                + NUM_RTT_ITERATIONS + " FAIL");
+        if (numFailuresToPeerMac > MAX_RTT_RANGING_SUCCESS) {
+            mListener.onTestMsgReceived(
+                    mContext.getString(R.string.aware_status_ranging_mac_failure,
+                            numFailuresToPeerMac, NUM_RTT_ITERATIONS));
+        } else {
+            mListener.onTestMsgReceived(
+                    mContext.getString(R.string.aware_status_ranging_mac_success,
+                            NUM_RTT_ITERATIONS - numFailuresToPeerMac, NUM_RTT_ITERATIONS));
         }
-        mListener.onTestMsgReceived(mContext.getString(R.string.aware_status_ranging_mac_success,
-                NUM_RTT_ITERATIONS - numFailures, NUM_RTT_ITERATIONS));
 
         // let peer know we're done with our RTT
         mWifiAwareDiscoverySession.sendMessage(mPeerHandle, MESSAGE_ID + 2, MSG_RTT);
@@ -195,20 +205,32 @@
         }
 
         if (mIsPublish) {
+            mListener.onTestMsgReceived(
+                    mContext.getString(R.string.aware_status_waiting_for_peer_rtt));
+
             // then pausing to let Subscriber finish it's RTT (can't terminate our Aware session
             // while we want Aware operations to proceed!).
-            callbackData = mDiscoveryCb.waitForCallbacks(
+            callbackData = mDiscoveryCb.waitForCallbacksNoTimeout(
                     CallbackUtils.DiscoveryCb.ON_MESSAGE_RECEIVED);
             if (!Arrays.equals(MSG_RTT, callbackData.serviceSpecificInfo)) {
                 setFailureReason(mContext.getString(R.string.aware_status_receive_failure));
-                Log.e(TAG, "executeTest: receive RTT message content mismatch: rx='"
-                        + new String(callbackData.serviceSpecificInfo) + "'");
+                Log.e(TAG, "executeTest: receive RTT message content mismatch: rx=" + (
+                    (callbackData.serviceSpecificInfo == null) ? "<null>"
+                        : ("'" + new String(callbackData.serviceSpecificInfo) + "'")));
                 return false;
             }
-            mListener.onTestMsgReceived(mContext.getString(R.string.aware_status_received));
+            mListener.onTestMsgReceived(
+                    mContext.getString(R.string.aware_status_received_peer_rtt_done));
             if (DBG) Log.d(TAG, "executeTest: publisher received message - can proceed (finish)");
         }
 
+        if (numFailuresToPeerHandle > MAX_RTT_RANGING_SUCCESS
+                || numFailuresToPeerMac > MAX_RTT_RANGING_SUCCESS) {
+            setFailureReason(mContext.getString(R.string.aware_status_lifecycle_failed,
+                    numFailuresToPeerHandle, NUM_RTT_ITERATIONS));
+            return false;
+        }
+
         mListener.onTestMsgReceived(mContext.getString(R.string.aware_status_lifecycle_ok));
         return true;
     }
diff --git a/common/device-side/util/src/com/android/compatibility/common/util/DeviceReportLog.java b/common/device-side/util/src/com/android/compatibility/common/util/DeviceReportLog.java
index cd7518e..d170263 100644
--- a/common/device-side/util/src/com/android/compatibility/common/util/DeviceReportLog.java
+++ b/common/device-side/util/src/com/android/compatibility/common/util/DeviceReportLog.java
@@ -48,7 +48,7 @@
         super(reportLogName, streamName);
         try {
             // dir value must match the src-dir value configured in ReportLogCollector target
-            // preparer in cts/tools/cts-tradefed/res/config/cts-preconditions.xml
+            // preparer in cts/harness/tools/cts-tradefed/res/config/cts-preconditions.xml
             if (!Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) {
                 throw new IOException("External storage is not mounted");
             } else if ((!logDirectory.exists() && !logDirectory.mkdirs())
diff --git a/common/device-side/util/src/com/android/compatibility/common/util/MediaUtils.java b/common/device-side/util/src/com/android/compatibility/common/util/MediaUtils.java
index c7d2fa5..3ea6b63 100644
--- a/common/device-side/util/src/com/android/compatibility/common/util/MediaUtils.java
+++ b/common/device-side/util/src/com/android/compatibility/common/util/MediaUtils.java
@@ -195,6 +195,13 @@
      *  ------------------- HELPER METHODS FOR CHECKING CODEC SUPPORT -------------------
      */
 
+    public static boolean isGoogle(String codecName) {
+        codecName = codecName.toLowerCase();
+        return codecName.startsWith("omx.google.")
+                || codecName.startsWith("c2.android.")
+                || codecName.startsWith("c2.google.");
+    }
+
     // returns the list of codecs that support any one of the formats
     private static String[] getCodecNames(
             boolean isEncoder, Boolean isGoog, MediaFormat... formats) {
@@ -204,8 +211,7 @@
             if (info.isEncoder() != isEncoder) {
                 continue;
             }
-            if (isGoog != null
-                    && info.getName().toLowerCase().startsWith("omx.google.") != isGoog) {
+            if (isGoog != null && isGoogle(info.getName()) != isGoog) {
                 continue;
             }
 
diff --git a/common/host-side/util/src/com/android/compatibility/common/util/CpuFeatures.java b/common/host-side/util/src/com/android/compatibility/common/util/CpuFeatures.java
deleted file mode 100644
index 7940636..0000000
--- a/common/host-side/util/src/com/android/compatibility/common/util/CpuFeatures.java
+++ /dev/null
@@ -1,49 +0,0 @@
-/*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.android.compatibility.common.util;
-import com.android.tradefed.device.CollectingOutputReceiver;
-
-import com.android.tradefed.device.DeviceNotAvailableException;
-import com.android.tradefed.device.ITestDevice;
-
-/**
- * Host-side utility class for reading properties and gathering information for testing
- * Android device compatibility.
- */
-public class CpuFeatures {
-
-    private static String uname(ITestDevice device) throws DeviceNotAvailableException {
-        CollectingOutputReceiver Out = new CollectingOutputReceiver();
-        device.executeShellCommand("uname -m", Out);
-        return Out.getOutput().trim();
-    }
-
-    /**
-     * Return true if architecture is arm64.
-     */
-    public static boolean isArm64(ITestDevice device) throws DeviceNotAvailableException {
-
-        return uname(device).contains("aarch64");
-    }
-
-    /**
-     * Return true if architecture is arm32.
-     */
-    public static boolean isArm32(ITestDevice device) throws DeviceNotAvailableException {
-
-        return uname(device).contains("armv7");
-    }
-}
diff --git a/harness/Android.mk b/harness/Android.mk
new file mode 100644
index 0000000..948361a
--- /dev/null
+++ b/harness/Android.mk
@@ -0,0 +1,16 @@
+#
+# Copyright (C) 2018 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+include $(call all-subdir-makefiles)
diff --git a/common/host-side/Android.mk b/harness/common/Android.mk
similarity index 100%
copy from common/host-side/Android.mk
copy to harness/common/Android.mk
diff --git a/common/host-side/Android.mk b/harness/common/host-side/Android.mk
similarity index 100%
rename from common/host-side/Android.mk
rename to harness/common/host-side/Android.mk
diff --git a/common/host-side/manifest-generator/Android.mk b/harness/common/host-side/manifest-generator/Android.mk
similarity index 100%
rename from common/host-side/manifest-generator/Android.mk
rename to harness/common/host-side/manifest-generator/Android.mk
diff --git a/common/host-side/manifest-generator/MANIFEST.mf b/harness/common/host-side/manifest-generator/MANIFEST.mf
similarity index 100%
rename from common/host-side/manifest-generator/MANIFEST.mf
rename to harness/common/host-side/manifest-generator/MANIFEST.mf
diff --git a/common/host-side/manifest-generator/src/com/android/compatibility/common/generator/ManifestGenerator.java b/harness/common/host-side/manifest-generator/src/com/android/compatibility/common/generator/ManifestGenerator.java
similarity index 100%
rename from common/host-side/manifest-generator/src/com/android/compatibility/common/generator/ManifestGenerator.java
rename to harness/common/host-side/manifest-generator/src/com/android/compatibility/common/generator/ManifestGenerator.java
diff --git a/common/host-side/manifest-generator/tests/Android.mk b/harness/common/host-side/manifest-generator/tests/Android.mk
similarity index 100%
rename from common/host-side/manifest-generator/tests/Android.mk
rename to harness/common/host-side/manifest-generator/tests/Android.mk
diff --git a/common/host-side/manifest-generator/tests/run_tests.sh b/harness/common/host-side/manifest-generator/tests/run_tests.sh
similarity index 95%
rename from common/host-side/manifest-generator/tests/run_tests.sh
rename to harness/common/host-side/manifest-generator/tests/run_tests.sh
index 758589c..62abb19 100755
--- a/common/host-side/manifest-generator/tests/run_tests.sh
+++ b/harness/common/host-side/manifest-generator/tests/run_tests.sh
@@ -16,7 +16,7 @@
 
 # Helper script for running unit tests for compatibility libraries
 
-CTS_DIR=$(dirname ${0})/../../../..
+CTS_DIR=$(dirname ${0})/../../../../..
 source ${CTS_DIR}/test_defs.sh
 
 JARS="
diff --git a/common/host-side/manifest-generator/tests/src/com/android/compatibility/common/generator/ManifestGeneratorTest.java b/harness/common/host-side/manifest-generator/tests/src/com/android/compatibility/common/generator/ManifestGeneratorTest.java
similarity index 100%
rename from common/host-side/manifest-generator/tests/src/com/android/compatibility/common/generator/ManifestGeneratorTest.java
rename to harness/common/host-side/manifest-generator/tests/src/com/android/compatibility/common/generator/ManifestGeneratorTest.java
diff --git a/common/host-side/tradefed/.classpath b/harness/common/host-side/tradefed/.classpath
similarity index 100%
rename from common/host-side/tradefed/.classpath
rename to harness/common/host-side/tradefed/.classpath
diff --git a/common/host-side/tradefed/.project b/harness/common/host-side/tradefed/.project
similarity index 100%
rename from common/host-side/tradefed/.project
rename to harness/common/host-side/tradefed/.project
diff --git a/common/host-side/tradefed/Android.mk b/harness/common/host-side/tradefed/Android.mk
similarity index 100%
rename from common/host-side/tradefed/Android.mk
rename to harness/common/host-side/tradefed/Android.mk
diff --git a/common/host-side/tradefed/res/config/common-compatibility-config.xml b/harness/common/host-side/tradefed/res/config/common-compatibility-config.xml
similarity index 100%
rename from common/host-side/tradefed/res/config/common-compatibility-config.xml
rename to harness/common/host-side/tradefed/res/config/common-compatibility-config.xml
diff --git a/common/host-side/tradefed/res/config/cts-unit-tests.xml b/harness/common/host-side/tradefed/res/config/cts-unit-tests.xml
similarity index 100%
rename from common/host-side/tradefed/res/config/cts-unit-tests.xml
rename to harness/common/host-side/tradefed/res/config/cts-unit-tests.xml
diff --git a/common/host-side/tradefed/res/config/everything.xml b/harness/common/host-side/tradefed/res/config/everything.xml
similarity index 100%
rename from common/host-side/tradefed/res/config/everything.xml
rename to harness/common/host-side/tradefed/res/config/everything.xml
diff --git a/common/host-side/tradefed/res/config/metadata-config.xml b/harness/common/host-side/tradefed/res/config/metadata-config.xml
similarity index 100%
rename from common/host-side/tradefed/res/config/metadata-config.xml
rename to harness/common/host-side/tradefed/res/config/metadata-config.xml
diff --git a/common/host-side/tradefed/res/report/compatibility_failures.xsl b/harness/common/host-side/tradefed/res/report/compatibility_failures.xsl
similarity index 100%
rename from common/host-side/tradefed/res/report/compatibility_failures.xsl
rename to harness/common/host-side/tradefed/res/report/compatibility_failures.xsl
diff --git a/common/host-side/tradefed/res/report/compatibility_result.css b/harness/common/host-side/tradefed/res/report/compatibility_result.css
similarity index 100%
rename from common/host-side/tradefed/res/report/compatibility_result.css
rename to harness/common/host-side/tradefed/res/report/compatibility_result.css
diff --git a/common/host-side/tradefed/res/report/compatibility_result.xsd b/harness/common/host-side/tradefed/res/report/compatibility_result.xsd
similarity index 100%
rename from common/host-side/tradefed/res/report/compatibility_result.xsd
rename to harness/common/host-side/tradefed/res/report/compatibility_result.xsd
diff --git a/common/host-side/tradefed/res/report/compatibility_result.xsl b/harness/common/host-side/tradefed/res/report/compatibility_result.xsl
similarity index 100%
rename from common/host-side/tradefed/res/report/compatibility_result.xsl
rename to harness/common/host-side/tradefed/res/report/compatibility_result.xsl
diff --git a/common/host-side/tradefed/res/report/logo.png b/harness/common/host-side/tradefed/res/report/logo.png
similarity index 100%
rename from common/host-side/tradefed/res/report/logo.png
rename to harness/common/host-side/tradefed/res/report/logo.png
Binary files differ
diff --git a/common/host-side/tradefed/src/com/android/compatibility/common/tradefed/build/CompatibilityBuildHelper.java b/harness/common/host-side/tradefed/src/com/android/compatibility/common/tradefed/build/CompatibilityBuildHelper.java
similarity index 100%
rename from common/host-side/tradefed/src/com/android/compatibility/common/tradefed/build/CompatibilityBuildHelper.java
rename to harness/common/host-side/tradefed/src/com/android/compatibility/common/tradefed/build/CompatibilityBuildHelper.java
diff --git a/common/host-side/tradefed/src/com/android/compatibility/common/tradefed/build/CompatibilityBuildProvider.java b/harness/common/host-side/tradefed/src/com/android/compatibility/common/tradefed/build/CompatibilityBuildProvider.java
similarity index 100%
rename from common/host-side/tradefed/src/com/android/compatibility/common/tradefed/build/CompatibilityBuildProvider.java
rename to harness/common/host-side/tradefed/src/com/android/compatibility/common/tradefed/build/CompatibilityBuildProvider.java
diff --git a/common/host-side/tradefed/src/com/android/compatibility/common/tradefed/command/CompatibilityConsole.java b/harness/common/host-side/tradefed/src/com/android/compatibility/common/tradefed/command/CompatibilityConsole.java
similarity index 100%
rename from common/host-side/tradefed/src/com/android/compatibility/common/tradefed/command/CompatibilityConsole.java
rename to harness/common/host-side/tradefed/src/com/android/compatibility/common/tradefed/command/CompatibilityConsole.java
diff --git a/common/host-side/tradefed/src/com/android/compatibility/common/tradefed/result/ConsoleReporter.java b/harness/common/host-side/tradefed/src/com/android/compatibility/common/tradefed/result/ConsoleReporter.java
similarity index 100%
rename from common/host-side/tradefed/src/com/android/compatibility/common/tradefed/result/ConsoleReporter.java
rename to harness/common/host-side/tradefed/src/com/android/compatibility/common/tradefed/result/ConsoleReporter.java
diff --git a/common/host-side/tradefed/src/com/android/compatibility/common/tradefed/result/IModuleListener.java b/harness/common/host-side/tradefed/src/com/android/compatibility/common/tradefed/result/IModuleListener.java
similarity index 100%
rename from common/host-side/tradefed/src/com/android/compatibility/common/tradefed/result/IModuleListener.java
rename to harness/common/host-side/tradefed/src/com/android/compatibility/common/tradefed/result/IModuleListener.java
diff --git a/common/host-side/tradefed/src/com/android/compatibility/common/tradefed/result/InvocationFailureHandler.java b/harness/common/host-side/tradefed/src/com/android/compatibility/common/tradefed/result/InvocationFailureHandler.java
similarity index 100%
rename from common/host-side/tradefed/src/com/android/compatibility/common/tradefed/result/InvocationFailureHandler.java
rename to harness/common/host-side/tradefed/src/com/android/compatibility/common/tradefed/result/InvocationFailureHandler.java
diff --git a/common/host-side/tradefed/src/com/android/compatibility/common/tradefed/result/MetadataReporter.java b/harness/common/host-side/tradefed/src/com/android/compatibility/common/tradefed/result/MetadataReporter.java
similarity index 100%
rename from common/host-side/tradefed/src/com/android/compatibility/common/tradefed/result/MetadataReporter.java
rename to harness/common/host-side/tradefed/src/com/android/compatibility/common/tradefed/result/MetadataReporter.java
diff --git a/common/host-side/tradefed/src/com/android/compatibility/common/tradefed/result/ModuleListener.java b/harness/common/host-side/tradefed/src/com/android/compatibility/common/tradefed/result/ModuleListener.java
similarity index 100%
rename from common/host-side/tradefed/src/com/android/compatibility/common/tradefed/result/ModuleListener.java
rename to harness/common/host-side/tradefed/src/com/android/compatibility/common/tradefed/result/ModuleListener.java
diff --git a/common/host-side/tradefed/src/com/android/compatibility/common/tradefed/result/ResultReporter.java b/harness/common/host-side/tradefed/src/com/android/compatibility/common/tradefed/result/ResultReporter.java
similarity index 100%
rename from common/host-side/tradefed/src/com/android/compatibility/common/tradefed/result/ResultReporter.java
rename to harness/common/host-side/tradefed/src/com/android/compatibility/common/tradefed/result/ResultReporter.java
diff --git a/common/host-side/tradefed/src/com/android/compatibility/common/tradefed/result/SubPlanHelper.java b/harness/common/host-side/tradefed/src/com/android/compatibility/common/tradefed/result/SubPlanHelper.java
similarity index 100%
rename from common/host-side/tradefed/src/com/android/compatibility/common/tradefed/result/SubPlanHelper.java
rename to harness/common/host-side/tradefed/src/com/android/compatibility/common/tradefed/result/SubPlanHelper.java
diff --git a/common/host-side/tradefed/src/com/android/compatibility/common/tradefed/result/TestRunHandler.java b/harness/common/host-side/tradefed/src/com/android/compatibility/common/tradefed/result/TestRunHandler.java
similarity index 100%
rename from common/host-side/tradefed/src/com/android/compatibility/common/tradefed/result/TestRunHandler.java
rename to harness/common/host-side/tradefed/src/com/android/compatibility/common/tradefed/result/TestRunHandler.java
diff --git a/common/host-side/tradefed/src/com/android/compatibility/common/tradefed/result/suite/CertificationChecksumHelper.java b/harness/common/host-side/tradefed/src/com/android/compatibility/common/tradefed/result/suite/CertificationChecksumHelper.java
similarity index 100%
rename from common/host-side/tradefed/src/com/android/compatibility/common/tradefed/result/suite/CertificationChecksumHelper.java
rename to harness/common/host-side/tradefed/src/com/android/compatibility/common/tradefed/result/suite/CertificationChecksumHelper.java
diff --git a/common/host-side/tradefed/src/com/android/compatibility/common/tradefed/result/suite/CertificationResultXml.java b/harness/common/host-side/tradefed/src/com/android/compatibility/common/tradefed/result/suite/CertificationResultXml.java
similarity index 84%
rename from common/host-side/tradefed/src/com/android/compatibility/common/tradefed/result/suite/CertificationResultXml.java
rename to harness/common/host-side/tradefed/src/com/android/compatibility/common/tradefed/result/suite/CertificationResultXml.java
index 13eed58..4911d92 100644
--- a/common/host-side/tradefed/src/com/android/compatibility/common/tradefed/result/suite/CertificationResultXml.java
+++ b/harness/common/host-side/tradefed/src/com/android/compatibility/common/tradefed/result/suite/CertificationResultXml.java
@@ -16,9 +16,12 @@
 package com.android.compatibility.common.tradefed.result.suite;
 
 import com.android.tradefed.build.IBuildInfo;
+import com.android.tradefed.invoker.IInvocationContext;
 import com.android.tradefed.result.suite.SuiteResultHolder;
 import com.android.tradefed.result.suite.XmlSuiteResultFormatter;
 
+import org.xmlpull.v1.XmlPullParser;
+import org.xmlpull.v1.XmlPullParserException;
 import org.xmlpull.v1.XmlSerializer;
 
 import java.io.IOException;
@@ -82,6 +85,18 @@
         }
     }
 
+    @Override
+    public void parseSuiteAttributes(XmlPullParser parser, IInvocationContext context)
+            throws XmlPullParserException {
+        mSuiteName = parser.getAttributeValue(NS, SUITE_NAME_ATTR);
+        mSuiteVersion = parser.getAttributeValue(NS, SUITE_VERSION_ATTR);
+        mSuitePlan = parser.getAttributeValue(NS, SUITE_PLAN_ATTR);
+        mSuiteBuild = parser.getAttributeValue(NS, SUITE_BUILD_ATTR);
+
+        mReferenceUrl = parser.getAttributeValue(NS, REFERENCE_URL_ATTR);
+        mLogUrl = parser.getAttributeValue(NS, LOG_URL_ATTR);
+    }
+
     /**
      * Add compatibility specific build info attributes.
      */
diff --git a/common/host-side/tradefed/src/com/android/compatibility/common/tradefed/result/suite/CertificationSuiteResultReporter.java b/harness/common/host-side/tradefed/src/com/android/compatibility/common/tradefed/result/suite/CertificationSuiteResultReporter.java
similarity index 100%
rename from common/host-side/tradefed/src/com/android/compatibility/common/tradefed/result/suite/CertificationSuiteResultReporter.java
rename to harness/common/host-side/tradefed/src/com/android/compatibility/common/tradefed/result/suite/CertificationSuiteResultReporter.java
diff --git a/common/host-side/tradefed/src/com/android/compatibility/common/tradefed/targetprep/ApkInstaller.java b/harness/common/host-side/tradefed/src/com/android/compatibility/common/tradefed/targetprep/ApkInstaller.java
similarity index 100%
rename from common/host-side/tradefed/src/com/android/compatibility/common/tradefed/targetprep/ApkInstaller.java
rename to harness/common/host-side/tradefed/src/com/android/compatibility/common/tradefed/targetprep/ApkInstaller.java
diff --git a/common/host-side/tradefed/src/com/android/compatibility/common/tradefed/targetprep/ApkInstrumentationPreparer.java b/harness/common/host-side/tradefed/src/com/android/compatibility/common/tradefed/targetprep/ApkInstrumentationPreparer.java
similarity index 100%
rename from common/host-side/tradefed/src/com/android/compatibility/common/tradefed/targetprep/ApkInstrumentationPreparer.java
rename to harness/common/host-side/tradefed/src/com/android/compatibility/common/tradefed/targetprep/ApkInstrumentationPreparer.java
diff --git a/common/host-side/tradefed/src/com/android/compatibility/common/tradefed/targetprep/ApkPreconditionCheck.java b/harness/common/host-side/tradefed/src/com/android/compatibility/common/tradefed/targetprep/ApkPreconditionCheck.java
similarity index 100%
rename from common/host-side/tradefed/src/com/android/compatibility/common/tradefed/targetprep/ApkPreconditionCheck.java
rename to harness/common/host-side/tradefed/src/com/android/compatibility/common/tradefed/targetprep/ApkPreconditionCheck.java
diff --git a/common/host-side/tradefed/src/com/android/compatibility/common/tradefed/targetprep/BusinessLogicPreparer.java b/harness/common/host-side/tradefed/src/com/android/compatibility/common/tradefed/targetprep/BusinessLogicPreparer.java
similarity index 100%
rename from common/host-side/tradefed/src/com/android/compatibility/common/tradefed/targetprep/BusinessLogicPreparer.java
rename to harness/common/host-side/tradefed/src/com/android/compatibility/common/tradefed/targetprep/BusinessLogicPreparer.java
diff --git a/common/host-side/tradefed/src/com/android/compatibility/common/tradefed/targetprep/DeviceFileCollector.java b/harness/common/host-side/tradefed/src/com/android/compatibility/common/tradefed/targetprep/DeviceFileCollector.java
similarity index 100%
rename from common/host-side/tradefed/src/com/android/compatibility/common/tradefed/targetprep/DeviceFileCollector.java
rename to harness/common/host-side/tradefed/src/com/android/compatibility/common/tradefed/targetprep/DeviceFileCollector.java
diff --git a/common/host-side/tradefed/src/com/android/compatibility/common/tradefed/targetprep/DeviceInfoCollector.java b/harness/common/host-side/tradefed/src/com/android/compatibility/common/tradefed/targetprep/DeviceInfoCollector.java
similarity index 100%
rename from common/host-side/tradefed/src/com/android/compatibility/common/tradefed/targetprep/DeviceInfoCollector.java
rename to harness/common/host-side/tradefed/src/com/android/compatibility/common/tradefed/targetprep/DeviceInfoCollector.java
diff --git a/common/host-side/tradefed/src/com/android/compatibility/common/tradefed/targetprep/DynamicConfigPusher.java b/harness/common/host-side/tradefed/src/com/android/compatibility/common/tradefed/targetprep/DynamicConfigPusher.java
similarity index 100%
rename from common/host-side/tradefed/src/com/android/compatibility/common/tradefed/targetprep/DynamicConfigPusher.java
rename to harness/common/host-side/tradefed/src/com/android/compatibility/common/tradefed/targetprep/DynamicConfigPusher.java
diff --git a/common/host-side/tradefed/src/com/android/compatibility/common/tradefed/targetprep/FilePusher.java b/harness/common/host-side/tradefed/src/com/android/compatibility/common/tradefed/targetprep/FilePusher.java
similarity index 100%
rename from common/host-side/tradefed/src/com/android/compatibility/common/tradefed/targetprep/FilePusher.java
rename to harness/common/host-side/tradefed/src/com/android/compatibility/common/tradefed/targetprep/FilePusher.java
diff --git a/common/host-side/tradefed/src/com/android/compatibility/common/tradefed/targetprep/LocationCheck.java b/harness/common/host-side/tradefed/src/com/android/compatibility/common/tradefed/targetprep/LocationCheck.java
similarity index 100%
rename from common/host-side/tradefed/src/com/android/compatibility/common/tradefed/targetprep/LocationCheck.java
rename to harness/common/host-side/tradefed/src/com/android/compatibility/common/tradefed/targetprep/LocationCheck.java
diff --git a/common/host-side/tradefed/src/com/android/compatibility/common/tradefed/targetprep/MediaPreparer.java b/harness/common/host-side/tradefed/src/com/android/compatibility/common/tradefed/targetprep/MediaPreparer.java
similarity index 100%
rename from common/host-side/tradefed/src/com/android/compatibility/common/tradefed/targetprep/MediaPreparer.java
rename to harness/common/host-side/tradefed/src/com/android/compatibility/common/tradefed/targetprep/MediaPreparer.java
diff --git a/common/host-side/tradefed/src/com/android/compatibility/common/tradefed/targetprep/NetworkConnectivityChecker.java b/harness/common/host-side/tradefed/src/com/android/compatibility/common/tradefed/targetprep/NetworkConnectivityChecker.java
similarity index 100%
rename from common/host-side/tradefed/src/com/android/compatibility/common/tradefed/targetprep/NetworkConnectivityChecker.java
rename to harness/common/host-side/tradefed/src/com/android/compatibility/common/tradefed/targetprep/NetworkConnectivityChecker.java
diff --git a/common/host-side/tradefed/src/com/android/compatibility/common/tradefed/targetprep/PackageDisabler.java b/harness/common/host-side/tradefed/src/com/android/compatibility/common/tradefed/targetprep/PackageDisabler.java
similarity index 100%
rename from common/host-side/tradefed/src/com/android/compatibility/common/tradefed/targetprep/PackageDisabler.java
rename to harness/common/host-side/tradefed/src/com/android/compatibility/common/tradefed/targetprep/PackageDisabler.java
diff --git a/common/host-side/tradefed/src/com/android/compatibility/common/tradefed/targetprep/PreconditionPreparer.java b/harness/common/host-side/tradefed/src/com/android/compatibility/common/tradefed/targetprep/PreconditionPreparer.java
similarity index 100%
rename from common/host-side/tradefed/src/com/android/compatibility/common/tradefed/targetprep/PreconditionPreparer.java
rename to harness/common/host-side/tradefed/src/com/android/compatibility/common/tradefed/targetprep/PreconditionPreparer.java
diff --git a/common/host-side/tradefed/src/com/android/compatibility/common/tradefed/targetprep/PropertyCheck.java b/harness/common/host-side/tradefed/src/com/android/compatibility/common/tradefed/targetprep/PropertyCheck.java
similarity index 100%
rename from common/host-side/tradefed/src/com/android/compatibility/common/tradefed/targetprep/PropertyCheck.java
rename to harness/common/host-side/tradefed/src/com/android/compatibility/common/tradefed/targetprep/PropertyCheck.java
diff --git a/common/host-side/tradefed/src/com/android/compatibility/common/tradefed/targetprep/ReportLogCollector.java b/harness/common/host-side/tradefed/src/com/android/compatibility/common/tradefed/targetprep/ReportLogCollector.java
similarity index 100%
rename from common/host-side/tradefed/src/com/android/compatibility/common/tradefed/targetprep/ReportLogCollector.java
rename to harness/common/host-side/tradefed/src/com/android/compatibility/common/tradefed/targetprep/ReportLogCollector.java
diff --git a/common/host-side/tradefed/src/com/android/compatibility/common/tradefed/targetprep/ResultFilePuller.java b/harness/common/host-side/tradefed/src/com/android/compatibility/common/tradefed/targetprep/ResultFilePuller.java
similarity index 100%
rename from common/host-side/tradefed/src/com/android/compatibility/common/tradefed/targetprep/ResultFilePuller.java
rename to harness/common/host-side/tradefed/src/com/android/compatibility/common/tradefed/targetprep/ResultFilePuller.java
diff --git a/common/host-side/tradefed/src/com/android/compatibility/common/tradefed/targetprep/SettingsPreparer.java b/harness/common/host-side/tradefed/src/com/android/compatibility/common/tradefed/targetprep/SettingsPreparer.java
similarity index 100%
rename from common/host-side/tradefed/src/com/android/compatibility/common/tradefed/targetprep/SettingsPreparer.java
rename to harness/common/host-side/tradefed/src/com/android/compatibility/common/tradefed/targetprep/SettingsPreparer.java
diff --git a/common/host-side/tradefed/src/com/android/compatibility/common/tradefed/targetprep/StayAwakePreparer.java b/harness/common/host-side/tradefed/src/com/android/compatibility/common/tradefed/targetprep/StayAwakePreparer.java
similarity index 100%
rename from common/host-side/tradefed/src/com/android/compatibility/common/tradefed/targetprep/StayAwakePreparer.java
rename to harness/common/host-side/tradefed/src/com/android/compatibility/common/tradefed/targetprep/StayAwakePreparer.java
diff --git a/common/host-side/tradefed/src/com/android/compatibility/common/tradefed/targetprep/TokenRequirement.java b/harness/common/host-side/tradefed/src/com/android/compatibility/common/tradefed/targetprep/TokenRequirement.java
similarity index 100%
rename from common/host-side/tradefed/src/com/android/compatibility/common/tradefed/targetprep/TokenRequirement.java
rename to harness/common/host-side/tradefed/src/com/android/compatibility/common/tradefed/targetprep/TokenRequirement.java
diff --git a/common/host-side/tradefed/src/com/android/compatibility/common/tradefed/targetprep/WifiCheck.java b/harness/common/host-side/tradefed/src/com/android/compatibility/common/tradefed/targetprep/WifiCheck.java
similarity index 100%
rename from common/host-side/tradefed/src/com/android/compatibility/common/tradefed/targetprep/WifiCheck.java
rename to harness/common/host-side/tradefed/src/com/android/compatibility/common/tradefed/targetprep/WifiCheck.java
diff --git a/common/host-side/tradefed/src/com/android/compatibility/common/tradefed/testtype/BusinessLogicConditionalHostTestBase.java b/harness/common/host-side/tradefed/src/com/android/compatibility/common/tradefed/testtype/BusinessLogicConditionalHostTestBase.java
similarity index 100%
rename from common/host-side/tradefed/src/com/android/compatibility/common/tradefed/testtype/BusinessLogicConditionalHostTestBase.java
rename to harness/common/host-side/tradefed/src/com/android/compatibility/common/tradefed/testtype/BusinessLogicConditionalHostTestBase.java
diff --git a/common/host-side/tradefed/src/com/android/compatibility/common/tradefed/testtype/BusinessLogicHostTestBase.java b/harness/common/host-side/tradefed/src/com/android/compatibility/common/tradefed/testtype/BusinessLogicHostTestBase.java
similarity index 100%
rename from common/host-side/tradefed/src/com/android/compatibility/common/tradefed/testtype/BusinessLogicHostTestBase.java
rename to harness/common/host-side/tradefed/src/com/android/compatibility/common/tradefed/testtype/BusinessLogicHostTestBase.java
diff --git a/common/host-side/tradefed/src/com/android/compatibility/common/tradefed/testtype/CompatibilityTest.java b/harness/common/host-side/tradefed/src/com/android/compatibility/common/tradefed/testtype/CompatibilityTest.java
similarity index 100%
rename from common/host-side/tradefed/src/com/android/compatibility/common/tradefed/testtype/CompatibilityTest.java
rename to harness/common/host-side/tradefed/src/com/android/compatibility/common/tradefed/testtype/CompatibilityTest.java
diff --git a/common/host-side/tradefed/src/com/android/compatibility/common/tradefed/testtype/FailureListener.java b/harness/common/host-side/tradefed/src/com/android/compatibility/common/tradefed/testtype/FailureListener.java
similarity index 100%
rename from common/host-side/tradefed/src/com/android/compatibility/common/tradefed/testtype/FailureListener.java
rename to harness/common/host-side/tradefed/src/com/android/compatibility/common/tradefed/testtype/FailureListener.java
diff --git a/common/host-side/tradefed/src/com/android/compatibility/common/tradefed/testtype/IModuleDef.java b/harness/common/host-side/tradefed/src/com/android/compatibility/common/tradefed/testtype/IModuleDef.java
similarity index 100%
rename from common/host-side/tradefed/src/com/android/compatibility/common/tradefed/testtype/IModuleDef.java
rename to harness/common/host-side/tradefed/src/com/android/compatibility/common/tradefed/testtype/IModuleDef.java
diff --git a/common/host-side/tradefed/src/com/android/compatibility/common/tradefed/testtype/IModuleRepo.java b/harness/common/host-side/tradefed/src/com/android/compatibility/common/tradefed/testtype/IModuleRepo.java
similarity index 100%
rename from common/host-side/tradefed/src/com/android/compatibility/common/tradefed/testtype/IModuleRepo.java
rename to harness/common/host-side/tradefed/src/com/android/compatibility/common/tradefed/testtype/IModuleRepo.java
diff --git a/common/host-side/tradefed/src/com/android/compatibility/common/tradefed/testtype/ISubPlan.java b/harness/common/host-side/tradefed/src/com/android/compatibility/common/tradefed/testtype/ISubPlan.java
similarity index 100%
rename from common/host-side/tradefed/src/com/android/compatibility/common/tradefed/testtype/ISubPlan.java
rename to harness/common/host-side/tradefed/src/com/android/compatibility/common/tradefed/testtype/ISubPlan.java
diff --git a/common/host-side/tradefed/src/com/android/compatibility/common/tradefed/testtype/JarHostTest.java b/harness/common/host-side/tradefed/src/com/android/compatibility/common/tradefed/testtype/JarHostTest.java
similarity index 100%
rename from common/host-side/tradefed/src/com/android/compatibility/common/tradefed/testtype/JarHostTest.java
rename to harness/common/host-side/tradefed/src/com/android/compatibility/common/tradefed/testtype/JarHostTest.java
diff --git a/common/host-side/tradefed/src/com/android/compatibility/common/tradefed/testtype/ModuleDef.java b/harness/common/host-side/tradefed/src/com/android/compatibility/common/tradefed/testtype/ModuleDef.java
similarity index 100%
rename from common/host-side/tradefed/src/com/android/compatibility/common/tradefed/testtype/ModuleDef.java
rename to harness/common/host-side/tradefed/src/com/android/compatibility/common/tradefed/testtype/ModuleDef.java
diff --git a/common/host-side/tradefed/src/com/android/compatibility/common/tradefed/testtype/ModuleRepo.java b/harness/common/host-side/tradefed/src/com/android/compatibility/common/tradefed/testtype/ModuleRepo.java
similarity index 100%
rename from common/host-side/tradefed/src/com/android/compatibility/common/tradefed/testtype/ModuleRepo.java
rename to harness/common/host-side/tradefed/src/com/android/compatibility/common/tradefed/testtype/ModuleRepo.java
diff --git a/common/host-side/tradefed/src/com/android/compatibility/common/tradefed/testtype/SubPlan.java b/harness/common/host-side/tradefed/src/com/android/compatibility/common/tradefed/testtype/SubPlan.java
similarity index 100%
rename from common/host-side/tradefed/src/com/android/compatibility/common/tradefed/testtype/SubPlan.java
rename to harness/common/host-side/tradefed/src/com/android/compatibility/common/tradefed/testtype/SubPlan.java
diff --git a/common/host-side/tradefed/src/com/android/compatibility/common/tradefed/testtype/retry/RetryFactoryTest.java b/harness/common/host-side/tradefed/src/com/android/compatibility/common/tradefed/testtype/retry/RetryFactoryTest.java
similarity index 96%
rename from common/host-side/tradefed/src/com/android/compatibility/common/tradefed/testtype/retry/RetryFactoryTest.java
rename to harness/common/host-side/tradefed/src/com/android/compatibility/common/tradefed/testtype/retry/RetryFactoryTest.java
index 8a9f10a..eadaa21 100644
--- a/common/host-side/tradefed/src/com/android/compatibility/common/tradefed/testtype/retry/RetryFactoryTest.java
+++ b/harness/common/host-side/tradefed/src/com/android/compatibility/common/tradefed/testtype/retry/RetryFactoryTest.java
@@ -92,6 +92,12 @@
             importance = Importance.IF_UNSET)
     protected String mAbiName = null;
 
+    @Option(name = CompatibilityTestSuite.PRIMARY_ABI_RUN,
+            description =
+            "Whether to run tests with only the device primary abi. "
+                  + "This will override the --abi option.")
+    protected boolean mPrimaryAbiRun = false;
+
     @Option(name = CompatibilityTestSuite.MODULE_OPTION,
             shortName = 'm',
             description = "the test module to run.",
@@ -204,6 +210,8 @@
         test.setExcludeFilter(helper.getExcludeFilters());
         test.setDevice(mDevice);
         test.setBuild(mBuildInfo);
+        test.setAbiName(mAbiName);
+        test.setPrimaryAbiRun(mPrimaryAbiRun);
         test.setSystemStatusChecker(mStatusCheckers);
         test.setInvocationContext(mContext);
         test.setConfiguration(mMainConfiguration);
diff --git a/common/host-side/tradefed/src/com/android/compatibility/common/tradefed/testtype/suite/CompatibilitySuiteModuleLoader.java b/harness/common/host-side/tradefed/src/com/android/compatibility/common/tradefed/testtype/suite/CompatibilitySuiteModuleLoader.java
similarity index 100%
rename from common/host-side/tradefed/src/com/android/compatibility/common/tradefed/testtype/suite/CompatibilitySuiteModuleLoader.java
rename to harness/common/host-side/tradefed/src/com/android/compatibility/common/tradefed/testtype/suite/CompatibilitySuiteModuleLoader.java
diff --git a/common/host-side/tradefed/src/com/android/compatibility/common/tradefed/testtype/suite/CompatibilityTestSuite.java b/harness/common/host-side/tradefed/src/com/android/compatibility/common/tradefed/testtype/suite/CompatibilityTestSuite.java
similarity index 100%
rename from common/host-side/tradefed/src/com/android/compatibility/common/tradefed/testtype/suite/CompatibilityTestSuite.java
rename to harness/common/host-side/tradefed/src/com/android/compatibility/common/tradefed/testtype/suite/CompatibilityTestSuite.java
diff --git a/common/host-side/tradefed/src/com/android/compatibility/common/tradefed/util/CollectorUtil.java b/harness/common/host-side/tradefed/src/com/android/compatibility/common/tradefed/util/CollectorUtil.java
similarity index 100%
rename from common/host-side/tradefed/src/com/android/compatibility/common/tradefed/util/CollectorUtil.java
rename to harness/common/host-side/tradefed/src/com/android/compatibility/common/tradefed/util/CollectorUtil.java
diff --git a/common/host-side/tradefed/src/com/android/compatibility/common/tradefed/util/DynamicConfigFileReader.java b/harness/common/host-side/tradefed/src/com/android/compatibility/common/tradefed/util/DynamicConfigFileReader.java
similarity index 100%
rename from common/host-side/tradefed/src/com/android/compatibility/common/tradefed/util/DynamicConfigFileReader.java
rename to harness/common/host-side/tradefed/src/com/android/compatibility/common/tradefed/util/DynamicConfigFileReader.java
diff --git a/common/host-side/tradefed/src/com/android/compatibility/common/tradefed/util/LinearPartition.java b/harness/common/host-side/tradefed/src/com/android/compatibility/common/tradefed/util/LinearPartition.java
similarity index 100%
rename from common/host-side/tradefed/src/com/android/compatibility/common/tradefed/util/LinearPartition.java
rename to harness/common/host-side/tradefed/src/com/android/compatibility/common/tradefed/util/LinearPartition.java
diff --git a/common/host-side/tradefed/src/com/android/compatibility/common/tradefed/util/OptionHelper.java b/harness/common/host-side/tradefed/src/com/android/compatibility/common/tradefed/util/OptionHelper.java
similarity index 100%
rename from common/host-side/tradefed/src/com/android/compatibility/common/tradefed/util/OptionHelper.java
rename to harness/common/host-side/tradefed/src/com/android/compatibility/common/tradefed/util/OptionHelper.java
diff --git a/common/host-side/tradefed/src/com/android/compatibility/common/tradefed/util/RetryFilterHelper.java b/harness/common/host-side/tradefed/src/com/android/compatibility/common/tradefed/util/RetryFilterHelper.java
similarity index 100%
rename from common/host-side/tradefed/src/com/android/compatibility/common/tradefed/util/RetryFilterHelper.java
rename to harness/common/host-side/tradefed/src/com/android/compatibility/common/tradefed/util/RetryFilterHelper.java
diff --git a/common/host-side/tradefed/src/com/android/compatibility/common/tradefed/util/RetryType.java b/harness/common/host-side/tradefed/src/com/android/compatibility/common/tradefed/util/RetryType.java
similarity index 100%
rename from common/host-side/tradefed/src/com/android/compatibility/common/tradefed/util/RetryType.java
rename to harness/common/host-side/tradefed/src/com/android/compatibility/common/tradefed/util/RetryType.java
diff --git a/common/host-side/tradefed/src/com/android/compatibility/common/tradefed/util/UniqueModuleCountUtil.java b/harness/common/host-side/tradefed/src/com/android/compatibility/common/tradefed/util/UniqueModuleCountUtil.java
similarity index 100%
rename from common/host-side/tradefed/src/com/android/compatibility/common/tradefed/util/UniqueModuleCountUtil.java
rename to harness/common/host-side/tradefed/src/com/android/compatibility/common/tradefed/util/UniqueModuleCountUtil.java
diff --git a/common/host-side/tradefed/tests/Android.mk b/harness/common/host-side/tradefed/tests/Android.mk
similarity index 100%
rename from common/host-side/tradefed/tests/Android.mk
rename to harness/common/host-side/tradefed/tests/Android.mk
diff --git a/common/host-side/tradefed/tests/res/test-dynamic-config.dynamic b/harness/common/host-side/tradefed/tests/res/test-dynamic-config.dynamic
similarity index 100%
rename from common/host-side/tradefed/tests/res/test-dynamic-config.dynamic
rename to harness/common/host-side/tradefed/tests/res/test-dynamic-config.dynamic
diff --git a/common/host-side/tradefed/tests/res/testtype/testJar1.jar b/harness/common/host-side/tradefed/tests/res/testtype/testJar1.jar
similarity index 100%
rename from common/host-side/tradefed/tests/res/testtype/testJar1.jar
rename to harness/common/host-side/tradefed/tests/res/testtype/testJar1.jar
Binary files differ
diff --git a/common/host-side/tradefed/tests/res/testtype/testJar2.jar b/harness/common/host-side/tradefed/tests/res/testtype/testJar2.jar
similarity index 100%
rename from common/host-side/tradefed/tests/res/testtype/testJar2.jar
rename to harness/common/host-side/tradefed/tests/res/testtype/testJar2.jar
Binary files differ
diff --git a/common/host-side/tradefed/tests/run_tests.sh b/harness/common/host-side/tradefed/tests/run_tests.sh
similarity index 95%
rename from common/host-side/tradefed/tests/run_tests.sh
rename to harness/common/host-side/tradefed/tests/run_tests.sh
index 1d1940d..e772e54 100755
--- a/common/host-side/tradefed/tests/run_tests.sh
+++ b/harness/common/host-side/tradefed/tests/run_tests.sh
@@ -14,7 +14,7 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 
-CTS_DIR=$(dirname ${0})/../../../..
+CTS_DIR=$(dirname ${0})/../../../../..
 source ${CTS_DIR}/test_defs.sh
 
 JARS="
diff --git a/common/host-side/tradefed/tests/src/com/android/compatibility/common/tradefed/UnitTests.java b/harness/common/host-side/tradefed/tests/src/com/android/compatibility/common/tradefed/UnitTests.java
similarity index 100%
rename from common/host-side/tradefed/tests/src/com/android/compatibility/common/tradefed/UnitTests.java
rename to harness/common/host-side/tradefed/tests/src/com/android/compatibility/common/tradefed/UnitTests.java
diff --git a/common/host-side/tradefed/tests/src/com/android/compatibility/common/tradefed/build/CompatibilityBuildHelperTest.java b/harness/common/host-side/tradefed/tests/src/com/android/compatibility/common/tradefed/build/CompatibilityBuildHelperTest.java
similarity index 100%
rename from common/host-side/tradefed/tests/src/com/android/compatibility/common/tradefed/build/CompatibilityBuildHelperTest.java
rename to harness/common/host-side/tradefed/tests/src/com/android/compatibility/common/tradefed/build/CompatibilityBuildHelperTest.java
diff --git a/common/host-side/tradefed/tests/src/com/android/compatibility/common/tradefed/build/CompatibilityBuildProviderTest.java b/harness/common/host-side/tradefed/tests/src/com/android/compatibility/common/tradefed/build/CompatibilityBuildProviderTest.java
similarity index 100%
rename from common/host-side/tradefed/tests/src/com/android/compatibility/common/tradefed/build/CompatibilityBuildProviderTest.java
rename to harness/common/host-side/tradefed/tests/src/com/android/compatibility/common/tradefed/build/CompatibilityBuildProviderTest.java
diff --git a/common/host-side/tradefed/tests/src/com/android/compatibility/common/tradefed/command/CompatibilityConsoleTest.java b/harness/common/host-side/tradefed/tests/src/com/android/compatibility/common/tradefed/command/CompatibilityConsoleTest.java
similarity index 100%
rename from common/host-side/tradefed/tests/src/com/android/compatibility/common/tradefed/command/CompatibilityConsoleTest.java
rename to harness/common/host-side/tradefed/tests/src/com/android/compatibility/common/tradefed/command/CompatibilityConsoleTest.java
diff --git a/common/host-side/tradefed/tests/src/com/android/compatibility/common/tradefed/config/ConfigurationFactoryTest.java b/harness/common/host-side/tradefed/tests/src/com/android/compatibility/common/tradefed/config/ConfigurationFactoryTest.java
similarity index 100%
rename from common/host-side/tradefed/tests/src/com/android/compatibility/common/tradefed/config/ConfigurationFactoryTest.java
rename to harness/common/host-side/tradefed/tests/src/com/android/compatibility/common/tradefed/config/ConfigurationFactoryTest.java
diff --git a/common/host-side/tradefed/tests/src/com/android/compatibility/common/tradefed/presubmit/ApkPackageNameCheck.java b/harness/common/host-side/tradefed/tests/src/com/android/compatibility/common/tradefed/presubmit/ApkPackageNameCheck.java
similarity index 100%
rename from common/host-side/tradefed/tests/src/com/android/compatibility/common/tradefed/presubmit/ApkPackageNameCheck.java
rename to harness/common/host-side/tradefed/tests/src/com/android/compatibility/common/tradefed/presubmit/ApkPackageNameCheck.java
diff --git a/common/host-side/tradefed/tests/src/com/android/compatibility/common/tradefed/presubmit/CtsConfigLoadingTest.java b/harness/common/host-side/tradefed/tests/src/com/android/compatibility/common/tradefed/presubmit/CtsConfigLoadingTest.java
similarity index 100%
rename from common/host-side/tradefed/tests/src/com/android/compatibility/common/tradefed/presubmit/CtsConfigLoadingTest.java
rename to harness/common/host-side/tradefed/tests/src/com/android/compatibility/common/tradefed/presubmit/CtsConfigLoadingTest.java
diff --git a/common/host-side/tradefed/tests/src/com/android/compatibility/common/tradefed/presubmit/IntegrationTest.java b/harness/common/host-side/tradefed/tests/src/com/android/compatibility/common/tradefed/presubmit/IntegrationTest.java
similarity index 100%
rename from common/host-side/tradefed/tests/src/com/android/compatibility/common/tradefed/presubmit/IntegrationTest.java
rename to harness/common/host-side/tradefed/tests/src/com/android/compatibility/common/tradefed/presubmit/IntegrationTest.java
diff --git a/common/host-side/tradefed/tests/src/com/android/compatibility/common/tradefed/presubmit/PresubmitSetupValidation.java b/harness/common/host-side/tradefed/tests/src/com/android/compatibility/common/tradefed/presubmit/PresubmitSetupValidation.java
similarity index 100%
rename from common/host-side/tradefed/tests/src/com/android/compatibility/common/tradefed/presubmit/PresubmitSetupValidation.java
rename to harness/common/host-side/tradefed/tests/src/com/android/compatibility/common/tradefed/presubmit/PresubmitSetupValidation.java
diff --git a/common/host-side/tradefed/tests/src/com/android/compatibility/common/tradefed/presubmit/ValidateTestsAbi.java b/harness/common/host-side/tradefed/tests/src/com/android/compatibility/common/tradefed/presubmit/ValidateTestsAbi.java
similarity index 100%
rename from common/host-side/tradefed/tests/src/com/android/compatibility/common/tradefed/presubmit/ValidateTestsAbi.java
rename to harness/common/host-side/tradefed/tests/src/com/android/compatibility/common/tradefed/presubmit/ValidateTestsAbi.java
diff --git a/common/host-side/tradefed/tests/src/com/android/compatibility/common/tradefed/result/ChecksumReporterTest.java b/harness/common/host-side/tradefed/tests/src/com/android/compatibility/common/tradefed/result/ChecksumReporterTest.java
similarity index 100%
rename from common/host-side/tradefed/tests/src/com/android/compatibility/common/tradefed/result/ChecksumReporterTest.java
rename to harness/common/host-side/tradefed/tests/src/com/android/compatibility/common/tradefed/result/ChecksumReporterTest.java
diff --git a/common/host-side/tradefed/tests/src/com/android/compatibility/common/tradefed/result/ConsoleReporterTest.java b/harness/common/host-side/tradefed/tests/src/com/android/compatibility/common/tradefed/result/ConsoleReporterTest.java
similarity index 100%
rename from common/host-side/tradefed/tests/src/com/android/compatibility/common/tradefed/result/ConsoleReporterTest.java
rename to harness/common/host-side/tradefed/tests/src/com/android/compatibility/common/tradefed/result/ConsoleReporterTest.java
diff --git a/common/host-side/tradefed/tests/src/com/android/compatibility/common/tradefed/result/MetadataReporterTest.java b/harness/common/host-side/tradefed/tests/src/com/android/compatibility/common/tradefed/result/MetadataReporterTest.java
similarity index 100%
rename from common/host-side/tradefed/tests/src/com/android/compatibility/common/tradefed/result/MetadataReporterTest.java
rename to harness/common/host-side/tradefed/tests/src/com/android/compatibility/common/tradefed/result/MetadataReporterTest.java
diff --git a/common/host-side/tradefed/tests/src/com/android/compatibility/common/tradefed/result/ResultReporterBuildInfoTest.java b/harness/common/host-side/tradefed/tests/src/com/android/compatibility/common/tradefed/result/ResultReporterBuildInfoTest.java
similarity index 100%
rename from common/host-side/tradefed/tests/src/com/android/compatibility/common/tradefed/result/ResultReporterBuildInfoTest.java
rename to harness/common/host-side/tradefed/tests/src/com/android/compatibility/common/tradefed/result/ResultReporterBuildInfoTest.java
diff --git a/common/host-side/tradefed/tests/src/com/android/compatibility/common/tradefed/result/ResultReporterTest.java b/harness/common/host-side/tradefed/tests/src/com/android/compatibility/common/tradefed/result/ResultReporterTest.java
similarity index 100%
rename from common/host-side/tradefed/tests/src/com/android/compatibility/common/tradefed/result/ResultReporterTest.java
rename to harness/common/host-side/tradefed/tests/src/com/android/compatibility/common/tradefed/result/ResultReporterTest.java
diff --git a/common/host-side/tradefed/tests/src/com/android/compatibility/common/tradefed/result/SubPlanHelperTest.java b/harness/common/host-side/tradefed/tests/src/com/android/compatibility/common/tradefed/result/SubPlanHelperTest.java
similarity index 100%
rename from common/host-side/tradefed/tests/src/com/android/compatibility/common/tradefed/result/SubPlanHelperTest.java
rename to harness/common/host-side/tradefed/tests/src/com/android/compatibility/common/tradefed/result/SubPlanHelperTest.java
diff --git a/common/host-side/tradefed/tests/src/com/android/compatibility/common/tradefed/result/suite/CertificationChecksumHelperTest.java b/harness/common/host-side/tradefed/tests/src/com/android/compatibility/common/tradefed/result/suite/CertificationChecksumHelperTest.java
similarity index 100%
rename from common/host-side/tradefed/tests/src/com/android/compatibility/common/tradefed/result/suite/CertificationChecksumHelperTest.java
rename to harness/common/host-side/tradefed/tests/src/com/android/compatibility/common/tradefed/result/suite/CertificationChecksumHelperTest.java
diff --git a/common/host-side/tradefed/tests/src/com/android/compatibility/common/tradefed/targetprep/DynamicConfigPusherTest.java b/harness/common/host-side/tradefed/tests/src/com/android/compatibility/common/tradefed/targetprep/DynamicConfigPusherTest.java
similarity index 100%
rename from common/host-side/tradefed/tests/src/com/android/compatibility/common/tradefed/targetprep/DynamicConfigPusherTest.java
rename to harness/common/host-side/tradefed/tests/src/com/android/compatibility/common/tradefed/targetprep/DynamicConfigPusherTest.java
diff --git a/common/host-side/tradefed/tests/src/com/android/compatibility/common/tradefed/targetprep/MediaPreparerTest.java b/harness/common/host-side/tradefed/tests/src/com/android/compatibility/common/tradefed/targetprep/MediaPreparerTest.java
similarity index 100%
rename from common/host-side/tradefed/tests/src/com/android/compatibility/common/tradefed/targetprep/MediaPreparerTest.java
rename to harness/common/host-side/tradefed/tests/src/com/android/compatibility/common/tradefed/targetprep/MediaPreparerTest.java
diff --git a/common/host-side/tradefed/tests/src/com/android/compatibility/common/tradefed/targetprep/PropertyCheckTest.java b/harness/common/host-side/tradefed/tests/src/com/android/compatibility/common/tradefed/targetprep/PropertyCheckTest.java
similarity index 100%
rename from common/host-side/tradefed/tests/src/com/android/compatibility/common/tradefed/targetprep/PropertyCheckTest.java
rename to harness/common/host-side/tradefed/tests/src/com/android/compatibility/common/tradefed/targetprep/PropertyCheckTest.java
diff --git a/common/host-side/tradefed/tests/src/com/android/compatibility/common/tradefed/targetprep/SettingsPreparerTest.java b/harness/common/host-side/tradefed/tests/src/com/android/compatibility/common/tradefed/targetprep/SettingsPreparerTest.java
similarity index 100%
rename from common/host-side/tradefed/tests/src/com/android/compatibility/common/tradefed/targetprep/SettingsPreparerTest.java
rename to harness/common/host-side/tradefed/tests/src/com/android/compatibility/common/tradefed/targetprep/SettingsPreparerTest.java
diff --git a/common/host-side/tradefed/tests/src/com/android/compatibility/common/tradefed/testtype/CompatibilityTestTest.java b/harness/common/host-side/tradefed/tests/src/com/android/compatibility/common/tradefed/testtype/CompatibilityTestTest.java
similarity index 100%
rename from common/host-side/tradefed/tests/src/com/android/compatibility/common/tradefed/testtype/CompatibilityTestTest.java
rename to harness/common/host-side/tradefed/tests/src/com/android/compatibility/common/tradefed/testtype/CompatibilityTestTest.java
diff --git a/common/host-side/tradefed/tests/src/com/android/compatibility/common/tradefed/testtype/JarHostTestTest.java b/harness/common/host-side/tradefed/tests/src/com/android/compatibility/common/tradefed/testtype/JarHostTestTest.java
similarity index 100%
rename from common/host-side/tradefed/tests/src/com/android/compatibility/common/tradefed/testtype/JarHostTestTest.java
rename to harness/common/host-side/tradefed/tests/src/com/android/compatibility/common/tradefed/testtype/JarHostTestTest.java
diff --git a/common/host-side/tradefed/tests/src/com/android/compatibility/common/tradefed/testtype/ModuleDefTest.java b/harness/common/host-side/tradefed/tests/src/com/android/compatibility/common/tradefed/testtype/ModuleDefTest.java
similarity index 100%
rename from common/host-side/tradefed/tests/src/com/android/compatibility/common/tradefed/testtype/ModuleDefTest.java
rename to harness/common/host-side/tradefed/tests/src/com/android/compatibility/common/tradefed/testtype/ModuleDefTest.java
diff --git a/common/host-side/tradefed/tests/src/com/android/compatibility/common/tradefed/testtype/ModuleRepoTest.java b/harness/common/host-side/tradefed/tests/src/com/android/compatibility/common/tradefed/testtype/ModuleRepoTest.java
similarity index 100%
rename from common/host-side/tradefed/tests/src/com/android/compatibility/common/tradefed/testtype/ModuleRepoTest.java
rename to harness/common/host-side/tradefed/tests/src/com/android/compatibility/common/tradefed/testtype/ModuleRepoTest.java
diff --git a/common/host-side/tradefed/tests/src/com/android/compatibility/common/tradefed/testtype/ShardableTestStub.java b/harness/common/host-side/tradefed/tests/src/com/android/compatibility/common/tradefed/testtype/ShardableTestStub.java
similarity index 100%
rename from common/host-side/tradefed/tests/src/com/android/compatibility/common/tradefed/testtype/ShardableTestStub.java
rename to harness/common/host-side/tradefed/tests/src/com/android/compatibility/common/tradefed/testtype/ShardableTestStub.java
diff --git a/common/host-side/tradefed/tests/src/com/android/compatibility/common/tradefed/testtype/SimpleTestStub.java b/harness/common/host-side/tradefed/tests/src/com/android/compatibility/common/tradefed/testtype/SimpleTestStub.java
similarity index 100%
rename from common/host-side/tradefed/tests/src/com/android/compatibility/common/tradefed/testtype/SimpleTestStub.java
rename to harness/common/host-side/tradefed/tests/src/com/android/compatibility/common/tradefed/testtype/SimpleTestStub.java
diff --git a/common/host-side/tradefed/tests/src/com/android/compatibility/common/tradefed/testtype/SubPlanTest.java b/harness/common/host-side/tradefed/tests/src/com/android/compatibility/common/tradefed/testtype/SubPlanTest.java
similarity index 100%
rename from common/host-side/tradefed/tests/src/com/android/compatibility/common/tradefed/testtype/SubPlanTest.java
rename to harness/common/host-side/tradefed/tests/src/com/android/compatibility/common/tradefed/testtype/SubPlanTest.java
diff --git a/common/host-side/tradefed/tests/src/com/android/compatibility/common/tradefed/testtype/TestStub.java b/harness/common/host-side/tradefed/tests/src/com/android/compatibility/common/tradefed/testtype/TestStub.java
similarity index 100%
rename from common/host-side/tradefed/tests/src/com/android/compatibility/common/tradefed/testtype/TestStub.java
rename to harness/common/host-side/tradefed/tests/src/com/android/compatibility/common/tradefed/testtype/TestStub.java
diff --git a/common/host-side/tradefed/tests/src/com/android/compatibility/common/tradefed/testtype/TestStubShardable.java b/harness/common/host-side/tradefed/tests/src/com/android/compatibility/common/tradefed/testtype/TestStubShardable.java
similarity index 100%
rename from common/host-side/tradefed/tests/src/com/android/compatibility/common/tradefed/testtype/TestStubShardable.java
rename to harness/common/host-side/tradefed/tests/src/com/android/compatibility/common/tradefed/testtype/TestStubShardable.java
diff --git a/common/host-side/tradefed/tests/src/com/android/compatibility/common/tradefed/testtype/retry/RetryFactoryTestTest.java b/harness/common/host-side/tradefed/tests/src/com/android/compatibility/common/tradefed/testtype/retry/RetryFactoryTestTest.java
similarity index 100%
rename from common/host-side/tradefed/tests/src/com/android/compatibility/common/tradefed/testtype/retry/RetryFactoryTestTest.java
rename to harness/common/host-side/tradefed/tests/src/com/android/compatibility/common/tradefed/testtype/retry/RetryFactoryTestTest.java
diff --git a/common/host-side/tradefed/tests/src/com/android/compatibility/common/tradefed/util/CollectorUtilTest.java b/harness/common/host-side/tradefed/tests/src/com/android/compatibility/common/tradefed/util/CollectorUtilTest.java
similarity index 100%
rename from common/host-side/tradefed/tests/src/com/android/compatibility/common/tradefed/util/CollectorUtilTest.java
rename to harness/common/host-side/tradefed/tests/src/com/android/compatibility/common/tradefed/util/CollectorUtilTest.java
diff --git a/common/host-side/tradefed/tests/src/com/android/compatibility/common/tradefed/util/DynamicConfigFileReaderTest.java b/harness/common/host-side/tradefed/tests/src/com/android/compatibility/common/tradefed/util/DynamicConfigFileReaderTest.java
similarity index 100%
rename from common/host-side/tradefed/tests/src/com/android/compatibility/common/tradefed/util/DynamicConfigFileReaderTest.java
rename to harness/common/host-side/tradefed/tests/src/com/android/compatibility/common/tradefed/util/DynamicConfigFileReaderTest.java
diff --git a/common/host-side/tradefed/tests/src/com/android/compatibility/common/tradefed/util/OptionHelperTest.java b/harness/common/host-side/tradefed/tests/src/com/android/compatibility/common/tradefed/util/OptionHelperTest.java
similarity index 100%
rename from common/host-side/tradefed/tests/src/com/android/compatibility/common/tradefed/util/OptionHelperTest.java
rename to harness/common/host-side/tradefed/tests/src/com/android/compatibility/common/tradefed/util/OptionHelperTest.java
diff --git a/common/host-side/tradefed/tests/src/com/android/compatibility/common/tradefed/util/RetryFilterHelperTest.java b/harness/common/host-side/tradefed/tests/src/com/android/compatibility/common/tradefed/util/RetryFilterHelperTest.java
similarity index 100%
rename from common/host-side/tradefed/tests/src/com/android/compatibility/common/tradefed/util/RetryFilterHelperTest.java
rename to harness/common/host-side/tradefed/tests/src/com/android/compatibility/common/tradefed/util/RetryFilterHelperTest.java
diff --git a/common/host-side/tradefed/tests/src/com/android/compatibility/common/tradefed/util/UniqueModuleCountUtilTest.java b/harness/common/host-side/tradefed/tests/src/com/android/compatibility/common/tradefed/util/UniqueModuleCountUtilTest.java
similarity index 100%
rename from common/host-side/tradefed/tests/src/com/android/compatibility/common/tradefed/util/UniqueModuleCountUtilTest.java
rename to harness/common/host-side/tradefed/tests/src/com/android/compatibility/common/tradefed/util/UniqueModuleCountUtilTest.java
diff --git a/common/host-side/util/.classpath b/harness/common/host-side/util/.classpath
similarity index 100%
rename from common/host-side/util/.classpath
rename to harness/common/host-side/util/.classpath
diff --git a/common/host-side/util/.project b/harness/common/host-side/util/.project
similarity index 100%
rename from common/host-side/util/.project
rename to harness/common/host-side/util/.project
diff --git a/common/host-side/util/Android.mk b/harness/common/host-side/util/Android.mk
similarity index 100%
rename from common/host-side/util/Android.mk
rename to harness/common/host-side/util/Android.mk
diff --git a/common/host-side/util/src/com/android/compatibility/common/util/ApiLevelUtil.java b/harness/common/host-side/util/src/com/android/compatibility/common/util/ApiLevelUtil.java
similarity index 100%
rename from common/host-side/util/src/com/android/compatibility/common/util/ApiLevelUtil.java
rename to harness/common/host-side/util/src/com/android/compatibility/common/util/ApiLevelUtil.java
diff --git a/common/host-side/util/src/com/android/compatibility/common/util/BusinessLogicHostExecutor.java b/harness/common/host-side/util/src/com/android/compatibility/common/util/BusinessLogicHostExecutor.java
similarity index 100%
rename from common/host-side/util/src/com/android/compatibility/common/util/BusinessLogicHostExecutor.java
rename to harness/common/host-side/util/src/com/android/compatibility/common/util/BusinessLogicHostExecutor.java
diff --git a/harness/common/host-side/util/src/com/android/compatibility/common/util/CpuFeatures.java b/harness/common/host-side/util/src/com/android/compatibility/common/util/CpuFeatures.java
new file mode 100644
index 0000000..123a320
--- /dev/null
+++ b/harness/common/host-side/util/src/com/android/compatibility/common/util/CpuFeatures.java
@@ -0,0 +1,74 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.compatibility.common.util;
+import com.android.tradefed.device.CollectingOutputReceiver;
+
+import com.android.tradefed.device.DeviceNotAvailableException;
+import com.android.tradefed.device.ITestDevice;
+import java.util.regex.Pattern;
+
+/**
+ * Host-side utility class for reading properties and gathering information for testing
+ * Android device compatibility.
+ */
+public class CpuFeatures {
+
+    private static final String UNAME_OPTION_MACHINE_TYPE = "-m";
+    private static final String UNAME_OPTION_KERNEL_RELEASE = "-r";
+
+    private static String uname(ITestDevice device, String option) throws DeviceNotAvailableException {
+        CollectingOutputReceiver Out = new CollectingOutputReceiver();
+        device.executeShellCommand("uname " + option, Out);
+        return Out.getOutput().trim();
+    }
+
+    /**
+     * Return true if architecture is arm64.
+     */
+    public static boolean isArm64(ITestDevice device) throws DeviceNotAvailableException {
+
+        return uname(device, UNAME_OPTION_MACHINE_TYPE).contains("aarch64");
+    }
+
+    /**
+     * Return true if architecture is arm32.
+     */
+    public static boolean isArm32(ITestDevice device) throws DeviceNotAvailableException {
+
+        return uname(device, UNAME_OPTION_MACHINE_TYPE).contains("armv7");
+    }
+
+    /**
+     * Return true if architecture is x86.
+     */
+    public static boolean isX86(ITestDevice device) throws DeviceNotAvailableException {
+
+        return uname(device, UNAME_OPTION_MACHINE_TYPE).contains("x86");
+    }
+
+    /**
+     * Return true kernel if version is less than input values.
+     */
+    public static boolean kernelVersionLessThan(ITestDevice device, int major, int minor)
+            throws DeviceNotAvailableException {
+
+        String[] kernelVersion = uname(device, UNAME_OPTION_KERNEL_RELEASE).split(Pattern.quote("."));
+        int deviceMajor = Integer.parseInt(kernelVersion[0]);
+        int deviceMinor = Integer.parseInt(kernelVersion[1]);
+
+        return (major < deviceMajor) || ((major == deviceMajor) && (minor < deviceMinor));
+    }
+}
diff --git a/common/host-side/util/src/com/android/compatibility/common/util/DeviceInfo.java b/harness/common/host-side/util/src/com/android/compatibility/common/util/DeviceInfo.java
similarity index 100%
rename from common/host-side/util/src/com/android/compatibility/common/util/DeviceInfo.java
rename to harness/common/host-side/util/src/com/android/compatibility/common/util/DeviceInfo.java
diff --git a/common/host-side/util/src/com/android/compatibility/common/util/DynamicConfigHandler.java b/harness/common/host-side/util/src/com/android/compatibility/common/util/DynamicConfigHandler.java
similarity index 100%
rename from common/host-side/util/src/com/android/compatibility/common/util/DynamicConfigHandler.java
rename to harness/common/host-side/util/src/com/android/compatibility/common/util/DynamicConfigHandler.java
diff --git a/common/host-side/util/src/com/android/compatibility/common/util/DynamicConfigHostSide.java b/harness/common/host-side/util/src/com/android/compatibility/common/util/DynamicConfigHostSide.java
similarity index 100%
rename from common/host-side/util/src/com/android/compatibility/common/util/DynamicConfigHostSide.java
rename to harness/common/host-side/util/src/com/android/compatibility/common/util/DynamicConfigHostSide.java
diff --git a/common/host-side/util/src/com/android/compatibility/common/util/FeatureUtil.java b/harness/common/host-side/util/src/com/android/compatibility/common/util/FeatureUtil.java
similarity index 100%
rename from common/host-side/util/src/com/android/compatibility/common/util/FeatureUtil.java
rename to harness/common/host-side/util/src/com/android/compatibility/common/util/FeatureUtil.java
diff --git a/common/host-side/util/src/com/android/compatibility/common/util/HostInfoStore.java b/harness/common/host-side/util/src/com/android/compatibility/common/util/HostInfoStore.java
similarity index 100%
rename from common/host-side/util/src/com/android/compatibility/common/util/HostInfoStore.java
rename to harness/common/host-side/util/src/com/android/compatibility/common/util/HostInfoStore.java
diff --git a/common/host-side/util/src/com/android/compatibility/common/util/MetricsReportLog.java b/harness/common/host-side/util/src/com/android/compatibility/common/util/MetricsReportLog.java
similarity index 98%
rename from common/host-side/util/src/com/android/compatibility/common/util/MetricsReportLog.java
rename to harness/common/host-side/util/src/com/android/compatibility/common/util/MetricsReportLog.java
index c45972d..39b5e33 100644
--- a/common/host-side/util/src/com/android/compatibility/common/util/MetricsReportLog.java
+++ b/harness/common/host-side/util/src/com/android/compatibility/common/util/MetricsReportLog.java
@@ -31,7 +31,7 @@
     private final IBuildInfo mBuildInfo;
 
     // Temporary folder must match the temp-dir value configured in ReportLogCollector target
-    // preparer in cts/tools/cts-tradefed/res/config/cts-oreconditions.xml
+    // preparer in cts/harness/tools/cts-tradefed/res/config/cts-oreconditions.xml
     private static final String TEMPORARY_REPORT_FOLDER = "temp-report-logs";
     private ReportLogHostInfoStore store;
 
diff --git a/common/host-side/util/src/com/android/compatibility/common/util/MetricsStore.java b/harness/common/host-side/util/src/com/android/compatibility/common/util/MetricsStore.java
similarity index 100%
rename from common/host-side/util/src/com/android/compatibility/common/util/MetricsStore.java
rename to harness/common/host-side/util/src/com/android/compatibility/common/util/MetricsStore.java
diff --git a/common/host-side/util/src/com/android/compatibility/common/util/MonitoringUtils.java b/harness/common/host-side/util/src/com/android/compatibility/common/util/MonitoringUtils.java
similarity index 100%
rename from common/host-side/util/src/com/android/compatibility/common/util/MonitoringUtils.java
rename to harness/common/host-side/util/src/com/android/compatibility/common/util/MonitoringUtils.java
diff --git a/common/host-side/util/src/com/android/compatibility/common/util/PackageUtil.java b/harness/common/host-side/util/src/com/android/compatibility/common/util/PackageUtil.java
similarity index 100%
rename from common/host-side/util/src/com/android/compatibility/common/util/PackageUtil.java
rename to harness/common/host-side/util/src/com/android/compatibility/common/util/PackageUtil.java
diff --git a/common/host-side/util/src/com/android/compatibility/common/util/PropertyUtil.java b/harness/common/host-side/util/src/com/android/compatibility/common/util/PropertyUtil.java
similarity index 100%
rename from common/host-side/util/src/com/android/compatibility/common/util/PropertyUtil.java
rename to harness/common/host-side/util/src/com/android/compatibility/common/util/PropertyUtil.java
diff --git a/common/host-side/util/src/com/android/compatibility/common/util/ReportLogHostInfoStore.java b/harness/common/host-side/util/src/com/android/compatibility/common/util/ReportLogHostInfoStore.java
similarity index 100%
rename from common/host-side/util/src/com/android/compatibility/common/util/ReportLogHostInfoStore.java
rename to harness/common/host-side/util/src/com/android/compatibility/common/util/ReportLogHostInfoStore.java
diff --git a/common/host-side/util/src/com/android/compatibility/common/util/RootProcessScanner.java b/harness/common/host-side/util/src/com/android/compatibility/common/util/RootProcessScanner.java
similarity index 100%
rename from common/host-side/util/src/com/android/compatibility/common/util/RootProcessScanner.java
rename to harness/common/host-side/util/src/com/android/compatibility/common/util/RootProcessScanner.java
diff --git a/common/host-side/util/src/com/android/compatibility/common/util/ShellCommandUtil.java b/harness/common/host-side/util/src/com/android/compatibility/common/util/ShellCommandUtil.java
similarity index 100%
rename from common/host-side/util/src/com/android/compatibility/common/util/ShellCommandUtil.java
rename to harness/common/host-side/util/src/com/android/compatibility/common/util/ShellCommandUtil.java
diff --git a/common/host-side/util/src/com/android/compatibility/common/util/TestFilter.java b/harness/common/host-side/util/src/com/android/compatibility/common/util/TestFilter.java
similarity index 100%
rename from common/host-side/util/src/com/android/compatibility/common/util/TestFilter.java
rename to harness/common/host-side/util/src/com/android/compatibility/common/util/TestFilter.java
diff --git a/common/host-side/util/tests/Android.mk b/harness/common/host-side/util/tests/Android.mk
similarity index 100%
rename from common/host-side/util/tests/Android.mk
rename to harness/common/host-side/util/tests/Android.mk
diff --git a/common/host-side/util/tests/run_tests.sh b/harness/common/host-side/util/tests/run_tests.sh
similarity index 96%
rename from common/host-side/util/tests/run_tests.sh
rename to harness/common/host-side/util/tests/run_tests.sh
index d4513f9..57814f4 100755
--- a/common/host-side/util/tests/run_tests.sh
+++ b/harness/common/host-side/util/tests/run_tests.sh
@@ -16,7 +16,7 @@
 
 # Helper script for running unit tests for compatibility libraries
 
-CTS_DIR=$(dirname ${0})/../../../..
+CTS_DIR=$(dirname ${0})/../../../../..
 source ${CTS_DIR}/test_defs.sh
 
 JARS="
diff --git a/common/host-side/util/tests/src/com/android/compatibility/common/util/BusinessLogicHostExecutorTest.java b/harness/common/host-side/util/tests/src/com/android/compatibility/common/util/BusinessLogicHostExecutorTest.java
similarity index 100%
rename from common/host-side/util/tests/src/com/android/compatibility/common/util/BusinessLogicHostExecutorTest.java
rename to harness/common/host-side/util/tests/src/com/android/compatibility/common/util/BusinessLogicHostExecutorTest.java
diff --git a/common/host-side/util/tests/src/com/android/compatibility/common/util/DynamicConfigHandlerTest.java b/harness/common/host-side/util/tests/src/com/android/compatibility/common/util/DynamicConfigHandlerTest.java
similarity index 100%
rename from common/host-side/util/tests/src/com/android/compatibility/common/util/DynamicConfigHandlerTest.java
rename to harness/common/host-side/util/tests/src/com/android/compatibility/common/util/DynamicConfigHandlerTest.java
diff --git a/common/host-side/util/tests/src/com/android/compatibility/common/util/HostUnitTests.java b/harness/common/host-side/util/tests/src/com/android/compatibility/common/util/HostUnitTests.java
similarity index 100%
rename from common/host-side/util/tests/src/com/android/compatibility/common/util/HostUnitTests.java
rename to harness/common/host-side/util/tests/src/com/android/compatibility/common/util/HostUnitTests.java
diff --git a/common/host-side/util/tests/src/com/android/compatibility/common/util/ModuleResultTest.java b/harness/common/host-side/util/tests/src/com/android/compatibility/common/util/ModuleResultTest.java
similarity index 100%
rename from common/host-side/util/tests/src/com/android/compatibility/common/util/ModuleResultTest.java
rename to harness/common/host-side/util/tests/src/com/android/compatibility/common/util/ModuleResultTest.java
diff --git a/common/host-side/util/tests/src/com/android/compatibility/common/util/TestFilterTest.java b/harness/common/host-side/util/tests/src/com/android/compatibility/common/util/TestFilterTest.java
similarity index 100%
rename from common/host-side/util/tests/src/com/android/compatibility/common/util/TestFilterTest.java
rename to harness/common/host-side/util/tests/src/com/android/compatibility/common/util/TestFilterTest.java
diff --git a/common/util/.classpath b/harness/common/util/.classpath
similarity index 100%
rename from common/util/.classpath
rename to harness/common/util/.classpath
diff --git a/common/util/.project b/harness/common/util/.project
similarity index 100%
rename from common/util/.project
rename to harness/common/util/.project
diff --git a/common/util/Android.mk b/harness/common/util/Android.mk
similarity index 100%
rename from common/util/Android.mk
rename to harness/common/util/Android.mk
diff --git a/common/util/src/com/android/compatibility/common/util/AbiUtils.java b/harness/common/util/src/com/android/compatibility/common/util/AbiUtils.java
similarity index 100%
rename from common/util/src/com/android/compatibility/common/util/AbiUtils.java
rename to harness/common/util/src/com/android/compatibility/common/util/AbiUtils.java
diff --git a/common/util/src/com/android/compatibility/common/util/BusinessLogic.java b/harness/common/util/src/com/android/compatibility/common/util/BusinessLogic.java
similarity index 100%
rename from common/util/src/com/android/compatibility/common/util/BusinessLogic.java
rename to harness/common/util/src/com/android/compatibility/common/util/BusinessLogic.java
diff --git a/common/util/src/com/android/compatibility/common/util/BusinessLogicExecutor.java b/harness/common/util/src/com/android/compatibility/common/util/BusinessLogicExecutor.java
similarity index 100%
rename from common/util/src/com/android/compatibility/common/util/BusinessLogicExecutor.java
rename to harness/common/util/src/com/android/compatibility/common/util/BusinessLogicExecutor.java
diff --git a/common/util/src/com/android/compatibility/common/util/BusinessLogicFactory.java b/harness/common/util/src/com/android/compatibility/common/util/BusinessLogicFactory.java
similarity index 100%
rename from common/util/src/com/android/compatibility/common/util/BusinessLogicFactory.java
rename to harness/common/util/src/com/android/compatibility/common/util/BusinessLogicFactory.java
diff --git a/common/util/src/com/android/compatibility/common/util/CaseResult.java b/harness/common/util/src/com/android/compatibility/common/util/CaseResult.java
similarity index 100%
rename from common/util/src/com/android/compatibility/common/util/CaseResult.java
rename to harness/common/util/src/com/android/compatibility/common/util/CaseResult.java
diff --git a/common/util/src/com/android/compatibility/common/util/CddTest.java b/harness/common/util/src/com/android/compatibility/common/util/CddTest.java
similarity index 100%
rename from common/util/src/com/android/compatibility/common/util/CddTest.java
rename to harness/common/util/src/com/android/compatibility/common/util/CddTest.java
diff --git a/common/util/src/com/android/compatibility/common/util/ChecksumReporter.java b/harness/common/util/src/com/android/compatibility/common/util/ChecksumReporter.java
similarity index 100%
rename from common/util/src/com/android/compatibility/common/util/ChecksumReporter.java
rename to harness/common/util/src/com/android/compatibility/common/util/ChecksumReporter.java
diff --git a/common/util/src/com/android/compatibility/common/util/DevicePropertyInfo.java b/harness/common/util/src/com/android/compatibility/common/util/DevicePropertyInfo.java
similarity index 100%
rename from common/util/src/com/android/compatibility/common/util/DevicePropertyInfo.java
rename to harness/common/util/src/com/android/compatibility/common/util/DevicePropertyInfo.java
diff --git a/common/util/src/com/android/compatibility/common/util/DynamicConfig.java b/harness/common/util/src/com/android/compatibility/common/util/DynamicConfig.java
similarity index 100%
rename from common/util/src/com/android/compatibility/common/util/DynamicConfig.java
rename to harness/common/util/src/com/android/compatibility/common/util/DynamicConfig.java
diff --git a/common/util/src/com/android/compatibility/common/util/FileUtil.java b/harness/common/util/src/com/android/compatibility/common/util/FileUtil.java
similarity index 100%
rename from common/util/src/com/android/compatibility/common/util/FileUtil.java
rename to harness/common/util/src/com/android/compatibility/common/util/FileUtil.java
diff --git a/common/util/src/com/android/compatibility/common/util/ICaseResult.java b/harness/common/util/src/com/android/compatibility/common/util/ICaseResult.java
similarity index 100%
rename from common/util/src/com/android/compatibility/common/util/ICaseResult.java
rename to harness/common/util/src/com/android/compatibility/common/util/ICaseResult.java
diff --git a/common/util/src/com/android/compatibility/common/util/IInvocationResult.java b/harness/common/util/src/com/android/compatibility/common/util/IInvocationResult.java
similarity index 100%
rename from common/util/src/com/android/compatibility/common/util/IInvocationResult.java
rename to harness/common/util/src/com/android/compatibility/common/util/IInvocationResult.java
diff --git a/common/util/src/com/android/compatibility/common/util/IModuleResult.java b/harness/common/util/src/com/android/compatibility/common/util/IModuleResult.java
similarity index 100%
rename from common/util/src/com/android/compatibility/common/util/IModuleResult.java
rename to harness/common/util/src/com/android/compatibility/common/util/IModuleResult.java
diff --git a/common/util/src/com/android/compatibility/common/util/ITestResult.java b/harness/common/util/src/com/android/compatibility/common/util/ITestResult.java
similarity index 100%
rename from common/util/src/com/android/compatibility/common/util/ITestResult.java
rename to harness/common/util/src/com/android/compatibility/common/util/ITestResult.java
diff --git a/common/util/src/com/android/compatibility/common/util/InfoStore.java b/harness/common/util/src/com/android/compatibility/common/util/InfoStore.java
similarity index 100%
rename from common/util/src/com/android/compatibility/common/util/InfoStore.java
rename to harness/common/util/src/com/android/compatibility/common/util/InfoStore.java
diff --git a/common/util/src/com/android/compatibility/common/util/InvocationResult.java b/harness/common/util/src/com/android/compatibility/common/util/InvocationResult.java
similarity index 100%
rename from common/util/src/com/android/compatibility/common/util/InvocationResult.java
rename to harness/common/util/src/com/android/compatibility/common/util/InvocationResult.java
diff --git a/common/util/src/com/android/compatibility/common/util/KeyValueArgsParser.java b/harness/common/util/src/com/android/compatibility/common/util/KeyValueArgsParser.java
similarity index 100%
rename from common/util/src/com/android/compatibility/common/util/KeyValueArgsParser.java
rename to harness/common/util/src/com/android/compatibility/common/util/KeyValueArgsParser.java
diff --git a/common/util/src/com/android/compatibility/common/util/LightInvocationResult.java b/harness/common/util/src/com/android/compatibility/common/util/LightInvocationResult.java
similarity index 100%
rename from common/util/src/com/android/compatibility/common/util/LightInvocationResult.java
rename to harness/common/util/src/com/android/compatibility/common/util/LightInvocationResult.java
diff --git a/common/util/src/com/android/compatibility/common/util/LogcatInspector.java b/harness/common/util/src/com/android/compatibility/common/util/LogcatInspector.java
similarity index 100%
rename from common/util/src/com/android/compatibility/common/util/LogcatInspector.java
rename to harness/common/util/src/com/android/compatibility/common/util/LogcatInspector.java
diff --git a/common/util/src/com/android/compatibility/common/util/MeasureRun.java b/harness/common/util/src/com/android/compatibility/common/util/MeasureRun.java
similarity index 100%
rename from common/util/src/com/android/compatibility/common/util/MeasureRun.java
rename to harness/common/util/src/com/android/compatibility/common/util/MeasureRun.java
diff --git a/common/util/src/com/android/compatibility/common/util/MeasureTime.java b/harness/common/util/src/com/android/compatibility/common/util/MeasureTime.java
similarity index 100%
rename from common/util/src/com/android/compatibility/common/util/MeasureTime.java
rename to harness/common/util/src/com/android/compatibility/common/util/MeasureTime.java
diff --git a/common/util/src/com/android/compatibility/common/util/MetricsXmlSerializer.java b/harness/common/util/src/com/android/compatibility/common/util/MetricsXmlSerializer.java
similarity index 100%
rename from common/util/src/com/android/compatibility/common/util/MetricsXmlSerializer.java
rename to harness/common/util/src/com/android/compatibility/common/util/MetricsXmlSerializer.java
diff --git a/common/util/src/com/android/compatibility/common/util/ModuleResult.java b/harness/common/util/src/com/android/compatibility/common/util/ModuleResult.java
similarity index 100%
rename from common/util/src/com/android/compatibility/common/util/ModuleResult.java
rename to harness/common/util/src/com/android/compatibility/common/util/ModuleResult.java
diff --git a/common/util/src/com/android/compatibility/common/util/MultipartForm.java b/harness/common/util/src/com/android/compatibility/common/util/MultipartForm.java
similarity index 100%
rename from common/util/src/com/android/compatibility/common/util/MultipartForm.java
rename to harness/common/util/src/com/android/compatibility/common/util/MultipartForm.java
diff --git a/common/util/src/com/android/compatibility/common/util/ReadElf.java b/harness/common/util/src/com/android/compatibility/common/util/ReadElf.java
similarity index 100%
rename from common/util/src/com/android/compatibility/common/util/ReadElf.java
rename to harness/common/util/src/com/android/compatibility/common/util/ReadElf.java
diff --git a/common/util/src/com/android/compatibility/common/util/ReportLog.java b/harness/common/util/src/com/android/compatibility/common/util/ReportLog.java
similarity index 100%
rename from common/util/src/com/android/compatibility/common/util/ReportLog.java
rename to harness/common/util/src/com/android/compatibility/common/util/ReportLog.java
diff --git a/common/util/src/com/android/compatibility/common/util/ResultHandler.java b/harness/common/util/src/com/android/compatibility/common/util/ResultHandler.java
similarity index 100%
rename from common/util/src/com/android/compatibility/common/util/ResultHandler.java
rename to harness/common/util/src/com/android/compatibility/common/util/ResultHandler.java
diff --git a/common/util/src/com/android/compatibility/common/util/ResultType.java b/harness/common/util/src/com/android/compatibility/common/util/ResultType.java
similarity index 100%
rename from common/util/src/com/android/compatibility/common/util/ResultType.java
rename to harness/common/util/src/com/android/compatibility/common/util/ResultType.java
diff --git a/common/util/src/com/android/compatibility/common/util/ResultUnit.java b/harness/common/util/src/com/android/compatibility/common/util/ResultUnit.java
similarity index 100%
rename from common/util/src/com/android/compatibility/common/util/ResultUnit.java
rename to harness/common/util/src/com/android/compatibility/common/util/ResultUnit.java
diff --git a/common/util/src/com/android/compatibility/common/util/ResultUploader.java b/harness/common/util/src/com/android/compatibility/common/util/ResultUploader.java
similarity index 100%
rename from common/util/src/com/android/compatibility/common/util/ResultUploader.java
rename to harness/common/util/src/com/android/compatibility/common/util/ResultUploader.java
diff --git a/common/util/src/com/android/compatibility/common/util/RetryChecksumStatus.java b/harness/common/util/src/com/android/compatibility/common/util/RetryChecksumStatus.java
similarity index 100%
rename from common/util/src/com/android/compatibility/common/util/RetryChecksumStatus.java
rename to harness/common/util/src/com/android/compatibility/common/util/RetryChecksumStatus.java
diff --git a/common/util/src/com/android/compatibility/common/util/Stacktrace.java b/harness/common/util/src/com/android/compatibility/common/util/Stacktrace.java
similarity index 100%
rename from common/util/src/com/android/compatibility/common/util/Stacktrace.java
rename to harness/common/util/src/com/android/compatibility/common/util/Stacktrace.java
diff --git a/common/util/src/com/android/compatibility/common/util/Stat.java b/harness/common/util/src/com/android/compatibility/common/util/Stat.java
similarity index 100%
rename from common/util/src/com/android/compatibility/common/util/Stat.java
rename to harness/common/util/src/com/android/compatibility/common/util/Stat.java
diff --git a/common/util/src/com/android/compatibility/common/util/StreamUtil.java b/harness/common/util/src/com/android/compatibility/common/util/StreamUtil.java
similarity index 100%
rename from common/util/src/com/android/compatibility/common/util/StreamUtil.java
rename to harness/common/util/src/com/android/compatibility/common/util/StreamUtil.java
diff --git a/common/util/src/com/android/compatibility/common/util/TestResult.java b/harness/common/util/src/com/android/compatibility/common/util/TestResult.java
similarity index 100%
rename from common/util/src/com/android/compatibility/common/util/TestResult.java
rename to harness/common/util/src/com/android/compatibility/common/util/TestResult.java
diff --git a/common/util/src/com/android/compatibility/common/util/TestStatus.java b/harness/common/util/src/com/android/compatibility/common/util/TestStatus.java
similarity index 100%
rename from common/util/src/com/android/compatibility/common/util/TestStatus.java
rename to harness/common/util/src/com/android/compatibility/common/util/TestStatus.java
diff --git a/common/util/src/com/android/compatibility/common/util/VendorInterfaceTest.java b/harness/common/util/src/com/android/compatibility/common/util/VendorInterfaceTest.java
similarity index 100%
rename from common/util/src/com/android/compatibility/common/util/VendorInterfaceTest.java
rename to harness/common/util/src/com/android/compatibility/common/util/VendorInterfaceTest.java
diff --git a/common/util/src/com/android/compatibility/common/util/VersionCodes.java b/harness/common/util/src/com/android/compatibility/common/util/VersionCodes.java
similarity index 100%
rename from common/util/src/com/android/compatibility/common/util/VersionCodes.java
rename to harness/common/util/src/com/android/compatibility/common/util/VersionCodes.java
diff --git a/common/util/src/com/android/compatibility/common/util/ZipUtil.java b/harness/common/util/src/com/android/compatibility/common/util/ZipUtil.java
similarity index 100%
rename from common/util/src/com/android/compatibility/common/util/ZipUtil.java
rename to harness/common/util/src/com/android/compatibility/common/util/ZipUtil.java
diff --git a/common/util/tests/Android.mk b/harness/common/util/tests/Android.mk
similarity index 100%
rename from common/util/tests/Android.mk
rename to harness/common/util/tests/Android.mk
diff --git a/common/util/tests/run_tests.sh b/harness/common/util/tests/run_tests.sh
similarity index 96%
rename from common/util/tests/run_tests.sh
rename to harness/common/util/tests/run_tests.sh
index 0045014..4fb630a 100755
--- a/common/util/tests/run_tests.sh
+++ b/harness/common/util/tests/run_tests.sh
@@ -14,7 +14,7 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 
-CTS_DIR=$(dirname ${0})/../../..
+CTS_DIR=$(dirname ${0})/../../../..
 source ${CTS_DIR}/test_defs.sh
 
 JARS="
diff --git a/common/util/tests/src/com/android/compatibility/common/util/BusinessLogicTest.java b/harness/common/util/tests/src/com/android/compatibility/common/util/BusinessLogicTest.java
similarity index 100%
rename from common/util/tests/src/com/android/compatibility/common/util/BusinessLogicTest.java
rename to harness/common/util/tests/src/com/android/compatibility/common/util/BusinessLogicTest.java
diff --git a/common/util/tests/src/com/android/compatibility/common/util/CaseResultTest.java b/harness/common/util/tests/src/com/android/compatibility/common/util/CaseResultTest.java
similarity index 100%
rename from common/util/tests/src/com/android/compatibility/common/util/CaseResultTest.java
rename to harness/common/util/tests/src/com/android/compatibility/common/util/CaseResultTest.java
diff --git a/common/util/tests/src/com/android/compatibility/common/util/DynamicConfigTest.java b/harness/common/util/tests/src/com/android/compatibility/common/util/DynamicConfigTest.java
similarity index 100%
rename from common/util/tests/src/com/android/compatibility/common/util/DynamicConfigTest.java
rename to harness/common/util/tests/src/com/android/compatibility/common/util/DynamicConfigTest.java
diff --git a/common/util/tests/src/com/android/compatibility/common/util/LightInvocationResultTest.java b/harness/common/util/tests/src/com/android/compatibility/common/util/LightInvocationResultTest.java
similarity index 100%
rename from common/util/tests/src/com/android/compatibility/common/util/LightInvocationResultTest.java
rename to harness/common/util/tests/src/com/android/compatibility/common/util/LightInvocationResultTest.java
diff --git a/common/util/tests/src/com/android/compatibility/common/util/MetricsXmlSerializerTest.java b/harness/common/util/tests/src/com/android/compatibility/common/util/MetricsXmlSerializerTest.java
similarity index 100%
rename from common/util/tests/src/com/android/compatibility/common/util/MetricsXmlSerializerTest.java
rename to harness/common/util/tests/src/com/android/compatibility/common/util/MetricsXmlSerializerTest.java
diff --git a/common/util/tests/src/com/android/compatibility/common/util/MultipartFormTest.java b/harness/common/util/tests/src/com/android/compatibility/common/util/MultipartFormTest.java
similarity index 100%
rename from common/util/tests/src/com/android/compatibility/common/util/MultipartFormTest.java
rename to harness/common/util/tests/src/com/android/compatibility/common/util/MultipartFormTest.java
diff --git a/common/util/tests/src/com/android/compatibility/common/util/ReportLogTest.java b/harness/common/util/tests/src/com/android/compatibility/common/util/ReportLogTest.java
similarity index 100%
rename from common/util/tests/src/com/android/compatibility/common/util/ReportLogTest.java
rename to harness/common/util/tests/src/com/android/compatibility/common/util/ReportLogTest.java
diff --git a/common/util/tests/src/com/android/compatibility/common/util/ResultHandlerTest.java b/harness/common/util/tests/src/com/android/compatibility/common/util/ResultHandlerTest.java
similarity index 100%
rename from common/util/tests/src/com/android/compatibility/common/util/ResultHandlerTest.java
rename to harness/common/util/tests/src/com/android/compatibility/common/util/ResultHandlerTest.java
diff --git a/common/util/tests/src/com/android/compatibility/common/util/StatTest.java b/harness/common/util/tests/src/com/android/compatibility/common/util/StatTest.java
similarity index 100%
rename from common/util/tests/src/com/android/compatibility/common/util/StatTest.java
rename to harness/common/util/tests/src/com/android/compatibility/common/util/StatTest.java
diff --git a/common/util/tests/src/com/android/compatibility/common/util/TestResultTest.java b/harness/common/util/tests/src/com/android/compatibility/common/util/TestResultTest.java
similarity index 100%
rename from common/util/tests/src/com/android/compatibility/common/util/TestResultTest.java
rename to harness/common/util/tests/src/com/android/compatibility/common/util/TestResultTest.java
diff --git a/common/util/tests/src/com/android/compatibility/common/util/UnitTests.java b/harness/common/util/tests/src/com/android/compatibility/common/util/UnitTests.java
similarity index 100%
rename from common/util/tests/src/com/android/compatibility/common/util/UnitTests.java
rename to harness/common/util/tests/src/com/android/compatibility/common/util/UnitTests.java
diff --git a/harness/tools/Android.mk b/harness/tools/Android.mk
new file mode 100644
index 0000000..9af9f44
--- /dev/null
+++ b/harness/tools/Android.mk
@@ -0,0 +1,15 @@
+# Copyright (C) 2018 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+include $(call all-subdir-makefiles)
diff --git a/tools/cts-test-metrics/CtsCameraTestCases.reportlog.json b/harness/tools/cts-test-metrics/CtsCameraTestCases.reportlog.json
similarity index 100%
rename from tools/cts-test-metrics/CtsCameraTestCases.reportlog.json
rename to harness/tools/cts-test-metrics/CtsCameraTestCases.reportlog.json
diff --git a/tools/cts-test-metrics/CtsUiHostTestCases.reportlog.json b/harness/tools/cts-test-metrics/CtsUiHostTestCases.reportlog.json
similarity index 100%
rename from tools/cts-test-metrics/CtsUiHostTestCases.reportlog.json
rename to harness/tools/cts-test-metrics/CtsUiHostTestCases.reportlog.json
diff --git a/tools/cts-test-metrics/README b/harness/tools/cts-test-metrics/README
similarity index 100%
rename from tools/cts-test-metrics/README
rename to harness/tools/cts-test-metrics/README
diff --git a/tools/cts-test-metrics/parse_test_metrics.py b/harness/tools/cts-test-metrics/parse_test_metrics.py
similarity index 100%
rename from tools/cts-test-metrics/parse_test_metrics.py
rename to harness/tools/cts-test-metrics/parse_test_metrics.py
diff --git a/tools/cts-tradefed/Android.mk b/harness/tools/cts-tradefed/Android.mk
similarity index 97%
rename from tools/cts-tradefed/Android.mk
rename to harness/tools/cts-tradefed/Android.mk
index e6c4750..62fc414 100644
--- a/tools/cts-tradefed/Android.mk
+++ b/harness/tools/cts-tradefed/Android.mk
@@ -30,7 +30,7 @@
 LOCAL_SUITE_TARGET_ARCH := $(TARGET_ARCH)
 LOCAL_SUITE_NAME := CTS
 LOCAL_SUITE_FULLNAME := "Compatibility Test Suite"
-LOCAL_SUITE_VERSION := 8.1_r1
+LOCAL_SUITE_VERSION := 9.0_r1
 LOCAL_STATIC_JAVA_LIBRARIES += cts-tradefed-harness
 
 LOCAL_MODULE := cts-tradefed
diff --git a/tools/cts-tradefed/DynamicConfig.xml b/harness/tools/cts-tradefed/DynamicConfig.xml
similarity index 100%
rename from tools/cts-tradefed/DynamicConfig.xml
rename to harness/tools/cts-tradefed/DynamicConfig.xml
diff --git a/tools/cts-tradefed/README b/harness/tools/cts-tradefed/README
similarity index 100%
rename from tools/cts-tradefed/README
rename to harness/tools/cts-tradefed/README
diff --git a/tools/cts-tradefed/etc/Android.mk b/harness/tools/cts-tradefed/etc/Android.mk
similarity index 100%
rename from tools/cts-tradefed/etc/Android.mk
rename to harness/tools/cts-tradefed/etc/Android.mk
diff --git a/tools/cts-tradefed/etc/cts-tradefed b/harness/tools/cts-tradefed/etc/cts-tradefed
similarity index 100%
rename from tools/cts-tradefed/etc/cts-tradefed
rename to harness/tools/cts-tradefed/etc/cts-tradefed
diff --git a/tools/cts-tradefed/res/config/basic-reporters.xml b/harness/tools/cts-tradefed/res/config/basic-reporters.xml
similarity index 100%
rename from tools/cts-tradefed/res/config/basic-reporters.xml
rename to harness/tools/cts-tradefed/res/config/basic-reporters.xml
diff --git a/tools/cts-tradefed/res/config/collect-tests-only.xml b/harness/tools/cts-tradefed/res/config/collect-tests-only.xml
similarity index 100%
rename from tools/cts-tradefed/res/config/collect-tests-only.xml
rename to harness/tools/cts-tradefed/res/config/collect-tests-only.xml
diff --git a/tools/cts-tradefed/res/config/cts-automated.xml b/harness/tools/cts-tradefed/res/config/cts-automated.xml
similarity index 100%
rename from tools/cts-tradefed/res/config/cts-automated.xml
rename to harness/tools/cts-tradefed/res/config/cts-automated.xml
diff --git a/tools/cts-tradefed/res/config/cts-camera.xml b/harness/tools/cts-tradefed/res/config/cts-camera.xml
similarity index 100%
rename from tools/cts-tradefed/res/config/cts-camera.xml
rename to harness/tools/cts-tradefed/res/config/cts-camera.xml
diff --git a/tools/cts-tradefed/res/config/cts-common.xml b/harness/tools/cts-tradefed/res/config/cts-common.xml
similarity index 100%
rename from tools/cts-tradefed/res/config/cts-common.xml
rename to harness/tools/cts-tradefed/res/config/cts-common.xml
diff --git a/tools/cts-tradefed/res/config/cts-dev.xml b/harness/tools/cts-tradefed/res/config/cts-dev.xml
similarity index 100%
rename from tools/cts-tradefed/res/config/cts-dev.xml
rename to harness/tools/cts-tradefed/res/config/cts-dev.xml
diff --git a/tools/cts-tradefed/res/config/cts-device-files.xml b/harness/tools/cts-tradefed/res/config/cts-device-files.xml
similarity index 100%
rename from tools/cts-tradefed/res/config/cts-device-files.xml
rename to harness/tools/cts-tradefed/res/config/cts-device-files.xml
diff --git a/tools/cts-tradefed/res/config/cts-exclude.xml b/harness/tools/cts-tradefed/res/config/cts-exclude.xml
similarity index 100%
rename from tools/cts-tradefed/res/config/cts-exclude.xml
rename to harness/tools/cts-tradefed/res/config/cts-exclude.xml
diff --git a/tools/cts-tradefed/res/config/cts-filtered-sample.xml b/harness/tools/cts-tradefed/res/config/cts-filtered-sample.xml
similarity index 100%
rename from tools/cts-tradefed/res/config/cts-filtered-sample.xml
rename to harness/tools/cts-tradefed/res/config/cts-filtered-sample.xml
diff --git a/tools/cts-tradefed/res/config/cts-global-presubmit.xml b/harness/tools/cts-tradefed/res/config/cts-global-presubmit.xml
similarity index 100%
rename from tools/cts-tradefed/res/config/cts-global-presubmit.xml
rename to harness/tools/cts-tradefed/res/config/cts-global-presubmit.xml
diff --git a/harness/tools/cts-tradefed/res/config/cts-instant-dev.xml b/harness/tools/cts-tradefed/res/config/cts-instant-dev.xml
new file mode 100644
index 0000000..f279ded
--- /dev/null
+++ b/harness/tools/cts-tradefed/res/config/cts-instant-dev.xml
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2018 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+<configuration description="Runs CTS-instant development from a pre-existing CTS installation">
+
+    <include name="cts-instant" />
+
+    <!-- Disable checks for development -->
+    <option name="log-level" value="verbose" />
+    <option name="skip-preconditions" value="true" />
+    <option name="skip-device-info" value="true" />
+    <option name="result-reporter:compress-logs" value="false" />
+    <option name="compatibility:skip-all-system-status-check" value="true" />
+
+</configuration>
diff --git a/harness/tools/cts-tradefed/res/config/cts-instant.xml b/harness/tools/cts-tradefed/res/config/cts-instant.xml
new file mode 100644
index 0000000..e728359
--- /dev/null
+++ b/harness/tools/cts-tradefed/res/config/cts-instant.xml
@@ -0,0 +1,128 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2018 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+<configuration description="Runs CTS-instant from a pre-existing CTS installation">
+
+    <include name="cts" />
+
+    <!-- This plan is only for instant app specific tests. -->
+    <option name="plan" value="cts-instant" />
+
+    <!-- Test instant apps only for the primary API -->
+    <option name="compatibility:primary-abi-only" value="true" />
+
+    <!-- Exclude tests applicable only to full mode -->
+    <option name="compatibility:test-arg" value="com.android.tradefed.testtype.AndroidJUnitTest:exclude-annotation:android.platform.test.annotations.AppModeFull" />
+
+    <!-- CtsAccessibilityTestCases -->
+    <option name="compatibility:module-arg" value="CtsAccessibilityTestCases:install-arg:--instant" />
+    <option name="compatibility:include-filter" value="CtsAccessibilityTestCases" />
+
+    <!-- CtsAccessibilityServiceTestCases -->
+    <option name="compatibility:module-arg" value="CtsAccessibilityServiceTestCases:install-arg:--instant" />
+    <option name="compatibility:include-filter" value="CtsAccessibilityServiceTestCases" />
+
+    <!-- CtsAnimationTestCases -->
+    <option name="compatibility:module-arg" value="CtsAnimationTestCases:install-arg:--instant" />
+    <option name="compatibility:include-filter" value="CtsAnimationTestCases" />
+
+    <!-- CtsAutoFillServiceTestCases  -->
+    <option name="compatibility:module-arg" value="CtsAutoFillServiceTestCases:install-arg:--instant" />
+    <option name="compatibility:include-filter" value="CtsAutoFillServiceTestCases" />
+
+    <!-- CtsPdfTestCases -->
+    <option name="compatibility:module-arg" value="CtsPdfTestCases:install-arg:--instant" />
+    <option name="compatibility:include-filter" value="CtsPdfTestCases" />
+
+    <!-- CtsViewTestCases -->
+    <option name="compatibility:module-arg" value="CtsViewTestCases:install-arg:--instant" />
+    <option name="compatibility:include-filter" value="CtsViewTestCases" />
+
+    <!-- CtsFragmentTestCases, CtsFragmentTestCasesSdk26 -->
+    <option name="compatibility:module-arg" value="CtsFragmentTestCases:install-arg:--instant" />
+    <option name="compatibility:include-filter" value="CtsFragmentTestCases" />
+    <option name="compatibility:module-arg" value="CtsFragmentTestCasesSdk26:install-arg:--instant" />
+    <option name="compatibility:include-filter" value="CtsFragmentTestCasesSdk26" />
+
+    <!-- CtsColorModeTestCases -->
+    <option name="compatibility:module-arg" value="CtsColorModeTestCases:install-arg:--instant" />
+    <option name="compatibility:include-filter" value="CtsColorModeTestCases" />
+
+    <!-- CtsBluetoothTestCases -->
+    <!-- Instant apps cannot hold android.permission.BLUETOOTH which makes BT tests irrelevant-->
+
+    <!-- CtsDatabaseTestCases -->
+    <option name="compatibility:module-arg" value="CtsDatabaseTestCases:install-arg:--instant" />
+    <option name="compatibility:include-filter" value="CtsDatabaseTestCases" />
+
+    <!-- CtsDisplayTestCases -->
+    <option name="compatibility:module-arg" value="CtsDisplayTestCases:install-arg:--instant" />
+    <option name="compatibility:include-filter" value="CtsDisplayTestCases" />
+
+    <!-- CtsDreamsTestCases -->
+    <option name="compatibility:module-arg" value="CtsDreamsTestCases:install-arg:--instant" />
+    <option name="compatibility:include-filter" value="CtsDreamsTestCases" />
+
+    <!-- CtsDumpsysHostTestCases -->
+    <!-- This module tests system service dumps, which is irrelevant for Instant Apps. -->
+
+    <!-- CtsGestureTestCases -->
+    <option name="compatibility:module-arg" value="CtsGestureTestCases:install-arg:--instant" />
+    <option name="compatibility:include-filter" value="CtsGestureTestCases" />
+
+    <!-- CtsMultiUserTestCases -->
+    <option name="compatibility:module-arg" value="CtsMultiUserTestCases:install-arg:--instant" />
+    <option name="compatibility:include-filter" value="CtsMultiUserTestCases" />
+
+    <!-- CtsPreference2TestCases -->
+    <option name="compatibility:module-arg" value="CtsPreference2TestCases:install-arg:--instant" />
+    <option name="compatibility:include-filter" value="CtsPreference2TestCases" />
+
+    <!-- CtsPreferenceTestCases -->
+    <option name="compatibility:module-arg" value="CtsPreferenceTestCases:install-arg:--instant" />
+    <option name="compatibility:include-filter" value="CtsPreferenceTestCases" />
+
+    <!-- CtsSampleDeviceTestCases -->
+    <option name="compatibility:module-arg" value="CtsSampleDeviceTestCases:install-arg:--instant" />
+    <option name="compatibility:include-filter" value="CtsSampleDeviceTestCases" />
+
+    <!-- CtsToastTestCases -->
+    <option name="compatibility:module-arg" value="CtsToastTestCases:install-arg:--instant" />
+    <option name="compatibility:include-filter" value="CtsToastTestCases" />
+
+    <!-- CtsUiDeviceTestCases -->
+    <option name="compatibility:module-arg" value="CtsUiDeviceTestCases:install-arg:--instant" />
+    <option name="compatibility:include-filter" value="CtsUiDeviceTestCases" />
+
+    <!-- CtsDpiTestCases -->
+    <option name="compatibility:module-arg" value="CtsDpiTestCases:install-arg:--instant" />
+    <option name="compatibility:include-filter" value="CtsDpiTestCases" />
+
+    <!-- CtsDpiTestCases2 -->
+    <!-- These target Cupcake not applicable to instant apps which target Oreo+ -->
+
+    <!-- CtsFileSystemTestCases -->
+    <option name="compatibility:module-arg" value="CtsFileSystemTestCases:install-arg:--instant" />
+    <option name="compatibility:include-filter" value="CtsFileSystemTestCases" />
+
+    <!-- CtsTextTestCases -->
+    <option name="compatibility:module-arg" value="CtsTextTestCases:install-arg:--instant" />
+    <option name="compatibility:include-filter" value="CtsTextTestCases" />
+
+    <!-- CtsWidgetTestCases -->
+    <option name="compatibility:module-arg" value="CtsWidgetTestCases:install-arg:--instant" />
+    <option name="compatibility:include-filter" value="CtsWidgetTestCases" />
+
+</configuration>
diff --git a/tools/cts-tradefed/res/config/cts-java.xml b/harness/tools/cts-tradefed/res/config/cts-java.xml
similarity index 100%
rename from tools/cts-tradefed/res/config/cts-java.xml
rename to harness/tools/cts-tradefed/res/config/cts-java.xml
diff --git a/tools/cts-tradefed/res/config/cts-jvmti.xml b/harness/tools/cts-tradefed/res/config/cts-jvmti.xml
similarity index 100%
rename from tools/cts-tradefed/res/config/cts-jvmti.xml
rename to harness/tools/cts-tradefed/res/config/cts-jvmti.xml
diff --git a/tools/cts-tradefed/res/config/cts-known-failures.xml b/harness/tools/cts-tradefed/res/config/cts-known-failures.xml
similarity index 100%
rename from tools/cts-tradefed/res/config/cts-known-failures.xml
rename to harness/tools/cts-tradefed/res/config/cts-known-failures.xml
diff --git a/tools/cts-tradefed/res/config/cts-preconditions.xml b/harness/tools/cts-tradefed/res/config/cts-preconditions.xml
similarity index 96%
rename from tools/cts-tradefed/res/config/cts-preconditions.xml
rename to harness/tools/cts-tradefed/res/config/cts-preconditions.xml
index 0f0f9b7..e3f517c 100644
--- a/tools/cts-tradefed/res/config/cts-preconditions.xml
+++ b/harness/tools/cts-tradefed/res/config/cts-preconditions.xml
@@ -63,7 +63,7 @@
     </target_preparer>
 
     <!-- The following values are used in cts/common/device-side/util/DeviceReportLog.java,
-    cts/common/host-side/util/MetricsReportLog.java and tools/tradefed-host/util/ReportLogUtil.java.
+    cts/harness/common/host-side/util/MetricsReportLog.java and tools/tradefed-host/util/ReportLogUtil.java.
     Any change in these values must also be translated to the stated files.
     -->
     <target_preparer class="com.android.compatibility.common.tradefed.targetprep.ReportLogCollector">
diff --git a/tools/cts-tradefed/res/config/cts-presubmit.xml b/harness/tools/cts-tradefed/res/config/cts-presubmit.xml
similarity index 100%
rename from tools/cts-tradefed/res/config/cts-presubmit.xml
rename to harness/tools/cts-tradefed/res/config/cts-presubmit.xml
diff --git a/tools/cts-tradefed/res/config/cts-suite-automated.xml b/harness/tools/cts-tradefed/res/config/cts-suite-automated.xml
similarity index 100%
rename from tools/cts-tradefed/res/config/cts-suite-automated.xml
rename to harness/tools/cts-tradefed/res/config/cts-suite-automated.xml
diff --git a/tools/cts-tradefed/res/config/cts-suite-virtual-device.xml b/harness/tools/cts-tradefed/res/config/cts-suite-virtual-device.xml
similarity index 100%
rename from tools/cts-tradefed/res/config/cts-suite-virtual-device.xml
rename to harness/tools/cts-tradefed/res/config/cts-suite-virtual-device.xml
diff --git a/tools/cts-tradefed/res/config/cts-suite.xml b/harness/tools/cts-tradefed/res/config/cts-suite.xml
similarity index 100%
rename from tools/cts-tradefed/res/config/cts-suite.xml
rename to harness/tools/cts-tradefed/res/config/cts-suite.xml
diff --git a/tools/cts-tradefed/res/config/cts-system-checkers.xml b/harness/tools/cts-tradefed/res/config/cts-system-checkers.xml
similarity index 100%
rename from tools/cts-tradefed/res/config/cts-system-checkers.xml
rename to harness/tools/cts-tradefed/res/config/cts-system-checkers.xml
diff --git a/tools/cts-tradefed/res/config/cts-virtual-device.xml b/harness/tools/cts-tradefed/res/config/cts-virtual-device.xml
similarity index 100%
rename from tools/cts-tradefed/res/config/cts-virtual-device.xml
rename to harness/tools/cts-tradefed/res/config/cts-virtual-device.xml
diff --git a/tools/cts-tradefed/res/config/cts.xml b/harness/tools/cts-tradefed/res/config/cts.xml
similarity index 100%
rename from tools/cts-tradefed/res/config/cts.xml
rename to harness/tools/cts-tradefed/res/config/cts.xml
diff --git a/tools/cts-tradefed/res/config/retry.xml b/harness/tools/cts-tradefed/res/config/retry.xml
similarity index 100%
rename from tools/cts-tradefed/res/config/retry.xml
rename to harness/tools/cts-tradefed/res/config/retry.xml
diff --git a/tools/cts-tradefed/res/config/security-bulletin.xml b/harness/tools/cts-tradefed/res/config/security-bulletin.xml
similarity index 100%
rename from tools/cts-tradefed/res/config/security-bulletin.xml
rename to harness/tools/cts-tradefed/res/config/security-bulletin.xml
diff --git a/tools/cts-tradefed/tests/Android.mk b/harness/tools/cts-tradefed/tests/Android.mk
similarity index 100%
rename from tools/cts-tradefed/tests/Android.mk
rename to harness/tools/cts-tradefed/tests/Android.mk
diff --git a/tools/cts-tradefed/tests/run_tests.sh b/harness/tools/cts-tradefed/tests/run_tests.sh
similarity index 88%
rename from tools/cts-tradefed/tests/run_tests.sh
rename to harness/tools/cts-tradefed/tests/run_tests.sh
index 64f4bb6..4bbf173 100755
--- a/tools/cts-tradefed/tests/run_tests.sh
+++ b/harness/tools/cts-tradefed/tests/run_tests.sh
@@ -16,7 +16,9 @@
 
 # Helper script for running unit tests for compatibility libraries
 
-CTS_DIR=$(dirname ${0})/../../..
+# TODO: Change it to the new harness repo once harness code is moved
+# to a new repo.
+CTS_DIR=$(dirname ${0})/../../../..
 source ${CTS_DIR}/test_defs.sh
 
 JARS="
diff --git a/tools/cts-tradefed/tests/src/com/android/compatibility/tradefed/CtsTradefedTest.java b/harness/tools/cts-tradefed/tests/src/com/android/compatibility/tradefed/CtsTradefedTest.java
similarity index 100%
rename from tools/cts-tradefed/tests/src/com/android/compatibility/tradefed/CtsTradefedTest.java
rename to harness/tools/cts-tradefed/tests/src/com/android/compatibility/tradefed/CtsTradefedTest.java
diff --git a/tools/dex-tools/Android.mk b/harness/tools/dex-tools/Android.mk
similarity index 100%
rename from tools/dex-tools/Android.mk
rename to harness/tools/dex-tools/Android.mk
diff --git a/tools/dex-tools/README.txt b/harness/tools/dex-tools/README.txt
similarity index 100%
rename from tools/dex-tools/README.txt
rename to harness/tools/dex-tools/README.txt
diff --git a/tools/dex-tools/TODO.txt b/harness/tools/dex-tools/TODO.txt
similarity index 100%
rename from tools/dex-tools/TODO.txt
rename to harness/tools/dex-tools/TODO.txt
diff --git a/tools/dex-tools/dex/classes.dex b/harness/tools/dex-tools/dex/classes.dex
similarity index 100%
rename from tools/dex-tools/dex/classes.dex
rename to harness/tools/dex-tools/dex/classes.dex
Binary files differ
diff --git a/tools/dex-tools/dex/classes.out.dex b/harness/tools/dex-tools/dex/classes.out.dex
similarity index 100%
rename from tools/dex-tools/dex/classes.out.dex
rename to harness/tools/dex-tools/dex/classes.out.dex
diff --git a/tools/dex-tools/dex/classes0.dex b/harness/tools/dex-tools/dex/classes0.dex
similarity index 100%
rename from tools/dex-tools/dex/classes0.dex
rename to harness/tools/dex-tools/dex/classes0.dex
Binary files differ
diff --git a/tools/dex-tools/dex/classes0.out.dex b/harness/tools/dex-tools/dex/classes0.out.dex
similarity index 100%
rename from tools/dex-tools/dex/classes0.out.dex
rename to harness/tools/dex-tools/dex/classes0.out.dex
diff --git a/tools/dex-tools/src/dex/reader/DexAnnotationAttributeImpl.java b/harness/tools/dex-tools/src/dex/reader/DexAnnotationAttributeImpl.java
similarity index 100%
rename from tools/dex-tools/src/dex/reader/DexAnnotationAttributeImpl.java
rename to harness/tools/dex-tools/src/dex/reader/DexAnnotationAttributeImpl.java
diff --git a/tools/dex-tools/src/dex/reader/DexAnnotationImpl.java b/harness/tools/dex-tools/src/dex/reader/DexAnnotationImpl.java
similarity index 100%
rename from tools/dex-tools/src/dex/reader/DexAnnotationImpl.java
rename to harness/tools/dex-tools/src/dex/reader/DexAnnotationImpl.java
diff --git a/tools/dex-tools/src/dex/reader/DexBuffer.java b/harness/tools/dex-tools/src/dex/reader/DexBuffer.java
similarity index 100%
rename from tools/dex-tools/src/dex/reader/DexBuffer.java
rename to harness/tools/dex-tools/src/dex/reader/DexBuffer.java
diff --git a/tools/dex-tools/src/dex/reader/DexClassImpl.java b/harness/tools/dex-tools/src/dex/reader/DexClassImpl.java
similarity index 100%
rename from tools/dex-tools/src/dex/reader/DexClassImpl.java
rename to harness/tools/dex-tools/src/dex/reader/DexClassImpl.java
diff --git a/tools/dex-tools/src/dex/reader/DexEncodedAnnotationImpl.java b/harness/tools/dex-tools/src/dex/reader/DexEncodedAnnotationImpl.java
similarity index 100%
rename from tools/dex-tools/src/dex/reader/DexEncodedAnnotationImpl.java
rename to harness/tools/dex-tools/src/dex/reader/DexEncodedAnnotationImpl.java
diff --git a/tools/dex-tools/src/dex/reader/DexEncodedValueImpl.java b/harness/tools/dex-tools/src/dex/reader/DexEncodedValueImpl.java
similarity index 100%
rename from tools/dex-tools/src/dex/reader/DexEncodedValueImpl.java
rename to harness/tools/dex-tools/src/dex/reader/DexEncodedValueImpl.java
diff --git a/tools/dex-tools/src/dex/reader/DexFieldImpl.java b/harness/tools/dex-tools/src/dex/reader/DexFieldImpl.java
similarity index 100%
rename from tools/dex-tools/src/dex/reader/DexFieldImpl.java
rename to harness/tools/dex-tools/src/dex/reader/DexFieldImpl.java
diff --git a/tools/dex-tools/src/dex/reader/DexFileImpl.java b/harness/tools/dex-tools/src/dex/reader/DexFileImpl.java
similarity index 100%
rename from tools/dex-tools/src/dex/reader/DexFileImpl.java
rename to harness/tools/dex-tools/src/dex/reader/DexFileImpl.java
diff --git a/tools/dex-tools/src/dex/reader/DexFileReader.java b/harness/tools/dex-tools/src/dex/reader/DexFileReader.java
similarity index 100%
rename from tools/dex-tools/src/dex/reader/DexFileReader.java
rename to harness/tools/dex-tools/src/dex/reader/DexFileReader.java
diff --git a/tools/dex-tools/src/dex/reader/DexMethodImpl.java b/harness/tools/dex-tools/src/dex/reader/DexMethodImpl.java
similarity index 100%
rename from tools/dex-tools/src/dex/reader/DexMethodImpl.java
rename to harness/tools/dex-tools/src/dex/reader/DexMethodImpl.java
diff --git a/tools/dex-tools/src/dex/reader/DexParameterImpl.java b/harness/tools/dex-tools/src/dex/reader/DexParameterImpl.java
similarity index 100%
rename from tools/dex-tools/src/dex/reader/DexParameterImpl.java
rename to harness/tools/dex-tools/src/dex/reader/DexParameterImpl.java
diff --git a/tools/dex-tools/src/dex/reader/TypeFormatter.java b/harness/tools/dex-tools/src/dex/reader/TypeFormatter.java
similarity index 100%
rename from tools/dex-tools/src/dex/reader/TypeFormatter.java
rename to harness/tools/dex-tools/src/dex/reader/TypeFormatter.java
diff --git a/tools/dex-tools/src/dex/structure/DexAnnotatedElement.java b/harness/tools/dex-tools/src/dex/structure/DexAnnotatedElement.java
similarity index 100%
rename from tools/dex-tools/src/dex/structure/DexAnnotatedElement.java
rename to harness/tools/dex-tools/src/dex/structure/DexAnnotatedElement.java
diff --git a/tools/dex-tools/src/dex/structure/DexAnnotation.java b/harness/tools/dex-tools/src/dex/structure/DexAnnotation.java
similarity index 100%
rename from tools/dex-tools/src/dex/structure/DexAnnotation.java
rename to harness/tools/dex-tools/src/dex/structure/DexAnnotation.java
diff --git a/tools/dex-tools/src/dex/structure/DexAnnotationAttribute.java b/harness/tools/dex-tools/src/dex/structure/DexAnnotationAttribute.java
similarity index 100%
rename from tools/dex-tools/src/dex/structure/DexAnnotationAttribute.java
rename to harness/tools/dex-tools/src/dex/structure/DexAnnotationAttribute.java
diff --git a/tools/dex-tools/src/dex/structure/DexClass.java b/harness/tools/dex-tools/src/dex/structure/DexClass.java
similarity index 100%
rename from tools/dex-tools/src/dex/structure/DexClass.java
rename to harness/tools/dex-tools/src/dex/structure/DexClass.java
diff --git a/tools/dex-tools/src/dex/structure/DexEncodedAnnotation.java b/harness/tools/dex-tools/src/dex/structure/DexEncodedAnnotation.java
similarity index 100%
rename from tools/dex-tools/src/dex/structure/DexEncodedAnnotation.java
rename to harness/tools/dex-tools/src/dex/structure/DexEncodedAnnotation.java
diff --git a/tools/dex-tools/src/dex/structure/DexEncodedValue.java b/harness/tools/dex-tools/src/dex/structure/DexEncodedValue.java
similarity index 100%
rename from tools/dex-tools/src/dex/structure/DexEncodedValue.java
rename to harness/tools/dex-tools/src/dex/structure/DexEncodedValue.java
diff --git a/tools/dex-tools/src/dex/structure/DexEncodedValueType.java b/harness/tools/dex-tools/src/dex/structure/DexEncodedValueType.java
similarity index 100%
rename from tools/dex-tools/src/dex/structure/DexEncodedValueType.java
rename to harness/tools/dex-tools/src/dex/structure/DexEncodedValueType.java
diff --git a/tools/dex-tools/src/dex/structure/DexField.java b/harness/tools/dex-tools/src/dex/structure/DexField.java
similarity index 100%
rename from tools/dex-tools/src/dex/structure/DexField.java
rename to harness/tools/dex-tools/src/dex/structure/DexField.java
diff --git a/tools/dex-tools/src/dex/structure/DexFile.java b/harness/tools/dex-tools/src/dex/structure/DexFile.java
similarity index 100%
rename from tools/dex-tools/src/dex/structure/DexFile.java
rename to harness/tools/dex-tools/src/dex/structure/DexFile.java
diff --git a/tools/dex-tools/src/dex/structure/DexInterface.java b/harness/tools/dex-tools/src/dex/structure/DexInterface.java
similarity index 100%
rename from tools/dex-tools/src/dex/structure/DexInterface.java
rename to harness/tools/dex-tools/src/dex/structure/DexInterface.java
diff --git a/tools/dex-tools/src/dex/structure/DexMethod.java b/harness/tools/dex-tools/src/dex/structure/DexMethod.java
similarity index 100%
rename from tools/dex-tools/src/dex/structure/DexMethod.java
rename to harness/tools/dex-tools/src/dex/structure/DexMethod.java
diff --git a/tools/dex-tools/src/dex/structure/DexParameter.java b/harness/tools/dex-tools/src/dex/structure/DexParameter.java
similarity index 100%
rename from tools/dex-tools/src/dex/structure/DexParameter.java
rename to harness/tools/dex-tools/src/dex/structure/DexParameter.java
diff --git a/tools/dex-tools/src/dex/structure/NamedElement.java b/harness/tools/dex-tools/src/dex/structure/NamedElement.java
similarity index 100%
rename from tools/dex-tools/src/dex/structure/NamedElement.java
rename to harness/tools/dex-tools/src/dex/structure/NamedElement.java
diff --git a/tools/dex-tools/src/dex/structure/WithModifiers.java b/harness/tools/dex-tools/src/dex/structure/WithModifiers.java
similarity index 100%
rename from tools/dex-tools/src/dex/structure/WithModifiers.java
rename to harness/tools/dex-tools/src/dex/structure/WithModifiers.java
diff --git a/tools/dex-tools/test/dex/reader/DexFileReaderTests.java b/harness/tools/dex-tools/test/dex/reader/DexFileReaderTests.java
similarity index 100%
rename from tools/dex-tools/test/dex/reader/DexFileReaderTests.java
rename to harness/tools/dex-tools/test/dex/reader/DexFileReaderTests.java
diff --git a/tools/dex-tools/test/dex/reader/DexTestsCommon.java b/harness/tools/dex-tools/test/dex/reader/DexTestsCommon.java
similarity index 100%
rename from tools/dex-tools/test/dex/reader/DexTestsCommon.java
rename to harness/tools/dex-tools/test/dex/reader/DexTestsCommon.java
diff --git a/tools/dex-tools/test/dex/reader/LargeDexTests.java b/harness/tools/dex-tools/test/dex/reader/LargeDexTests.java
similarity index 100%
rename from tools/dex-tools/test/dex/reader/LargeDexTests.java
rename to harness/tools/dex-tools/test/dex/reader/LargeDexTests.java
diff --git a/tools/dex-tools/test/dex/reader/util/JavaSource.java b/harness/tools/dex-tools/test/dex/reader/util/JavaSource.java
similarity index 100%
rename from tools/dex-tools/test/dex/reader/util/JavaSource.java
rename to harness/tools/dex-tools/test/dex/reader/util/JavaSource.java
diff --git a/tools/dex-tools/test/dex/reader/util/JavaSourceToDexUtil.java b/harness/tools/dex-tools/test/dex/reader/util/JavaSourceToDexUtil.java
similarity index 100%
rename from tools/dex-tools/test/dex/reader/util/JavaSourceToDexUtil.java
rename to harness/tools/dex-tools/test/dex/reader/util/JavaSourceToDexUtil.java
diff --git a/tools/dex-tools/test/dex/reader/util/MemoryByteCode.java b/harness/tools/dex-tools/test/dex/reader/util/MemoryByteCode.java
similarity index 100%
rename from tools/dex-tools/test/dex/reader/util/MemoryByteCode.java
rename to harness/tools/dex-tools/test/dex/reader/util/MemoryByteCode.java
diff --git a/tools/dex-tools/test/dex/reader/util/SpecialJavaFileManager.java b/harness/tools/dex-tools/test/dex/reader/util/SpecialJavaFileManager.java
similarity index 100%
rename from tools/dex-tools/test/dex/reader/util/SpecialJavaFileManager.java
rename to harness/tools/dex-tools/test/dex/reader/util/SpecialJavaFileManager.java
diff --git a/hostsidetests/appsecurity/test-apps/EphemeralTestApp/EphemeralApp1/src/com/android/cts/ephemeralapp1/ClientTest.java b/hostsidetests/appsecurity/test-apps/EphemeralTestApp/EphemeralApp1/src/com/android/cts/ephemeralapp1/ClientTest.java
index 8a0cb52..c674426 100644
--- a/hostsidetests/appsecurity/test-apps/EphemeralTestApp/EphemeralApp1/src/com/android/cts/ephemeralapp1/ClientTest.java
+++ b/hostsidetests/appsecurity/test-apps/EphemeralTestApp/EphemeralApp1/src/com/android/cts/ephemeralapp1/ClientTest.java
@@ -1234,6 +1234,9 @@
     public void testGetSearchableInfo() throws Throwable {
         final SearchManager searchManager = (SearchManager) InstrumentationRegistry.getContext()
                 .getSystemService(Context.SEARCH_SERVICE);
+        if (searchManager == null) {
+            return;
+        }
         // get searchable info for a component in ourself; pass
         {
             final SearchableInfo info = searchManager.getSearchableInfo(
diff --git a/hostsidetests/appsecurity/test-apps/EphemeralTestApp/NormalApp/src/com/android/cts/normalapp/ClientTest.java b/hostsidetests/appsecurity/test-apps/EphemeralTestApp/NormalApp/src/com/android/cts/normalapp/ClientTest.java
index 60ba5ad..2265dec 100644
--- a/hostsidetests/appsecurity/test-apps/EphemeralTestApp/NormalApp/src/com/android/cts/normalapp/ClientTest.java
+++ b/hostsidetests/appsecurity/test-apps/EphemeralTestApp/NormalApp/src/com/android/cts/normalapp/ClientTest.java
@@ -419,21 +419,6 @@
         } catch (ActivityNotFoundException expected) {
         }
 
-
-        // start the ephemeral activity; directed component, includes EXTERNAL flag
-        try {
-            final Intent startEphemeralIntent = new Intent(ACTION_START_EPHEMERAL_ACTIVITY)
-                    .setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_MATCH_EXTERNAL);
-            startEphemeralIntent.setComponent(
-                    new ComponentName("com.android.cts.ephemeralapp1",
-                            "com.android.cts.ephemeralapp1.EphemeralActivity"));
-            InstrumentationRegistry.getContext().startActivity(
-                    startEphemeralIntent, null /*options*/);
-            final TestResult testResult = getResult();
-            fail();
-        } catch (ActivityNotFoundException expected) {
-        }
-
         // start the ephemeral activity; using VIEW/BROWSABLE
         {
             final Intent startViewIntent = new Intent(Intent.ACTION_VIEW)
diff --git a/hostsidetests/bootstats/src/android/bootstats/cts/BootStatsHostTest.java b/hostsidetests/bootstats/src/android/bootstats/cts/BootStatsHostTest.java
index 75e3fd5..7d7257f 100644
--- a/hostsidetests/bootstats/src/android/bootstats/cts/BootStatsHostTest.java
+++ b/hostsidetests/bootstats/src/android/bootstats/cts/BootStatsHostTest.java
@@ -16,11 +16,12 @@
 
 package android.bootstats.cts;
 
+import com.android.tradefed.log.LogUtil.CLog;
 import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
 import com.android.tradefed.testtype.DeviceTestCase;
-
 import junit.framework.Assert;
 
+
 /**
  * Set of tests that verify statistics collection during boot.
  */
@@ -28,6 +29,13 @@
     private static final String TAG = "BootStatsHostTest";
 
     public void testBootStats() throws Exception {
+        final int apiLevel = getDevice().getApiLevel();
+        if (apiLevel < 26 /* Build.VERSION_CODES.O */) {
+            CLog.i(TAG, "Skipping test because boot time metrics were introduced"
+                + " in Android 8.0. Current API Level " + apiLevel);
+            return;
+        }
+
         long startTime = System.currentTimeMillis();
         // Clear buffer to make it easier to find new logs
         getDevice().executeShellCommand("logcat --buffer=events --clear");
diff --git a/hostsidetests/devicepolicy/app/DeviceAndProfileOwner/api23/Android.mk b/hostsidetests/devicepolicy/app/DeviceAndProfileOwner/api23/Android.mk
index dc040cc..1599d60 100644
--- a/hostsidetests/devicepolicy/app/DeviceAndProfileOwner/api23/Android.mk
+++ b/hostsidetests/devicepolicy/app/DeviceAndProfileOwner/api23/Android.mk
@@ -31,13 +31,19 @@
 
 LOCAL_USE_AAPT2 := true
 
-LOCAL_STATIC_JAVA_LIBRARIES = compatibility-device-util ctstestrunner ub-uiautomator
+LOCAL_STATIC_JAVA_LIBRARIES := \
+    compatibility-device-util \
+    ctstestrunner \
+    ub-uiautomator \
+    cts-security-test-support-library
 
 LOCAL_STATIC_ANDROID_LIBRARIES := \
     androidx.legacy_legacy-support-v4
 
 LOCAL_RESOURCE_DIR := $(LOCAL_PATH)/../res
 
+LOCAL_ASSET_DIR := $(LOCAL_PATH)/../assets
+
 # tag this module as a cts test artifact
 LOCAL_COMPATIBILITY_SUITE := cts vts general-tests
 
diff --git a/hostsidetests/devicepolicy/app/DeviceAndProfileOwner/api25/Android.mk b/hostsidetests/devicepolicy/app/DeviceAndProfileOwner/api25/Android.mk
index 85d7eba..481f821 100644
--- a/hostsidetests/devicepolicy/app/DeviceAndProfileOwner/api25/Android.mk
+++ b/hostsidetests/devicepolicy/app/DeviceAndProfileOwner/api25/Android.mk
@@ -31,13 +31,19 @@
 
 LOCAL_USE_AAPT2 := true
 
-LOCAL_STATIC_JAVA_LIBRARIES = compatibility-device-util ctstestrunner ub-uiautomator
+LOCAL_STATIC_JAVA_LIBRARIES := \
+    compatibility-device-util \
+    ctstestrunner \
+    ub-uiautomator \
+    cts-security-test-support-library
 
 LOCAL_STATIC_ANDROID_LIBRARIES := \
     androidx.legacy_legacy-support-v4
 
 LOCAL_RESOURCE_DIR := $(LOCAL_PATH)/../res
 
+LOCAL_ASSET_DIR := $(LOCAL_PATH)/../assets
+
 # tag this module as a cts test artifact
 LOCAL_COMPATIBILITY_SUITE := cts vts general-tests
 
diff --git a/hostsidetests/devicepolicy/app/DeviceAndProfileOwner/assets/user-cert-chain.crt b/hostsidetests/devicepolicy/app/DeviceAndProfileOwner/assets/user-cert-chain.crt
new file mode 100644
index 0000000..69a2ec4
--- /dev/null
+++ b/hostsidetests/devicepolicy/app/DeviceAndProfileOwner/assets/user-cert-chain.crt
@@ -0,0 +1,90 @@
+-----BEGIN CERTIFICATE-----
+MIIEdTCCAl2gAwIBAgICEAAwDQYJKoZIhvcNAQELBQAwWzELMAkGA1UEBhMCR0Ix
+EDAOBgNVBAgMB0VuZ2xhbmQxEjAQBgNVBAoMCUdvb2dsZSBVSzEMMAoGA1UECwwD
+QWZXMRgwFgYDVQQDDA9JbnRlcm1lZGlhdGUgQ0EwHhcNMTgwNTA0MTM0MDE2WhcN
+MTkwNTA0MTM0MDE2WjBcMQswCQYDVQQGEwJHQjEQMA4GA1UECAwHRW5nbGFuZDES
+MBAGA1UECgwJR29vZ2xlIFVLMQwwCgYDVQQLDANBZlcxGTAXBgNVBAMMEExlYWYg
+Q2VydGlmaWNhdGUwgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBANEeK9ebNbMU
+4SfnlCcWjndW6361NGP+G4lAzY8BC+ARL0M/sTCBWdI6rXdya4rKqeZoLmzrrnoy
+BhWjWR8/2PHPehe/0BYLfmvdAlly0qs3Sy/M8M1jm2EQSsn4Y7qQZzHd3miwmvYu
+D7V289GaMrtLOjTWY0K8el3+lbX4sFy3AgMBAAGjgcUwgcIwCQYDVR0TBAIwADAR
+BglghkgBhvhCAQEEBAMCBaAwMwYJYIZIAYb4QgENBCYWJE9wZW5TU0wgR2VuZXJh
+dGVkIENsaWVudCBDZXJ0aWZpY2F0ZTAdBgNVHQ4EFgQU7SFqAjCmwZOZISq5+fo7
+9rhxKTAwHwYDVR0jBBgwFoAU1g0G+yGBoH3bYetZOsR4KBLmDSkwDgYDVR0PAQH/
+BAQDAgXgMB0GA1UdJQQWMBQGCCsGAQUFBwMCBggrBgEFBQcDBDANBgkqhkiG9w0B
+AQsFAAOCAgEAAwQofIl4Hkv2F7buuifJmbCrlt3PMPAUOHqXeBHBwBqx0NZGmmeD
+cIhLSUxcy4LItr4dHjJZhLc8S3LWrb56hPhUgQyZXxDqJkK8tIVYRjSm+HEarcV7
+LGYrifbk6SbNXDNDyNFaISR2JTUjqJoTh1scqoNECyFi2/R2L2YJnUNZlraZc8Jh
+jwM/I1sAawb0VQ9sl6l9PRZpblFCeGIGuJjse73iD4N3CV3cANsnLBczHY8hVO7O
+lqkDEL1lQaK7UoIbfMjlwRYo3lXhA/fucoFVtZMU4moFrF8EFkXtm1WpFjt17uEc
+3wRMKVUdEe9eC0e6J3ygX8jQePmsJ2KPu/YNDwX7IbZdco8ve3h42EQMCWf5tj+r
+8If/WktFMYTjOry9UjBNJR/GhC813DdXbBeLgiosv0F6t5WAR4xN5+kd5IOJsxfm
+XH6Gqc58S0fQ2qYhadJ2xeyd+wTq+vEKXjRAT+ux/g75YuWClI3TPIcUayqhDTbG
+CtWh8CWv1ner8ikDQav9QftYmfeg6pt84G7Gp5GVOhMjSK0++NUBP9U9BNbqfF7w
+3mTLIVd9EFNZj6ZYq7BVZLT+LkWz5L9eA0FNCwYJ28cAdWfwZIo2zYi80sMPSBhX
+gAMyTUT5U1r1e2rmIenMOissJklugck9aMfy2eeL2DAPPkpHJaRQibQ=
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIFkDCCA3igAwIBAgICEAAwDQYJKoZIhvcNAQELBQAwUzELMAkGA1UEBhMCR0Ix
+EDAOBgNVBAgMB0VuZ2xhbmQxEjAQBgNVBAoMCUdvb2dsZSBVSzEMMAoGA1UECwwD
+QWZXMRAwDgYDVQQDDAdSb290IENBMB4XDTE4MDUwNDEzMzk1OFoXDTI4MDUwMTEz
+Mzk1OFowWzELMAkGA1UEBhMCR0IxEDAOBgNVBAgMB0VuZ2xhbmQxEjAQBgNVBAoM
+CUdvb2dsZSBVSzEMMAoGA1UECwwDQWZXMRgwFgYDVQQDDA9JbnRlcm1lZGlhdGUg
+Q0EwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQC4wg9xAYmkcBVL8zOY
+watFS5clnxZYvzyrDOAUnEIb8+485+9b94FgAV3/BeoHK8TGK3L63zj5ZfTBwKaH
+qMo6KJZDq3HXVf02nFdyGsF2Tt0XUsJByKi0Zyow6921mTwKJIifeJOyV2bYVTyl
+rkw04M9XAtsT0BdH61eDrTc2KTIqUyf81Zjac2RJ/y4zECtZK8owO2ACf1a8UXUF
+8qLxeEI/QFgpVb8arm0NrNy/MuSkltMb1K4+iAbMimsL75mkYm9FynoBXeaCkrF1
+DS/TFu2vjAjxs0j7ly7LkoEZFVE/rCSUnJ84BX37sIBZVWSh/lJU2aW79BA8LqtU
+mbihzNOef0odIjDmvkb+pa+PM9q/TMxaIk75pS/xKkhvHsXcR+mbVdFItO8V/cY2
+R+RumeNNuloNSqIFtg+YcoLkaVJcJL7YHfNLp5RaxbZCurR0uCp/bebjg5ofhOtx
+vUFQntq8MBJJdyZBh/P9RSMXqKv5WZg/tdjlRn6QPn1E4hJGXgctp5qXLGDPlNq4
+bDfA3cTpNadBIVPbo7apNe1MGbJBAGec54pHd7xEPcvQxE+MKLHwFJ+gfpenJjf0
+ZhEvEWQWN/v1URgbj/tIPUsmxxCfwJurIB6JSWSM8rEaGod5xk4hdtwl3K6tgdNI
+pHnofVEFPCQ5BYQgwZYhz9N92wIDAQABo2YwZDAdBgNVHQ4EFgQU1g0G+yGBoH3b
+YetZOsR4KBLmDSkwHwYDVR0jBBgwFoAUvAjWrHfE0UJ1CL1TBLA6oUOGlyMwEgYD
+VR0TAQH/BAgwBgEB/wIBADAOBgNVHQ8BAf8EBAMCAYYwDQYJKoZIhvcNAQELBQAD
+ggIBADyWqCGfkV9krR5YfMhgYf29FY1hdhkmqtj+xM4k3Xjz2T/S7mnK38tZWuhy
+Dm4bNHcOXGFv5Lkt2I1WhHsSYanpPNxQ0rNf1Q6GN25jTUIL2LW4BADsojXx9FFC
+ZR83p5sU8tUbxkCYsCL71FrimDlP9HI7/DKLQpt+Aen606DD/OgCpdu2z8qjAKSm
+8XY1g76IZXhBRCwmePUBHZdE4mLIEbA0A4hliDpSmnqcW82KgpLwqZEWnBqOQ1jS
+Sz6Wkc103nNmXU+bbRrp6QbIiXm6MxvcyLmwFlsz1755op9L2pt5u7oYto49uoPZ
+usG4XcM3yu6xX98OdZ8GY8LfC5gjKE/hLxyqQ8WFDhHLXcWK9OFnNpOdZPdQY/hr
+kEc9Dy/6PhSm0bcHwdb/8ULIpPeAK4YoI/PnX6yFkQ1d+/u8v3KUDWhHLcDw6bx3
+m5+rHS9qi5uFrrMQVe9djT6fCcOSSOWysBnGjhi/2kq0QANYTWCZt54POZWyhdM8
+fxiWKWb0TYcZ8WglJiw6VbhgubYk1L4e5Oc11usoMZbPvQisUmM5jHrG1UoomIiZ
+4++crlQh150vhALQlMWiVoy4kkcukianHRxTwyt0Qp5+aZVWZsgvXG4GJV3zdHhl
+/QS03DR8RVuR+gocytZ4/AVe8OLSbQgkyo0TFdi+e9/eZsuT
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIFjDCCA3SgAwIBAgIJAPkRa828+pS/MA0GCSqGSIb3DQEBCwUAMFMxCzAJBgNV
+BAYTAkdCMRAwDgYDVQQIDAdFbmdsYW5kMRIwEAYDVQQKDAlHb29nbGUgVUsxDDAK
+BgNVBAsMA0FmVzEQMA4GA1UEAwwHUm9vdCBDQTAeFw0xODA1MDQxMzM5NTBaFw0z
+ODA0MjkxMzM5NTBaMFMxCzAJBgNVBAYTAkdCMRAwDgYDVQQIDAdFbmdsYW5kMRIw
+EAYDVQQKDAlHb29nbGUgVUsxDDAKBgNVBAsMA0FmVzEQMA4GA1UEAwwHUm9vdCBD
+QTCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBANus/4IJXnsfrQACYHpa
+ZlVol3Z99dHGf5i6tqBP8E2uXGMc9ntC2lNJZwWrptIli1f2mpBQYbAstpaZNLZB
+8To9CxySbqNtZEXJEQhs5vh3iyStcXaQHhreikLzpgr0UpVrKy+SvL4ILarKF6+U
+JN9vShEmO7AhfqBs0mOUqNuQlM+loHvhCta+wtiLIQEFyHXdLIXR1YCh3gwqrFtA
+xvCDhK6J6ZGAM9f8W+LaCaWoMylDqD27Vth6tBhnRKtyfWj8bkE+sPKgkIb09yks
+0SjAq2bHMpe07nMR5BHREVl73h1QswZVYQKI21PLAc976r1ec7U1oviHQuPSpNBQ
+L0t/0V8X6jBe2SzPfpG8I34HPs/UPyPCC7Eu514MV03OdvWx24XbvfwQoZlxQ/g4
+6gg9jSI/87rFfI92r8NjgVg88QWTpRaBh15BSrRXEkvzenvjs7TlxgxdSmC6wsuH
+jfEYCfelZvMEHBwK9hCwzavFtiTTfsyq9FBdvtpp35IFd7Nvg0j0EtKeWTFTEO3z
+p00yNn20dND5prXMnTA6XKn/+cFRwIKx7Mh5+NK8zJBkh/32griye06ZGvH3tfFR
+45TkYkS7sxYbmaTEg/seWH8nkBW24q/ItY/M0xebPXSemM8RdhEY/nlVMxO/QKl+
+ja4rc7zqzFlonTu/zP0QaVV9AgMBAAGjYzBhMB0GA1UdDgQWBBS8CNasd8TRQnUI
+vVMEsDqhQ4aXIzAfBgNVHSMEGDAWgBS8CNasd8TRQnUIvVMEsDqhQ4aXIzAPBgNV
+HRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBhjANBgkqhkiG9w0BAQsFAAOCAgEA
+Y1rIDPAUc4g0GMX8/V4KZARFrM7ql64wqpjyJ4qe+dXnX0fAjhvQff8ozPdZ44N2
+CAukKCMO74DtnFWAI/MjATAXfrTeBtznQiGopnO+cHAvWP6U+7uuUqCQcYWaCx/b
+eyEAaOg7FVUQ4vTdl4qgsqagyjqBFiefpTYYdH3wbWso2N3xUTBbnUHJZ2h+LGMW
+VS//hyxhNKjXjCKtOJQmg5x1DQPi1tiQx9PcjMqCsbzEzbr7Gr4otOue+fDWnFTR
+AVUtxigLk508NrArbvIK6YCZ0eSsRVeaMknfcFxq7Oh9wXBDXNnQ+Gf+Y4PCLz2F
+FRJ/+8AaZYnLjTbJ2By3u6r5xkLoKUoLF8W4ERMF4eEQzU0wASLYYI1SdzqEZjv9
+yDF7E2CATs0/3X89HolnOdMTxBJBdOEApg53f7nSsMLSYc1umbfPRg/db5FOhruR
+xwCzcDJEpT2NYnmnDtzIIsQLrOLZAc/KLsR346scXjIqfW3uJFqF7JKu217QHmRq
+cPHjoTX2vWzJH2mo43fpRzJEXhThQ0Ii6COH3r8OScSxyC4yrDoOSvdmL1q9KTH+
+o2D52WTNglmJy4NKfuAcs3EPmmaf8fv9kOgE667Ifm2yl5/NvxDAWq4UoeCIHBf9
+76b9U8xQgKFCTXWQu23kMxuNaaPHwTPjBhxA6+Pjxh8=
+-----END CERTIFICATE-----
diff --git a/hostsidetests/devicepolicy/app/DeviceAndProfileOwner/assets/user-cert-chain.key b/hostsidetests/devicepolicy/app/DeviceAndProfileOwner/assets/user-cert-chain.key
new file mode 100644
index 0000000..f6d5942
--- /dev/null
+++ b/hostsidetests/devicepolicy/app/DeviceAndProfileOwner/assets/user-cert-chain.key
Binary files differ
diff --git a/hostsidetests/devicepolicy/app/DeviceAndProfileOwner/latest/Android.mk b/hostsidetests/devicepolicy/app/DeviceAndProfileOwner/latest/Android.mk
index f2d145e..8c6d3fd 100644
--- a/hostsidetests/devicepolicy/app/DeviceAndProfileOwner/latest/Android.mk
+++ b/hostsidetests/devicepolicy/app/DeviceAndProfileOwner/latest/Android.mk
@@ -31,13 +31,19 @@
 
 LOCAL_USE_AAPT2 := true
 
-LOCAL_STATIC_JAVA_LIBRARIES = compatibility-device-util ctstestrunner ub-uiautomator
+LOCAL_STATIC_JAVA_LIBRARIES := \
+    compatibility-device-util \
+    ctstestrunner \
+    ub-uiautomator \
+    cts-security-test-support-library
 
 LOCAL_STATIC_ANDROID_LIBRARIES := \
     androidx.legacy_legacy-support-v4
 
 LOCAL_RESOURCE_DIR := $(LOCAL_PATH)/../res
 
+LOCAL_ASSET_DIR := $(LOCAL_PATH)/../assets
+
 # tag this module as a cts test artifact
 LOCAL_COMPATIBILITY_SUITE := arcts cts vts general-tests
 
diff --git a/hostsidetests/devicepolicy/app/DeviceAndProfileOwner/latest/AndroidManifest.xml b/hostsidetests/devicepolicy/app/DeviceAndProfileOwner/latest/AndroidManifest.xml
index 515db7c..5419611 100644
--- a/hostsidetests/devicepolicy/app/DeviceAndProfileOwner/latest/AndroidManifest.xml
+++ b/hostsidetests/devicepolicy/app/DeviceAndProfileOwner/latest/AndroidManifest.xml
@@ -29,6 +29,8 @@
     <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
     <uses-permission android:name="android.permission.SET_WALLPAPER" />
     <uses-permission android:name="android.permission.MODIFY_AUDIO_SETTINGS" />
+    <!-- Needed to read the serial number during Device ID attestation tests -->
+    <uses-permission android:name="android.permission.READ_PHONE_STATE" />
 
     <!-- Add a network security config that trusts user added CAs for tests -->
     <application android:networkSecurityConfig="@xml/network_security_config"
@@ -73,6 +75,10 @@
         <activity android:name="com.android.cts.deviceandprofileowner.AutofillActivity"/>
 
         <activity android:name=".PrintActivity"/>
+
+        <activity
+            android:name="com.android.cts.deviceandprofileowner.KeyManagementActivity"
+            android:theme="@android:style/Theme.Translucent.NoTitleBar" />
     </application>
 
     <instrumentation
diff --git a/hostsidetests/devicepolicy/app/DeviceOwner/assets/ca.conf b/hostsidetests/devicepolicy/app/DeviceAndProfileOwner/scripts/ca.conf
similarity index 100%
rename from hostsidetests/devicepolicy/app/DeviceOwner/assets/ca.conf
rename to hostsidetests/devicepolicy/app/DeviceAndProfileOwner/scripts/ca.conf
diff --git a/hostsidetests/devicepolicy/app/DeviceOwner/assets/generate-client-cert-chain.sh b/hostsidetests/devicepolicy/app/DeviceAndProfileOwner/scripts/generate-client-cert-chain.sh
similarity index 91%
rename from hostsidetests/devicepolicy/app/DeviceOwner/assets/generate-client-cert-chain.sh
rename to hostsidetests/devicepolicy/app/DeviceAndProfileOwner/scripts/generate-client-cert-chain.sh
index 8b0639f..df2f380 100755
--- a/hostsidetests/devicepolicy/app/DeviceOwner/assets/generate-client-cert-chain.sh
+++ b/hostsidetests/devicepolicy/app/DeviceAndProfileOwner/scripts/generate-client-cert-chain.sh
@@ -9,7 +9,9 @@
 set -e
 
 WORKDIR='temp'
+TARGETDIR='../assets/'
 
+rm -rf "$WORKDIR"
 mkdir "$WORKDIR"
 cp ca.conf "$WORKDIR/"
 pushd "$WORKDIR"
@@ -26,6 +28,7 @@
     -days 7300 \
     -sha256 \
     -extensions v3_ca \
+    -nodes \
     -keyout private/ca.key.pem \
     -out certs/ca.cert.pem
 popd
@@ -41,6 +44,7 @@
     -config ca.conf \
     -new \
     -sha256 \
+    -nodes \
     -keyout intermediate/private/intermediate.key.pem \
     -out intermediate/csr/intermediate.csr.pem
 
@@ -80,7 +84,7 @@
     "$WORKDIR"/user.cert.pem \
     "$WORKDIR"/intermediate/certs/intermediate.cert.pem \
     "$WORKDIR"/rootca/certs/ca.cert.pem \
-    > user-cert-chain.crt
+    > "$TARGETDIR"/user-cert-chain.crt
 
 openssl pkcs8 \
     -topk8 \
@@ -88,6 +92,6 @@
     -inform PEM \
     -outform DER \
     -in "$WORKDIR"/user.key.pem \
-    -out user-cert-chain.key
+    -out "$TARGETDIR"/user-cert-chain.key
 
-rm -r "$WORKDIR"
\ No newline at end of file
+rm -r "$WORKDIR"
diff --git a/hostsidetests/devicepolicy/app/DeviceAndProfileOwner/src/com/android/cts/deviceandprofileowner/BaseDeviceAdminTest.java b/hostsidetests/devicepolicy/app/DeviceAndProfileOwner/src/com/android/cts/deviceandprofileowner/BaseDeviceAdminTest.java
index 1c4230b..a88a463 100644
--- a/hostsidetests/devicepolicy/app/DeviceAndProfileOwner/src/com/android/cts/deviceandprofileowner/BaseDeviceAdminTest.java
+++ b/hostsidetests/devicepolicy/app/DeviceAndProfileOwner/src/com/android/cts/deviceandprofileowner/BaseDeviceAdminTest.java
@@ -19,8 +19,11 @@
 import android.app.admin.DevicePolicyManager;
 import android.content.ComponentName;
 import android.content.Context;
+import android.content.Intent;
 import android.content.pm.PackageInfo;
 import android.content.pm.PackageManager;
+import android.net.Uri;
+import android.os.Process;
 import android.os.UserManager;
 import android.test.InstrumentationTestCase;
 import android.text.TextUtils;
@@ -37,6 +40,16 @@
 public class BaseDeviceAdminTest extends InstrumentationTestCase {
 
     public static class BasicAdminReceiver extends DeviceAdminReceiver {
+
+        @Override
+        public String onChoosePrivateKeyAlias(Context context, Intent intent, int uid, Uri uri,
+                String suggestedAlias) {
+            super.onChoosePrivateKeyAlias(context, intent, uid, uri, suggestedAlias);
+            if (uid != Process.myUid() || uri == null) {
+                return null;
+            }
+            return uri.getQueryParameter("alias");
+        }
     }
 
     public static final String PACKAGE_NAME = BasicAdminReceiver.class.getPackage().getName();
@@ -100,4 +113,8 @@
         }
         assertEquals(expectPasswordSufficient, mDevicePolicyManager.isActivePasswordSufficient());
     }
+
+    protected boolean isDeviceOwner() {
+        return mDevicePolicyManager.isDeviceOwnerApp(PACKAGE_NAME);
+    }
 }
diff --git a/hostsidetests/devicepolicy/app/DeviceOwner/src/com/android/cts/deviceowner/KeyManagementActivity.java b/hostsidetests/devicepolicy/app/DeviceAndProfileOwner/src/com/android/cts/deviceandprofileowner/KeyManagementActivity.java
similarity index 93%
rename from hostsidetests/devicepolicy/app/DeviceOwner/src/com/android/cts/deviceowner/KeyManagementActivity.java
rename to hostsidetests/devicepolicy/app/DeviceAndProfileOwner/src/com/android/cts/deviceandprofileowner/KeyManagementActivity.java
index fda124f..c7c53c5 100644
--- a/hostsidetests/devicepolicy/app/DeviceOwner/src/com/android/cts/deviceowner/KeyManagementActivity.java
+++ b/hostsidetests/devicepolicy/app/DeviceAndProfileOwner/src/com/android/cts/deviceandprofileowner/KeyManagementActivity.java
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package com.android.cts.deviceowner;
+package com.android.cts.deviceandprofileowner;
 
 import android.app.Activity;
 
diff --git a/hostsidetests/devicepolicy/app/DeviceOwner/src/com/android/cts/deviceowner/KeyManagementTest.java b/hostsidetests/devicepolicy/app/DeviceAndProfileOwner/src/com/android/cts/deviceandprofileowner/KeyManagementTest.java
similarity index 89%
rename from hostsidetests/devicepolicy/app/DeviceOwner/src/com/android/cts/deviceowner/KeyManagementTest.java
rename to hostsidetests/devicepolicy/app/DeviceAndProfileOwner/src/com/android/cts/deviceandprofileowner/KeyManagementTest.java
index 13b0f53..7d05b17 100755
--- a/hostsidetests/devicepolicy/app/DeviceOwner/src/com/android/cts/deviceowner/KeyManagementTest.java
+++ b/hostsidetests/devicepolicy/app/DeviceAndProfileOwner/src/com/android/cts/deviceandprofileowner/KeyManagementTest.java
@@ -13,19 +13,16 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-package com.android.cts.deviceowner;
+package com.android.cts.deviceandprofileowner;
 
-import static android.keystore.cts.CertificateUtils.createCertificate;
-import static com.android.compatibility.common.util.FakeKeys.FAKE_RSA_1;
 import static android.app.admin.DevicePolicyManager.ID_TYPE_BASE_INFO;
 import static android.app.admin.DevicePolicyManager.ID_TYPE_IMEI;
 import static android.app.admin.DevicePolicyManager.ID_TYPE_MEID;
 import static android.app.admin.DevicePolicyManager.ID_TYPE_SERIAL;
+import static android.keystore.cts.CertificateUtils.createCertificate;
 
-import android.app.admin.DevicePolicyManager;
 import android.content.ComponentName;
 import android.content.Context;
-import android.content.pm.PackageManager;
 import android.content.res.AssetManager;
 import android.keystore.cts.Attestation;
 import android.keystore.cts.AuthorizationList;
@@ -37,8 +34,10 @@
 import android.security.KeyChainException;
 import android.security.keystore.KeyGenParameterSpec;
 import android.security.keystore.KeyProperties;
+import android.support.test.uiautomator.UiDevice;
 import android.telephony.TelephonyManager;
-import android.test.ActivityInstrumentationTestCase2;
+
+import com.android.compatibility.common.util.FakeKeys.FAKE_RSA_1;
 
 import java.io.ByteArrayInputStream;
 import java.io.ByteArrayOutputStream;
@@ -63,18 +62,14 @@
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.Collection;
+import java.util.List;
 import java.util.concurrent.CountDownLatch;
 import java.util.concurrent.TimeUnit;
-import java.util.HashSet;
-import java.util.List;
-import java.util.LinkedList;
-import java.util.Set;
+
 import javax.security.auth.x500.X500Principal;
 
-public class KeyManagementTest extends ActivityInstrumentationTestCase2<KeyManagementActivity> {
-
+public class KeyManagementTest extends BaseDeviceAdminTest {
     private static final long KEYCHAIN_TIMEOUT_MINS = 6;
-    private DevicePolicyManager mDevicePolicyManager;
 
     private static class SupportedKeyAlgorithm {
         public final String keyAlgorithm;
@@ -88,7 +83,7 @@
             this.signatureAlgorithm = signatureAlgorithm;
             this.signaturePaddingSchemes = signaturePaddingSchemes;
         }
-    };
+    }
 
     private final SupportedKeyAlgorithm[] SUPPORTED_KEY_ALGORITHMS = new SupportedKeyAlgorithm[] {
         new SupportedKeyAlgorithm(KeyProperties.KEY_ALGORITHM_RSA, "SHA256withRSA",
@@ -97,25 +92,20 @@
         new SupportedKeyAlgorithm(KeyProperties.KEY_ALGORITHM_EC, "SHA256withECDSA", null)
     };
 
-    public KeyManagementTest() {
-        super(KeyManagementActivity.class);
-    }
+    private KeyManagementActivity mActivity;
 
     @Override
-    protected void setUp() throws Exception {
+    public void setUp() throws Exception {
         super.setUp();
-
-        // Confirm our DeviceOwner is set up
-        mDevicePolicyManager = (DevicePolicyManager)
-                getActivity().getSystemService(Context.DEVICE_POLICY_SERVICE);
-        assertDeviceOwner(mDevicePolicyManager);
-
-        // Hostside test has set a device lockscreen in order to enable credential storage
+        final UiDevice device = UiDevice.getInstance(getInstrumentation());
+        mActivity = launchActivity(getInstrumentation().getTargetContext().getPackageName(),
+                KeyManagementActivity.class, null);
+        device.waitForIdle();
     }
 
     @Override
-    protected void tearDown() throws Exception {
-        // Hostside test will clear device lockscreen which in turn will clear the keystore.
+    public void tearDown() throws Exception {
+        mActivity.finish();
         super.tearDown();
     }
 
@@ -133,7 +123,7 @@
             assertGranted(alias, true);
 
             // Verify key is at least something like the one we put in.
-            assertEquals(KeyChain.getPrivateKey(getActivity(), alias).getAlgorithm(), "RSA");
+            assertEquals(KeyChain.getPrivateKey(mActivity, alias).getAlgorithm(), "RSA");
         } finally {
             // Delete regardless of whether the test succeeded.
             assertTrue(mDevicePolicyManager.removeKeyPair(getWho(), alias));
@@ -159,7 +149,7 @@
             assertGranted(withhold, false);
 
             // Verify the granted key is actually obtainable in PrivateKey form.
-            assertEquals(KeyChain.getPrivateKey(getActivity(), grant).getAlgorithm(), "RSA");
+            assertEquals(KeyChain.getPrivateKey(mActivity, grant).getAlgorithm(), "RSA");
         } finally {
             // Delete both keypairs.
             assertTrue(mDevicePolicyManager.removeKeyPair(getWho(), grant));
@@ -195,10 +185,10 @@
             assertGranted(alias, true);
 
             // Verify the granted key is actually obtainable in PrivateKey form.
-            assertEquals(KeyChain.getPrivateKey(getActivity(), alias).getAlgorithm(), "RSA");
+            assertEquals(KeyChain.getPrivateKey(mActivity, alias).getAlgorithm(), "RSA");
 
             // Verify the certificate chain is correct
-            X509Certificate[] returnedCerts = KeyChain.getCertificateChain(getActivity(), alias);
+            X509Certificate[] returnedCerts = KeyChain.getCertificateChain(mActivity, alias);
             assertTrue(Arrays.equals(certChain, returnedCerts));
         } finally {
             // Delete both keypairs.
@@ -471,25 +461,29 @@
 
     public void testAllVariationsOfDeviceIdAttestation() throws Exception {
         List<Integer> modesToTest = new ArrayList<Integer>();
+        String imei = null;
+        String meid = null;
         // All devices must support at least basic device information attestation as well as serial
-        // number attestation.
+        // number attestation. Although attestation of unique device ids are only callable by device
+        // owner.
         modesToTest.add(ID_TYPE_BASE_INFO);
-        modesToTest.add(ID_TYPE_SERIAL);
-        // Get IMEI and MEID of the device.
-        TelephonyManager telephonyService = (TelephonyManager) getActivity().getSystemService(
-                Context.TELEPHONY_SERVICE);
-        assertNotNull("Need to be able to read device identifiers", telephonyService);
-        String imei = telephonyService.getImei(0);
-        String meid = telephonyService.getMeid(0);
-        // If the device has a valid IMEI it must support attestation for it.
-        if (imei != null) {
-            modesToTest.add(ID_TYPE_IMEI);
+        if (isDeviceOwner()) {
+            modesToTest.add(ID_TYPE_SERIAL);
+            // Get IMEI and MEID of the device.
+            TelephonyManager telephonyService = (TelephonyManager) mActivity.getSystemService(
+                    Context.TELEPHONY_SERVICE);
+            assertNotNull("Need to be able to read device identifiers", telephonyService);
+            imei = telephonyService.getImei(0);
+            meid = telephonyService.getMeid(0);
+            // If the device has a valid IMEI it must support attestation for it.
+            if (imei != null) {
+                modesToTest.add(ID_TYPE_IMEI);
+            }
+            // Same for MEID
+            if (meid != null) {
+                modesToTest.add(ID_TYPE_MEID);
+            }
         }
-        // Same for MEID
-        if (meid != null) {
-            modesToTest.add(ID_TYPE_MEID);
-        }
-
         int numCombinations = 1 << modesToTest.size();
         for (int i = 1; i < numCombinations; i++) {
             // Set the bits in devIdOpt to be passed into generateKeyPair according to the
@@ -539,6 +533,27 @@
         }
     }
 
+    public void testProfileOwnerCannotAttestDeviceUniqueIds() throws Exception {
+        if (isDeviceOwner()) {
+            return;
+        }
+        int[] forbiddenModes = new int[] {ID_TYPE_SERIAL, ID_TYPE_IMEI, ID_TYPE_MEID};
+        for (int i = 0; i < forbiddenModes.length; i++) {
+            try {
+                for (SupportedKeyAlgorithm supportedKey: SUPPORTED_KEY_ALGORITHMS) {
+                    generateKeyAndCheckAttestation(supportedKey.keyAlgorithm,
+                            supportedKey.signatureAlgorithm,
+                            supportedKey.signaturePaddingSchemes,
+                            forbiddenModes[i]);
+                    fail("Attestation of device UID (" + forbiddenModes[i] + ") should not be "
+                            + "possible from profile owner");
+                }
+            } catch (SecurityException e) {
+                assertTrue(e.getMessage().contains("does not own the device"));
+            }
+        }
+    }
+
     public void testCanSetKeyPairCert() throws Exception {
         final String alias = "com.android.test.set-ec-1";
         try {
@@ -562,7 +577,7 @@
             // Make sure that the alias can now be obtained.
             assertEquals(alias, new KeyChainAliasFuture(alias).get());
             // And can be retrieved from KeyChain
-            X509Certificate[] fetchedCerts = KeyChain.getCertificateChain(getActivity(), alias);
+            X509Certificate[] fetchedCerts = KeyChain.getCertificateChain(mActivity, alias);
             assertEquals(fetchedCerts.length, certs.size());
             assertTrue(Arrays.equals(fetchedCerts[0].getEncoded(), certs.get(0).getEncoded()));
         } finally {
@@ -587,7 +602,7 @@
             // Make sure that the alias can now be obtained.
             assertEquals(alias, new KeyChainAliasFuture(alias).get());
             // And can be retrieved from KeyChain
-            X509Certificate[] fetchedCerts = KeyChain.getCertificateChain(getActivity(), alias);
+            X509Certificate[] fetchedCerts = KeyChain.getCertificateChain(mActivity, alias);
             assertEquals(fetchedCerts.length, chain.size());
             for (int i = 0; i < chain.size(); i++) {
                 assertTrue(Arrays.equals(fetchedCerts[i].getEncoded(), chain.get(i).getEncoded()));
@@ -600,7 +615,7 @@
     private void assertGranted(String alias, boolean expected) throws InterruptedException {
         boolean granted = false;
         try {
-            granted = (KeyChain.getPrivateKey(getActivity(), alias) != null);
+            granted = (KeyChain.getPrivateKey(mActivity, alias) != null);
         } catch (KeyChainException e) {
             if (expected) {
                 e.printStackTrace();
@@ -623,7 +638,7 @@
     private Collection<Certificate> loadCertificatesFromAsset(String assetName) {
         try {
             final CertificateFactory certFactory = CertificateFactory.getInstance("X.509");
-            AssetManager am = getActivity().getAssets();
+            AssetManager am = mActivity.getAssets();
             InputStream is = am.open(assetName);
             return (Collection<Certificate>) certFactory.generateCertificates(is);
         } catch (IOException | CertificateException e) {
@@ -634,7 +649,7 @@
 
     private PrivateKey loadPrivateKeyFromAsset(String assetName) {
         try {
-            AssetManager am = getActivity().getAssets();
+            AssetManager am = mActivity.getAssets();
             InputStream is = am.open(assetName);
             ByteArrayOutputStream output = new ByteArrayOutputStream();
             int length;
@@ -659,13 +674,14 @@
             mLatch.countDown();
         }
 
-        public KeyChainAliasFuture(String alias) throws UnsupportedEncodingException {
+        public KeyChainAliasFuture(String alias)
+                throws UnsupportedEncodingException {
             /* Pass the alias as a GET to an imaginary server instead of explicitly asking for it,
              * to make sure the DPC actually has to do some work to grant the cert.
              */
             final Uri uri =
                     Uri.parse("https://example.org/?alias=" + URLEncoder.encode(alias, "UTF-8"));
-            KeyChain.choosePrivateKeyAlias(getActivity(), this,
+            KeyChain.choosePrivateKeyAlias(mActivity, this,
                     null /* keyTypes */, null /* issuers */, uri, null /* alias */);
         }
 
@@ -675,14 +691,7 @@
         }
     }
 
-    private void assertDeviceOwner(DevicePolicyManager devicePolicyManager) {
-        assertNotNull(devicePolicyManager);
-        assertTrue(devicePolicyManager.isAdminActive(getWho()));
-        assertTrue(devicePolicyManager.isDeviceOwnerApp(getActivity().getPackageName()));
-        assertFalse(devicePolicyManager.isManagedProfile(getWho()));
-    }
-
-    private ComponentName getWho() {
-        return BasicAdminReceiver.getComponentName(getActivity());
+    protected ComponentName getWho() {
+        return ADMIN_RECEIVER_COMPONENT;
     }
 }
diff --git a/hostsidetests/devicepolicy/app/DeviceOwner/AndroidManifest.xml b/hostsidetests/devicepolicy/app/DeviceOwner/AndroidManifest.xml
index b13589d..b4dff59 100644
--- a/hostsidetests/devicepolicy/app/DeviceOwner/AndroidManifest.xml
+++ b/hostsidetests/devicepolicy/app/DeviceOwner/AndroidManifest.xml
@@ -29,8 +29,6 @@
     <uses-permission android:name="android.permission.BLUETOOTH" />
     <uses-permission android:name="android.permission.BLUETOOTH_ADMIN" />
     <uses-permission android:name="android.permission.DISABLE_KEYGUARD" />
-    <!-- Needed to read the serial number during Device ID attestation tests -->
-    <uses-permission android:name="android.permission.READ_PHONE_STATE" />
 
     <application
         android:testOnly="true"
@@ -71,10 +69,6 @@
         </service>
 
         <activity
-            android:name="com.android.cts.deviceowner.KeyManagementActivity"
-            android:theme="@android:style/Theme.Translucent.NoTitleBar" />
-
-        <activity
             android:name="com.android.cts.deviceowner.LockTaskUtilityActivity" />
         <activity
             android:name="com.android.cts.deviceowner.LockTaskUtilityActivityIfWhitelisted"
diff --git a/hostsidetests/devicepolicy/app/DeviceOwner/assets/user-cert-chain.crt b/hostsidetests/devicepolicy/app/DeviceOwner/assets/user-cert-chain.crt
deleted file mode 100644
index 72a86e3..0000000
--- a/hostsidetests/devicepolicy/app/DeviceOwner/assets/user-cert-chain.crt
+++ /dev/null
@@ -1,96 +0,0 @@
------BEGIN CERTIFICATE-----
-MIIFLzCCAxegAwIBAgICEAEwDQYJKoZIhvcNAQELBQAwZDELMAkGA1UEBhMCR0Ix
-EDAOBgNVBAgMB0VuZ2xhbmQxEjAQBgNVBAoMCUdvb2dsZSBVSzEMMAoGA1UECwwD
-QWZ3MSEwHwYDVQQDDBhBZlcgVGVzdCBJbnRlcm1lZGlhdGUgQ0EwHhcNMTYwMzE4
-MTcxMzA4WhcNMTcwMzI4MTcxMzA4WjCBiDELMAkGA1UEBhMCR0IxEDAOBgNVBAgM
-B0VuZ2xhbmQxEjAQBgNVBAoMCUdvb2dsZSBVSzEMMAoGA1UECwwDQWZ3MSUwIwYD
-VQQDDBxVc2VyMDAgdW5kZXIgaW50ZXJtZWRpYXRlIENBMR4wHAYJKoZIhvcNAQkB
-Fg90ZXN0QGdvb2dsZS5jb20wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIB
-AQC8W+PUeNVDIy6GSeTVjN9JSkYxcsupFq9AOUma0R+7z9EGuZBURZprgbrN7c2q
-RQnlSBZTC9fRMkXZ6LImWoY5GqS3NcbkJbUlA+UeK2uJXQQfjTO7bYDslvudX+8y
-WfYrR71DLpIFgDkxQAWGywMzNTR6TEmPy1qBGIFYohGqZkQoTS//s/iEEKDSsbPr
-mkTrf4lDAc8cgnmUPFPkN1Lr4ITkvhmEHQjJTcS+Qjeotlt+ss5vrmlqopFkCbI9
-7uC6RQDI0PvP9achzBsTUi0vNsGg45luCJhNrDu6s4NpnusKIVAoJPSJdion2yoD
-3Dp8LX/ueGNbP64LY6qmDWDlAgMBAAGjgcUwgcIwCQYDVR0TBAIwADARBglghkgB
-hvhCAQEEBAMCBaAwMwYJYIZIAYb4QgENBCYWJE9wZW5TU0wgR2VuZXJhdGVkIENs
-aWVudCBDZXJ0aWZpY2F0ZTAdBgNVHQ4EFgQUSp7kS1On3b7MdMstDVPCNkHm/EUw
-HwYDVR0jBBgwFoAUdejD6Fb3X8ZHOCKMWe5XwukxBDswDgYDVR0PAQH/BAQDAgXg
-MB0GA1UdJQQWMBQGCCsGAQUFBwMCBggrBgEFBQcDBDANBgkqhkiG9w0BAQsFAAOC
-AgEAXIOVhMjxbpO1uxe1MnyIsTrl0ajPlkn+4qWLwjXzUQ6TcE2Ow91AMcYs5siq
-UBplZyNYNBOhX8TZLNy7jJ/REwj65Qa/y0TcDucpGhtT9l1JIJCdEpPoymyiM18C
-NktXDyaw+DFkWC0a5oUhjk4UuzTfHkSVMKjZUnRPPiwL2gl9zEgS8qVI3ew4JjdP
-KCYGy/1B+61EE5vCP8GAByeKgtgnh4sVZnsKYQZzjwwUGL1uXQtazPs04qTUw3IK
-YvoOyNsXB4gcp2u4DXv2roVI36DQM5ZGenS9MViTeblg5vkZgy8xsktHyDGDlNe6
-cPw5OgyxDo4nr6TY4SX9eankantPMx7498n390B4lYAgBj4Cz4QaXM1IGN3JVF5J
-EEKqGkLpOYMRNZ4qPFhMknDZgHljjgFlcXGwtXtugCzQ5ldwkFb9qZeB5lQn1Aw0
-PthcDdGp/KCtHC5jF+BjlQITt0tVqJ4+SAdHyF53H+ScoINFul89m32pgvJjI/0k
-c0tidvXNPNodbJCqHmc917DryVJGXbxp+BqxTQ0a7e9K/WA4MnRKPfBTTeDq/j+w
-6B/rLd0bhMrPDi6a/1w97PqfAbS9TlkpnK8Gj4pN+ZOEEF0j0DtDRbb+CfJX14fR
-2R96mEfCeSbCuxLcbwdG1OUQM8GKlIcYfWIp0KjICxRKaDU=
------END CERTIFICATE-----
------BEGIN CERTIFICATE-----
-MIIFojCCA4qgAwIBAgICEAAwDQYJKoZIhvcNAQELBQAwXDELMAkGA1UEBhMCR0Ix
-EDAOBgNVBAgMB0VuZ2xhbmQxEjAQBgNVBAoMCUdvb2dsZSBVSzEMMAoGA1UECwwD
-QWZXMRkwFwYDVQQDDBBBZncgVGVzdCBSb290IENBMB4XDTE2MDMxODE3MDQ1N1oX
-DTI2MDMxNjE3MDQ1N1owZDELMAkGA1UEBhMCR0IxEDAOBgNVBAgMB0VuZ2xhbmQx
-EjAQBgNVBAoMCUdvb2dsZSBVSzEMMAoGA1UECwwDQWZ3MSEwHwYDVQQDDBhBZlcg
-VGVzdCBJbnRlcm1lZGlhdGUgQ0EwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIK
-AoICAQCZbYchy2Fry9nJuu2YEp2P13lIbyWu0FXF8qTus8Vp/25LyXDjBiDXZUlY
-PL32PY0PRbBQjm7tm/WNqXw8S7gw+5XXpY+XNCd/ygyIZhMdxPm7nqYsEtZDFViL
-ct/QJNAKILFejZQOfRSeyxeINprL+EjFHecA6KtruZULzJE0u0UGTgs5h9HbqhH7
-LbZ8iiE/TfG6kflUI2kAPxGiRpIyerYoVjp3Ta5026T+aoc6VyNnSYiZULgYLoL8
-P8x19G3Pplqf4U5bUyKtRtnPWOvM9iYphxsVuTc8rRpZGcMKhdL4gGLQpdruIZ43
-gvGMq4Kt2xVJExBOKMg3j3x52j1XtOcad/nz7ncak/6ElTd0gfhFgt9PwAfQZ32b
-BL3Zlcb+7Pvtv14xAWNHy5cMyn7UDzIsy/yqWLvJSfkZViU0vPuokXMKZIyzv73V
-4N9qXQAWXNz4HwgWy35rB1sirgMxLdWCpHrVeh/DzSrWZ/MtJIC9Ac1jTAuI6F1u
-b7dRRujWpcr57ReKDXXJzM83JQnENJQ3gAHrY8qTkGz7NLa7DsyzPdKOC7vZ0+Ed
-VMvn+c2AMWrwkRpn9JlU5bd2BN7D6UWGLTdzSN9QH7n7sXmQNAo/M7Lr9baxKZNY
-aU5DORVjnGvITZDHYiw9OuakWZUZATF+TTInKEasF131r9q9ZwIDAQABo2YwZDAd
-BgNVHQ4EFgQUdejD6Fb3X8ZHOCKMWe5XwukxBDswHwYDVR0jBBgwFoAUV4EHHOi0
-AqQIj4IMjPEFW3fVS8QwEgYDVR0TAQH/BAgwBgEB/wIBADAOBgNVHQ8BAf8EBAMC
-AYYwDQYJKoZIhvcNAQELBQADggIBACs0qS3EXymo1VgBInR9GrzvUq1gC/d3ohSG
-iB3x2zfqfQ4D0eiYADcCdXTPIwPtm8P8woK5QsRV/MCklqyvgVpRHFQe1uOAZJ7X
-Ud6hx9CCye0QkEoy+JDeVdPeFFf1b8S/daxLXUVbCKSTA+z8YLPRSEFi2d3cOwpx
-WPlkfLSwP6DfODicmPNd1V/qB/fevlmfRB6UKquT+v9xWyQqu4aa6F6xGWYWmc+1
-E/MB/oEOizJVv8VVETqMk8/xFPrMk28foI8ohrLkstSx8gH+oII1Ud1k1XoMMqqU
-Ge656Tr85Di5WfacMdKUommOEKQYRiic6ikcNEAVVNOHlOtw08ua7g1k1G/dwcj0
-DCF2WmWzdAMwST0AH/RPa+i9cX8f/yS15OUP7ncSaI7/ChGT3EBzP+bqxeXFOCNH
-0yNLk4tNLIzNwnKXGTfSbKMTYOZ3ngAiR4w3ro/LJhe2z03MOawxoiIosTc9UwKA
-YJ3nYHYw8/EJCKPth6yrUU3gU1V0vyaBy34y4xuha3oWnbc53vm1cv4BINwmuAms
-ASQpqCiGp2ZaalNu87xCnWE3HA4S3+0U3dsFJXdPdQt/cDzX+kDzojWeHmECp6mn
-GodmmPbEBqzDckMaM9CvSAp8NyZuO8hrOSoGTdxQtP1w3waOeM4zLYd7aBYUfefL
-36OoziEN
------END CERTIFICATE-----
------BEGIN CERTIFICATE-----
-MIIFnjCCA4agAwIBAgIJANLdX1zcxUSUMA0GCSqGSIb3DQEBCwUAMFwxCzAJBgNV
-BAYTAkdCMRAwDgYDVQQIDAdFbmdsYW5kMRIwEAYDVQQKDAlHb29nbGUgVUsxDDAK
-BgNVBAsMA0FmVzEZMBcGA1UEAwwQQWZ3IFRlc3QgUm9vdCBDQTAeFw0xNjAzMTgx
-NzAxMDBaFw0zNjAzMTMxNzAxMDBaMFwxCzAJBgNVBAYTAkdCMRAwDgYDVQQIDAdF
-bmdsYW5kMRIwEAYDVQQKDAlHb29nbGUgVUsxDDAKBgNVBAsMA0FmVzEZMBcGA1UE
-AwwQQWZ3IFRlc3QgUm9vdCBDQTCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoC
-ggIBANFyOD/BIGV4iHSGDrp1ajvp+00098dn+p1cqlMHMrWUjnqzcMdOVmeqSaQ/
-EkOlAIsdcl1yb+oo3DhomIzX/B2lTQSOSLDmthIgmu0hfk/gAiqLdA8/L2F9m64N
-9x4+72xscN3MxzvjKGUBgPDmRfR9Tp347j42HUCjmF5sTa7DzGMrU7I3gCmi7B3D
-zbkgdTwpucH2JDqHQPv+7PLaNyuZNEmiXM76DPyMypxMrtGrq/FDVJ7JwF+cSwbY
-WVfzbmOfHG7g6hRw7Bap/NNjcdtP09hRPG/g2WDy4z0Ay8MTZVe95EHTsyeR+kpv
-0f60eUI0cV7EovbLmp10I3RdsxbWTjbeFmNjM7WmmmsFRzA1jMlFGil/po4mJvMF
-Bcqbi4kUhQ49F4tRUlHRG1b/up71tDuzToF0YmN9GHkf/kt7/noVTYdEsm4RwaeF
-mhoaTMFaNaHGTHSyqroqbBCqlkfTqB1Cqw1weGqV6bGfaYpCJGx5vXmr06mh5dwo
-zvpyHQKCQu96a0G81T526RtVeA4QR89ELa0JSBpWR9MqVZKBte9AgS5vlF0386uM
-vcKC3zJ4srv1YrTOmMkLktNJHsyfLQgb70RdHR38hDEwKaq6VDWiewKDhsWAI5SJ
-wRgjAYspsNUVahDWvpXq/bRGM3JTW+QxiR22vgEitvKeIysLAgMBAAGjYzBhMB0G
-A1UdDgQWBBRXgQcc6LQCpAiPggyM8QVbd9VLxDAfBgNVHSMEGDAWgBRXgQcc6LQC
-pAiPggyM8QVbd9VLxDAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBhjAN
-BgkqhkiG9w0BAQsFAAOCAgEAjo/Fj7iTOr1/nTvZpeaon0/xY4D+Hf83FW/4yASZ
-Et0ITa510zIi8rIVvlaR1xdbXLYxHgdtm4vQtKZStwOBdwj+4VZrb9WgwQyBCYU5
-RqK387oMUeZdfsh9m2nqM8buYls3mldv34XUg8y1oytx6GDdC7NKz6PLNpIVkj5F
-aBnyfh43FsXHkzAy0nfkdE2mqfhQ4CD9Zkm9fJcX0inEmcspM5G8ba16uESZDqUS
-oJc1bgNtW64fL7pOtVfHDIJqKf/G/iIq1lk33gv5/4z6Z8e7fYVm1JabUUd9rZ6t
-cjXXFqkA7SkcXTs829/gaXQQv2FARt7g70UxJmNN0MCKfYnKM4dKddi934mTWrOI
-eLe0u3OAa1wZaHggJJXgRxMx/acWnGfersTpsAB1XG74XTSXHV7zHHnNWXjQ+gu0
-N4RAkQFMYWqp6KoHgQrdQfLPcaw0wc+ZMJj35z50b4ab+Bygthx3W+v/MiMFK9Wv
-/AsQCGslDcGWbFCYP7IvHDfownIFGefMnOm41NKWus9z6HoEUmfJiiSSVxECDT/2
-fE7M+sQovdrlHx7ru/fO6PP+6ocUE1afY6cHUzE0Dhv6xMcdvwL7COGd5ZU1bqAQ
-TqbePM5Kpk1ytkigdixzMDz/HFum0fdGfc/59Ll+f6+uHAX5NpOJZkBHBCWAoCeX
-bsg=
------END CERTIFICATE-----
diff --git a/hostsidetests/devicepolicy/app/DeviceOwner/assets/user-cert-chain.key b/hostsidetests/devicepolicy/app/DeviceOwner/assets/user-cert-chain.key
deleted file mode 100644
index 8bb399e..0000000
--- a/hostsidetests/devicepolicy/app/DeviceOwner/assets/user-cert-chain.key
+++ /dev/null
Binary files differ
diff --git a/hostsidetests/devicepolicy/app/DeviceOwner/src/com/android/cts/deviceowner/BasicAdminReceiver.java b/hostsidetests/devicepolicy/app/DeviceOwner/src/com/android/cts/deviceowner/BasicAdminReceiver.java
index a46e83be..37b3ed7 100644
--- a/hostsidetests/devicepolicy/app/DeviceOwner/src/com/android/cts/deviceowner/BasicAdminReceiver.java
+++ b/hostsidetests/devicepolicy/app/DeviceOwner/src/com/android/cts/deviceowner/BasicAdminReceiver.java
@@ -19,8 +19,6 @@
 import android.content.ComponentName;
 import android.content.Context;
 import android.content.Intent;
-import android.net.Uri;
-import android.os.Process;
 import android.os.UserHandle;
 import androidx.localbroadcastmanager.content.LocalBroadcastManager;
 
@@ -42,16 +40,6 @@
     }
 
     @Override
-    public String onChoosePrivateKeyAlias(Context context, Intent intent, int uid, Uri uri,
-            String suggestedAlias) {
-        super.onChoosePrivateKeyAlias(context, intent, uid, uri, suggestedAlias);
-        if (uid != Process.myUid() || uri == null) {
-            return null;
-        }
-        return uri.getQueryParameter("alias");
-    }
-
-    @Override
     public void onUserAdded(Context context, Intent intent, UserHandle userHandle) {
         super.onUserAdded(context, intent, userHandle);
         sendUserBroadcast(context, ACTION_USER_ADDED, userHandle);
diff --git a/hostsidetests/devicepolicy/app/ProfileOwner/src/com/android/cts/profileowner/AppUsageObserverTest.java b/hostsidetests/devicepolicy/app/ProfileOwner/src/com/android/cts/profileowner/AppUsageObserverTest.java
new file mode 100644
index 0000000..533e925
--- /dev/null
+++ b/hostsidetests/devicepolicy/app/ProfileOwner/src/com/android/cts/profileowner/AppUsageObserverTest.java
@@ -0,0 +1,72 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.cts.profileowner;
+
+import android.app.PendingIntent;
+import android.app.usage.UsageStatsManager;
+import android.content.Intent;
+import android.support.test.InstrumentationRegistry;
+
+import java.util.concurrent.TimeUnit;
+
+public class AppUsageObserverTest extends BaseProfileOwnerTest {
+
+    static final int OBSERVER_LIMIT = 1000;
+
+    public void testMinTimeLimit() throws Exception {
+        final String[] packages = {"not.real.package.name"};
+        final int obsId = 0;
+        UsageStatsManager usm = mContext.getSystemService(UsageStatsManager.class);
+
+        Intent intent = new Intent(Intent.ACTION_MAIN);
+        PendingIntent pendingIntent = PendingIntent.getActivity(
+                InstrumentationRegistry.getContext(),
+                1, intent, 0);
+
+        usm.registerAppUsageObserver(obsId, packages, 60, TimeUnit.SECONDS, pendingIntent);
+        usm.unregisterAppUsageObserver(obsId);
+        try {
+            usm.registerAppUsageObserver(obsId, packages, 59, TimeUnit.SECONDS, pendingIntent);
+            fail("Should have thrown an IllegalArgumentException");
+        } catch (IllegalArgumentException expected) {
+            // Do nothing. Exception is expected.
+        }
+    }
+
+    public void testObserverLimit() throws Exception {
+        final String[] packages = {"not.real.package.name"};
+        UsageStatsManager usm = mContext.getSystemService(UsageStatsManager.class);
+
+        Intent intent = new Intent(Intent.ACTION_MAIN);
+        PendingIntent pendingIntent = PendingIntent.getActivity(
+                InstrumentationRegistry.getContext(),
+                1, intent, 0);
+
+        for (int obsId = 0; obsId < OBSERVER_LIMIT; obsId++) {
+            usm.registerAppUsageObserver(obsId, packages, 60, TimeUnit.MINUTES, pendingIntent);
+        }
+        try {
+            usm.registerAppUsageObserver(OBSERVER_LIMIT, packages, 60, TimeUnit.MINUTES,
+                    pendingIntent);
+            fail("Should have thrown an IllegalStateException");
+        } catch (IllegalStateException expected) {
+            // Do nothing. Exception is expected.
+        }
+        for (int obsId = 0; obsId < OBSERVER_LIMIT; obsId++) {
+            usm.unregisterAppUsageObserver(obsId);
+        }
+    }
+}
diff --git a/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/DeviceAndProfileOwnerTest.java b/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/DeviceAndProfileOwnerTest.java
index 3edfdbd..fbe75d2 100644
--- a/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/DeviceAndProfileOwnerTest.java
+++ b/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/DeviceAndProfileOwnerTest.java
@@ -898,6 +898,23 @@
         runDeviceTestsAsUser(DEVICE_ADMIN_PKG, className, mUserId);
     }
 
+    public void testKeyManagement() throws Exception {
+        if (!mHasFeature) {
+            return;
+        }
+
+        try {
+            // Set a non-empty device lockscreen password, which is a precondition for installing
+            // CA certificates.
+            changeUserCredential("1234", null, mUserId);
+            // Verify the credential immediately to unlock the work profile challenge
+            verifyUserCredential("1234", mUserId);
+            executeDeviceTestClass(".KeyManagementTest");
+        } finally {
+            changeUserCredential(null, "1234", mUserId);
+        }
+    }
+
     /**
      * Executes a test class on device. Prior to running, turn off background data usage
      * restrictions, and restore the original restrictions after the test.
diff --git a/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/DeviceOwnerTest.java b/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/DeviceOwnerTest.java
index 25627ee..4b68e3a 100644
--- a/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/DeviceOwnerTest.java
+++ b/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/DeviceOwnerTest.java
@@ -120,16 +120,6 @@
         executeDeviceOwnerTest("DeviceOwnerSetupTest");
     }
 
-    public void testKeyManagement() throws Exception {
-        try {
-            changeUserCredential("1234", null, mPrimaryUserId);
-
-            executeDeviceOwnerTest("KeyManagementTest");
-        } finally {
-            changeUserCredential(null, "1234", mPrimaryUserId);
-        }
-    }
-
     public void testLockScreenInfo() throws Exception {
         executeDeviceOwnerTest("LockScreenInfoTest");
     }
diff --git a/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/ProfileOwnerTest.java b/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/ProfileOwnerTest.java
index 4f72186..e9feb3e 100644
--- a/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/ProfileOwnerTest.java
+++ b/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/ProfileOwnerTest.java
@@ -67,6 +67,13 @@
         executeProfileOwnerTest("AdminActionBookkeepingTest");
     }
 
+    public void testAppUsageObserver() throws Exception {
+        if (!mHasFeature) {
+            return;
+        }
+        executeProfileOwnerTest("AppUsageObserverTest");
+    }
+
     @Override
     protected void tearDown() throws Exception {
         if (mHasFeature) {
diff --git a/hostsidetests/incident/apps/storagedapp/Android.mk b/hostsidetests/dumpsys/apps/storagedapp/Android.mk
similarity index 100%
rename from hostsidetests/incident/apps/storagedapp/Android.mk
rename to hostsidetests/dumpsys/apps/storagedapp/Android.mk
diff --git a/hostsidetests/incident/apps/storagedapp/AndroidManifest.xml b/hostsidetests/dumpsys/apps/storagedapp/AndroidManifest.xml
similarity index 100%
rename from hostsidetests/incident/apps/storagedapp/AndroidManifest.xml
rename to hostsidetests/dumpsys/apps/storagedapp/AndroidManifest.xml
diff --git a/hostsidetests/incident/apps/storagedapp/src/com/android/server/cts/storaged/SimpleIOActivity.java b/hostsidetests/dumpsys/apps/storagedapp/src/com/android/server/cts/storaged/SimpleIOActivity.java
similarity index 100%
rename from hostsidetests/incident/apps/storagedapp/src/com/android/server/cts/storaged/SimpleIOActivity.java
rename to hostsidetests/dumpsys/apps/storagedapp/src/com/android/server/cts/storaged/SimpleIOActivity.java
diff --git a/hostsidetests/incident/apps/storagedapp/src/com/android/server/cts/storaged/SimpleIOService.java b/hostsidetests/dumpsys/apps/storagedapp/src/com/android/server/cts/storaged/SimpleIOService.java
similarity index 68%
rename from hostsidetests/incident/apps/storagedapp/src/com/android/server/cts/storaged/SimpleIOService.java
rename to hostsidetests/dumpsys/apps/storagedapp/src/com/android/server/cts/storaged/SimpleIOService.java
index a64d1cf..a5df56a 100644
--- a/hostsidetests/incident/apps/storagedapp/src/com/android/server/cts/storaged/SimpleIOService.java
+++ b/hostsidetests/dumpsys/apps/storagedapp/src/com/android/server/cts/storaged/SimpleIOService.java
@@ -24,8 +24,11 @@
 import android.os.Looper;
 import android.os.Message;
 import android.os.Process;
+import android.util.Log;
 
+import java.io.BufferedReader;
 import java.io.File;
+import java.io.FileReader;
 import java.io.FileWriter;
 import java.io.IOException;
 
@@ -34,8 +37,40 @@
     private ServiceHandler mServiceHandler;
 
     private final class ServiceHandler extends Handler {
+        private String getCgroupCpuset() {
+            File cgroup = new File("/proc/self/cgroup");
+            try (BufferedReader br = new BufferedReader(new FileReader(cgroup))) {
+                String line;
+                while ((line = br.readLine()) != null) {
+                    String[] parts = line.split(":");
+                    if (parts.length >= 3 && parts[1].equals("cpuset")) {
+                        return parts[2];
+                    }
+                }
+            } catch (IOException e) {
+            }
+            return null;
+        }
+
         public ServiceHandler(Looper looper) {
             super(looper);
+
+            // Spin for 20 seconds until we are not in the foreground. (Note
+            // that UsageStatsService considers "foreground" to be in the
+            // background - only top and persistent processes are reported as
+            // foreground for uid_io).
+            for (int i = 1; i <= 200; i++) {
+                String cpuset = getCgroupCpuset();
+                if (cpuset == null || !cpuset.equals("/top")) {
+                    break;
+                }
+                try {
+                    Thread.sleep(100);
+                } catch (InterruptedException e) {
+                }
+            }
+
+            Log.i("SimpleIOService", "cgroup:" + getCgroupCpuset());
         }
 
         @Override
diff --git a/hostsidetests/incident/apps/storagedapp/src/com/android/server/cts/storaged/StoragedTest.java b/hostsidetests/dumpsys/apps/storagedapp/src/com/android/server/cts/storaged/StoragedTest.java
similarity index 100%
rename from hostsidetests/incident/apps/storagedapp/src/com/android/server/cts/storaged/StoragedTest.java
rename to hostsidetests/dumpsys/apps/storagedapp/src/com/android/server/cts/storaged/StoragedTest.java
diff --git a/hostsidetests/dumpsys/src/android/dumpsys/cts/StoragedDumpsysTest.java b/hostsidetests/dumpsys/src/android/dumpsys/cts/StoragedDumpsysTest.java
index 34da3b6..3885f0a 100644
--- a/hostsidetests/dumpsys/src/android/dumpsys/cts/StoragedDumpsysTest.java
+++ b/hostsidetests/dumpsys/src/android/dumpsys/cts/StoragedDumpsysTest.java
@@ -20,6 +20,10 @@
 
 import java.io.BufferedReader;
 import java.io.StringReader;
+import java.util.Date;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+import java.text.SimpleDateFormat;
 
 /**
  * Test to check the format of the dumps of the processstats test.
@@ -34,6 +38,21 @@
         getDevice().uninstallPackage(DEVICE_SIDE_TEST_PACKAGE);
     }
 
+    private String getCgroupFromLog(String log) {
+        Pattern pattern = Pattern.compile("cgroup:([^\\s]+)", Pattern.MULTILINE);
+        Matcher matcher = pattern.matcher(log);
+        if (matcher.find()) {
+            return matcher.group(1);
+        }
+        return null;
+    }
+
+    private String getCurrentLogcatDate() throws Exception {
+        long timestampMs = getDevice().getDeviceDate();
+        return new SimpleDateFormat("MM-dd HH:mm:ss.SSS")
+            .format(new Date(timestampMs));
+    }
+
     /**
      * Tests the output of "dumpsys storaged --force --hours 0.01".
      *
@@ -54,9 +73,18 @@
 
         mDevice.executeShellCommand("dumpsys storaged --force");
 
+        String logcatDate = getCurrentLogcatDate();
+
         runDeviceTests(DEVICE_SIDE_TEST_PACKAGE,
                 "com.android.server.cts.storaged.StoragedTest",
                 "testBackgroundIO");
+        String log = mDevice.executeAdbCommand(
+                "logcat", "-v", "brief", "-d", "-t", logcatDate,
+                "SimpleIOService:I", "*:S");
+        String serviceCgroup = getCgroupFromLog(log);
+        if (serviceCgroup != null && serviceCgroup.equals("/top")) {
+            System.out.println("WARNING: Service was not in the correct cgroup; ActivityManager may be unresponsive.");
+        }
 
         runDeviceTests(DEVICE_SIDE_TEST_PACKAGE,
                 "com.android.server.cts.storaged.StoragedTest",
@@ -94,8 +122,14 @@
                 }
 
                 if (parts[0].equals(DEVICE_SIDE_TEST_PACKAGE)) {
-                    assertTrue((Integer.parseInt(parts[6]) >= 4096 && Integer.parseInt(parts[8]) >= 4096) ||
-                                Integer.parseInt(parts[8]) >= 8192);
+                    if (Integer.parseInt(parts[6]) >= 8192 && Integer.parseInt(parts[8]) == 0) {
+                        System.out.print("WARNING: Background I/O was attributed to the "
+                                + "foreground. This could indicate a broken or malfunctioning "
+                                + "ActivityManager or UsageStatsService.\n");
+                    } else {
+                        assertTrue((Integer.parseInt(parts[6]) >= 4096 && Integer.parseInt(parts[8]) >= 4096) ||
+                                    Integer.parseInt(parts[8]) >= 8192);
+                    }
                     hasTestIO = true;
                 }
             }
diff --git a/hostsidetests/harmfulappwarning/src/android/harmfulappwarning/cts/HarmfulAppWarningTest.java b/hostsidetests/harmfulappwarning/src/android/harmfulappwarning/cts/HarmfulAppWarningTest.java
index 09cfd8b..c93404d 100644
--- a/hostsidetests/harmfulappwarning/src/android/harmfulappwarning/cts/HarmfulAppWarningTest.java
+++ b/hostsidetests/harmfulappwarning/src/android/harmfulappwarning/cts/HarmfulAppWarningTest.java
@@ -33,6 +33,7 @@
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertNull;
 import static org.junit.Assert.assertTrue;
+import static org.junit.Assume.assumeFalse;
 
 /**
  * Host-side tests for the harmful app launch warning
@@ -53,6 +54,8 @@
 @RunWith(DeviceJUnit4ClassRunner.class)
 public class HarmfulAppWarningTest extends BaseHostJUnit4Test {
 
+    private static final String FEATURE_WEARABLE = "android.hardware.type.watch";
+
     private static final String TEST_APP_PACKAGE_NAME = "android.harmfulappwarning.sampleapp";
     private static final String TEST_APP_ACTIVITY_CLASS_NAME = "SampleDeviceActivity";
     private static final String TEST_APP_LAUNCHED_STRING = "Sample activity started.";
@@ -75,6 +78,10 @@
         installPackage("CtsHarmfulAppWarningSampleApp.apk");
         mDevice = getDevice();
         mDevice.clearLogcat();
+
+        // Skip the tests for wearable devices. This feature is not used on wearable
+        // devices, for now (no wearable UI, etc.)
+        assumeFalse(hasFeature(FEATURE_WEARABLE));
     }
 
     private void runDeviceTest(String testName) throws DeviceNotAvailableException {
@@ -148,4 +155,8 @@
         verifyHarmfulAppWarningSet();
         verifySampleAppInstalled();
     }
+
+    protected boolean hasFeature(String featureName) throws DeviceNotAvailableException {
+        return getDevice().executeShellCommand("pm list features").contains(featureName);
+    }
 }
diff --git a/hostsidetests/incident/apps/batterystatsapp/src/com/android/server/cts/device/batterystats/BatteryStatsProcessStateTests.java b/hostsidetests/incident/apps/batterystatsapp/src/com/android/server/cts/device/batterystats/BatteryStatsProcessStateTests.java
index 1f7516f..5c72aa4 100644
--- a/hostsidetests/incident/apps/batterystatsapp/src/com/android/server/cts/device/batterystats/BatteryStatsProcessStateTests.java
+++ b/hostsidetests/incident/apps/batterystatsapp/src/com/android/server/cts/device/batterystats/BatteryStatsProcessStateTests.java
@@ -37,7 +37,7 @@
         intent.setClass(mContext, SimpleForegroundService.class);
         Log.i(TAG, "Starting foreground service.");
         mContext.startForegroundService(intent);
-        Thread.sleep(3000);
+        Thread.sleep(2000);
     }
 
     @Test
diff --git a/hostsidetests/incident/apps/errorsapp/src/com/android/server/cts/errors/ErrorsTests.java b/hostsidetests/incident/apps/errorsapp/src/com/android/server/cts/errors/ErrorsTests.java
index 4b58cf5..f5ce5d9 100644
--- a/hostsidetests/incident/apps/errorsapp/src/com/android/server/cts/errors/ErrorsTests.java
+++ b/hostsidetests/incident/apps/errorsapp/src/com/android/server/cts/errors/ErrorsTests.java
@@ -42,7 +42,7 @@
 
     private static final String CRASH_TAG = "data_app_crash";
     private static final String ANR_TAG = "data_app_anr";
-    private static final String NATIVE_CRASH_TAG = "SYSTEM_TOMBSTONE";
+    private static final String NATIVE_CRASH_TAG = "data_app_native_crash";
 
     private static final int TIMEOUT_SECS = 60 * 3;
 
diff --git a/hostsidetests/incident/src/com/android/server/cts/BatteryStatsValidationTest.java b/hostsidetests/incident/src/com/android/server/cts/BatteryStatsValidationTest.java
index 9379bb6..02f6687 100644
--- a/hostsidetests/incident/src/com/android/server/cts/BatteryStatsValidationTest.java
+++ b/hostsidetests/incident/src/com/android/server/cts/BatteryStatsValidationTest.java
@@ -272,6 +272,8 @@
 
         batteryOnScreenOff();
         installPackage(DEVICE_SIDE_TEST_APK, true);
+        turnScreenOnForReal();
+        assertScreenOn();
 
         // Background test.
         executeBackground(ACTION_BLE_SCAN_UNOPTIMIZED, 40_000);
@@ -293,7 +295,8 @@
         }
         batteryOnScreenOff();
         installPackage(DEVICE_SIDE_TEST_APK, true);
-
+        turnScreenOnForReal();
+        assertScreenOn();
         // Ble scan time in BatteryStatsBgVsFgActions is 2 seconds, but be lenient.
         final int minTime = 1500; // min single scan time in ms
         final int maxTime = 3000; // max single scan time in ms
@@ -370,6 +373,8 @@
         }
         batteryOnScreenOff();
         installPackage(DEVICE_SIDE_TEST_APK, true);
+        turnScreenOnForReal();
+        assertScreenOn();
         allowImmediateSyncs();
 
         // Background test.
@@ -391,6 +396,8 @@
         }
         batteryOnScreenOff();
         installPackage(DEVICE_SIDE_TEST_APK, true);
+        turnScreenOnForReal();
+        assertScreenOn();
         allowImmediateSyncs();
 
         // Background test.
@@ -414,6 +421,8 @@
 
         batteryOnScreenOff();
         installPackage(DEVICE_SIDE_TEST_APK, true);
+        turnScreenOnForReal();
+        assertScreenOn();
         // Whitelist this app against background wifi scan throttling
         getDevice().executeShellCommand(String.format(
                 "settings put global wifi_scan_background_throttle_package_whitelist %s",
diff --git a/hostsidetests/incident/src/com/android/server/cts/IncidentdIsolatedTest.java b/hostsidetests/incident/src/com/android/server/cts/IncidentdIsolatedTest.java
deleted file mode 100644
index 98e4b7a..0000000
--- a/hostsidetests/incident/src/com/android/server/cts/IncidentdIsolatedTest.java
+++ /dev/null
@@ -1,72 +0,0 @@
-/*
- * Copyright (C) 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.android.server.cts;
-
-import android.os.IncidentProto;
-import com.android.ddmlib.Log.LogLevel;
-import com.android.tradefed.log.LogUtil.CLog;
-
-/**
- * Tests incidentd works when system_server is crashed.
- */
-public class IncidentdIsolatedTest extends ProtoDumpTestCase {
-    private static final String TAG = "IncidentdIsolatedTest";
-
-    private static final String SYSTEM_SERVER = "system_server";
-    private static final String CMD_TOP = "top -b -n 1 -o cmd";
-
-    @Override
-    protected void setUp() throws Exception {
-        super.setUp();
-        if (execCommandAndFind(CMD_TOP, SYSTEM_SERVER) != null) {
-            CLog.logAndDisplay(LogLevel.INFO, "stop server");
-            getDevice().executeShellCommand("stop");
-            Thread.sleep(10000); // wait for 10 seconds to stop.
-            assertTrue("system_server failed to stop",
-                    !execCommandAndGet(CMD_TOP).contains(SYSTEM_SERVER));
-        }
-    }
-
-    @Override
-    protected void tearDown() throws Exception {
-        super.tearDown();
-        if (!execCommandAndGet(CMD_TOP).contains(SYSTEM_SERVER)) {
-            CLog.logAndDisplay(LogLevel.INFO, "start server");
-            getDevice().executeShellCommand("start");
-            Thread.sleep(10000); // wait for 10 seconds to boot.
-            execCommandAndFind(CMD_TOP, SYSTEM_SERVER);
-        }
-    }
-
-    public void testFullReportParsable() throws Exception {
-        final IncidentProto dump = getDump(IncidentProto.parser(), "incident 2>/dev/null");
-        assertTrue(dump.toByteArray().length > 0);
-        assertTrue(dump.hasSystemProperties());
-        assertTrue(dump.hasEventLogTagMap());
-        assertTrue(dump.hasPageTypeInfo());
-        assertTrue(dump.hasKernelWakeSources());
-        assertTrue(dump.hasCpuInfo());
-        assertTrue(dump.hasCpuFreq());
-        assertTrue(dump.hasProcessesAndThreads());
-    }
-
-    public void testReportInPrivateDirectory() throws Exception {
-        assertTrue(execCommandAndGet("ls /data/misc/incidents").isEmpty());
-        assertTrue(execCommandAndGet("incident -d 1000 2>/dev/null").isEmpty());
-        Thread.sleep(5000); // wait for report to finish.
-        execCommandAndFind("ls /data/misc/incidents", "incident-");
-    }
-}
diff --git a/hostsidetests/net/src/com/android/cts/net/NetPolicyTestsPreparer.java b/hostsidetests/net/src/com/android/cts/net/NetPolicyTestsPreparer.java
index 9b19554..ca14c27 100644
--- a/hostsidetests/net/src/com/android/cts/net/NetPolicyTestsPreparer.java
+++ b/hostsidetests/net/src/com/android/cts/net/NetPolicyTestsPreparer.java
@@ -25,50 +25,38 @@
 
 public class NetPolicyTestsPreparer implements ITargetPreparer, ITargetCleaner {
     private final static String KEY_PAROLE_DURATION = "parole_duration";
-    private final static String DESIRED_PAROLE_DURATION = "0";
+    private final static int DESIRED_PAROLE_DURATION = 0;
+    private final static String KEY_STABLE_CHARGING_THRESHOLD = "stable_charging_threshold";
+    private final static int DESIRED_STABLE_CHARGING_THRESHOLD = 0;
 
-    private boolean mAppIdleConstsUpdated;
+    private ITestDevice mDevice;
     private String mOriginalAppIdleConsts;
 
     @Override
     public void setUp(ITestDevice device, IBuildInfo buildInfo) throws DeviceNotAvailableException {
-        updateParoleDuration(device);
+        mDevice = device;
+        mOriginalAppIdleConsts = getAppIdleConstants();
+        setAppIdleConstants(KEY_PAROLE_DURATION + "=" + DESIRED_PAROLE_DURATION + ","
+                + KEY_STABLE_CHARGING_THRESHOLD + "=" + DESIRED_STABLE_CHARGING_THRESHOLD);
         LogUtil.CLog.d("Original app_idle_constants: " + mOriginalAppIdleConsts);
     }
 
     @Override
     public void tearDown(ITestDevice device, IBuildInfo buildInfo, Throwable throwable)
             throws DeviceNotAvailableException {
-        if (mAppIdleConstsUpdated) {
-            executeCmd(device, "settings put global app_idle_constants " + mOriginalAppIdleConsts);
-        }
+        setAppIdleConstants(mOriginalAppIdleConsts);
     }
 
-    /**
-     * Updates parole_duration with the desired value.
-     */
-    private void updateParoleDuration(ITestDevice device) throws DeviceNotAvailableException {
-        mOriginalAppIdleConsts = executeCmd(device, "settings get global app_idle_constants");
-        String newAppIdleConstants;
-        final String newConstant = KEY_PAROLE_DURATION + "=" + DESIRED_PAROLE_DURATION;
-        if (mOriginalAppIdleConsts == null || "null".equals(mOriginalAppIdleConsts)) {
-            // app_idle_constants is initially empty, so just assign the desired value.
-            newAppIdleConstants = newConstant;
-        } else if (mOriginalAppIdleConsts.contains(KEY_PAROLE_DURATION)) {
-            // app_idle_constants contains parole_duration, so replace it with the desired value.
-            newAppIdleConstants = mOriginalAppIdleConsts.replaceAll(
-                    KEY_PAROLE_DURATION + "=\\d+", newConstant);
-        } else {
-            // app_idle_constants didn't have parole_duration, so append the desired value.
-            newAppIdleConstants = mOriginalAppIdleConsts + "," + newConstant;
-        }
-        executeCmd(device, "settings put global app_idle_constants " + newAppIdleConstants);
-        mAppIdleConstsUpdated = true;
+    private void setAppIdleConstants(String appIdleConstants) throws DeviceNotAvailableException {
+        executeCmd("settings put global app_idle_constants " + appIdleConstants);
     }
 
-    private String executeCmd(ITestDevice device, String cmd)
-            throws DeviceNotAvailableException {
-        final String output = device.executeShellCommand(cmd).trim();
+    private String getAppIdleConstants() throws DeviceNotAvailableException {
+        return executeCmd("settings get global app_idle_constants");
+    }
+
+    private String executeCmd(String cmd) throws DeviceNotAvailableException {
+        final String output = mDevice.executeShellCommand(cmd).trim();
         LogUtil.CLog.d("Output for '%s': %s", cmd, output);
         return output;
     }
diff --git a/hostsidetests/security/AndroidTest.xml b/hostsidetests/security/AndroidTest.xml
index 7305537..bc1baa1 100755
--- a/hostsidetests/security/AndroidTest.xml
+++ b/hostsidetests/security/AndroidTest.xml
@@ -68,7 +68,6 @@
         <!-- Bulletin 2017-03 -->
         <!-- Please add tests solely from this bulletin below to avoid merge conflict -->
         <option name="push" value="CVE-2017-0479->/data/local/tmp/CVE-2017-0479" />
-        <option name="push" value="CVE-2017-0334->/data/local/tmp/CVE-2017-0334" />
         <option name="push" value="CVE-2016-8479->/data/local/tmp/CVE-2016-8479" />
         <option name="push" value="CVE-2017-0508->/data/local/tmp/CVE-2017-0508" />
         <option name="push" value="CVE-2017-0333->/data/local/tmp/CVE-2017-0333" />
diff --git a/hostsidetests/security/securityPatch/CVE-2016-2471/Android.mk b/hostsidetests/security/securityPatch/CVE-2016-2471/Android.mk
index 1c766d0..ff70aa1 100755
--- a/hostsidetests/security/securityPatch/CVE-2016-2471/Android.mk
+++ b/hostsidetests/security/securityPatch/CVE-2016-2471/Android.mk
@@ -22,7 +22,7 @@
 LOCAL_MODULE_STEM_64 := $(LOCAL_MODULE)64
 
 # Tag this module as a cts test artifact
-LOCAL_COMPATIBILITY_SUITE := cts sts
+LOCAL_COMPATIBILITY_SUITE := cts vts sts
 LOCAL_CTS_TEST_PACKAGE := android.security.cts
 
 LOCAL_ARM_MODE := arm
diff --git a/hostsidetests/security/securityPatch/CVE-2016-2504/Android.mk b/hostsidetests/security/securityPatch/CVE-2016-2504/Android.mk
index 058e3ee..51e6dd8 100644
--- a/hostsidetests/security/securityPatch/CVE-2016-2504/Android.mk
+++ b/hostsidetests/security/securityPatch/CVE-2016-2504/Android.mk
@@ -22,7 +22,7 @@
 LOCAL_MODULE_STEM_64 := $(LOCAL_MODULE)64
 
 # Tag this module as a cts test artifact
-LOCAL_COMPATIBILITY_SUITE := cts sts
+LOCAL_COMPATIBILITY_SUITE := cts vts sts
 LOCAL_CTS_TEST_PACKAGE := android.security.cts
 
 
diff --git a/hostsidetests/security/securityPatch/CVE-2017-0479/Android.mk b/hostsidetests/security/securityPatch/CVE-2017-0479/Android.mk
deleted file mode 100644
index 264200d..0000000
--- a/hostsidetests/security/securityPatch/CVE-2017-0479/Android.mk
+++ /dev/null
@@ -1,37 +0,0 @@
-# Copyright (C) 2018 The Android Open Source Project
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-#      http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-LOCAL_PATH := $(call my-dir)
-
-include $(CLEAR_VARS)
-LOCAL_MODULE := CVE-2017-0479
-LOCAL_SRC_FILES := poc.cpp
-LOCAL_MULTILIB := both
-LOCAL_MODULE_STEM_32 := $(LOCAL_MODULE)32
-LOCAL_MODULE_STEM_64 := $(LOCAL_MODULE)64
-
-LOCAL_SHARED_LIBRARIES := libmedia libutils libbinder libandroid libaudioclient
-LOCAL_C_INCLUDES:= \
-        $(TOP)/frameworks/av/include/media/ \
-        $(TOP)/frameworks/av/services/ \
-        $(TOP)/system/media/audio_utils/include/ \
-        $(TOP)/external/sonic/
-
-# Tag this module as a sts test artifact
-LOCAL_COMPATIBILITY_SUITE := cts vts sts
-LOCAL_STS_TEST_PACKAGE := android.security.cts
-
-LOCAL_ARM_MODE := arm
-LOCAL_CPPFLAGS = -Wall -Werror
-include $(BUILD_CTS_EXECUTABLE)
diff --git a/hostsidetests/security/securityPatch/CVE-2017-0479/poc.cpp b/hostsidetests/security/securityPatch/CVE-2017-0479/poc.cpp
deleted file mode 100644
index d3e5892..0000000
--- a/hostsidetests/security/securityPatch/CVE-2017-0479/poc.cpp
+++ /dev/null
@@ -1,93 +0,0 @@
-/**
- * Copyright (C) 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-#include <sys/types.h>
-#include <sys/wait.h>
-#include <stdlib.h>
-#include <audioflinger/AudioFlinger.h>
-#include <hardware/audio_effect.h>
-#include <media/IAudioFlinger.h>
-#include <media/IEffect.h>
-#include <media/IEffectClient.h>
-
-using namespace android;
-
-struct EffectClient : public android::BnEffectClient {
-  EffectClient() {}
-  virtual void controlStatusChanged(bool controlGranted __unused) {}
-  virtual void enableStatusChanged(bool enabled __unused) {}
-  virtual void commandExecuted(uint32_t cmdCode __unused,
-                               uint32_t cmdSize __unused,
-                               void *pCmdData __unused,
-                               uint32_t replySize __unused,
-                               void *pReplyData __unused) {}
-};
-
-sp<IEffect> gEffect;
-
-void *disconnectThread(void *) {
-  usleep(5);
-  if (gEffect != NULL && gEffect.get() != NULL) {
-    gEffect->disconnect();
-  }
-  return NULL;
-}
-
-int main() {
-  static const effect_uuid_t EFFECT_UIID_EQUALIZER = {
-      0x0bed4300, 0xddd6, 0x11db, 0x8f34, {0x00, 0x02, 0xa5, 0xd5, 0xc5, 0x1b}};
-
-  effect_descriptor_t descriptor;
-  memset(&descriptor, 0, sizeof(descriptor));
-  descriptor.type = EFFECT_UIID_EQUALIZER;
-  descriptor.uuid = *EFFECT_UUID_NULL;
-  sp<EffectClient> effectClient(new EffectClient());
-
-  const int32_t priority = 0;
-  audio_session_t sessionId = (audio_session_t)(128);
-  const audio_io_handle_t io = AUDIO_IO_HANDLE_NONE;
-  const String16 opPackageName("com.exp.poc");
-  int32_t id;
-  int enabled;
-  status_t err;
-
-  uint32_t cmdCode, cmdSize, pReplySize;
-  int *pCmdData, *pReplyData;
-
-  cmdCode = EFFECT_CMD_GET_CONFIG;
-  cmdSize = 0;
-  pReplySize = sizeof(effect_config_t);
-  pCmdData = (int *)malloc(cmdSize);
-  pReplyData = (int *)malloc(pReplySize);
-
-  gEffect = NULL;
-  pthread_t pt;
-  const sp<IAudioFlinger> &audioFlinger = AudioSystem::get_audio_flinger();
-
-  while (1) {
-    gEffect = audioFlinger->createEffect(&descriptor, effectClient, priority,
-                                         io, sessionId, opPackageName, getpid(),
-                                         &err, &id, &enabled);
-    if (gEffect == NULL || err != NO_ERROR) {
-      return -1;
-    }
-    pthread_create(&pt, NULL, disconnectThread, NULL);
-    err = gEffect->command(cmdCode, cmdSize, (void *)pCmdData, &pReplySize,
-                           (void *)pReplyData);
-    usleep(50);
-  }
-  sleep(2);
-  return 0;
-}
diff --git a/hostsidetests/security/securityPatch/CVE-2017-13253/Android.mk b/hostsidetests/security/securityPatch/CVE-2017-13253/Android.mk
index e5a2d2a..e2a5083 100644
--- a/hostsidetests/security/securityPatch/CVE-2017-13253/Android.mk
+++ b/hostsidetests/security/securityPatch/CVE-2017-13253/Android.mk
@@ -25,7 +25,7 @@
 
 LOCAL_SHARED_LIBRARIES := libmedia libutils libbinder libmediadrm
 
-LOCAL_COMPATIBILITY_SUITE := cts sts
+LOCAL_COMPATIBILITY_SUITE := cts vts sts
 LOCAL_CTS_TEST_PACKAGE := android.security.cts
 
 LOCAL_ARM_MODE := arm
diff --git a/hostsidetests/security/src/android/security/cts/AdbUtils.java b/hostsidetests/security/src/android/security/cts/AdbUtils.java
index ca32ad4..5ac0f87 100644
--- a/hostsidetests/security/src/android/security/cts/AdbUtils.java
+++ b/hostsidetests/security/src/android/security/cts/AdbUtils.java
@@ -209,7 +209,22 @@
       CollectingOutputReceiver receiver = new CollectingOutputReceiver();
       device.executeShellCommand("/data/local/tmp/" + pocName + " > /dev/null 2>&1; echo $?",
                                  receiver, timeout, TimeUnit.SECONDS, 0);
-      //Refer to go/asdl-sts-guide Test section for knowing the significance of 113 code
-      return Integer.parseInt(receiver.getOutput().replaceAll("[^0-9]", "")) == 113;
+
+      String returnStr = null;
+      int returnNum = 0;
+
+      try{
+           returnStr = receiver.getOutput().replaceAll("[^0-9]", "");
+       }catch(NullPointerException e){
+          return false;
+       }
+       try{
+         returnNum = Integer.parseInt(returnStr);
+       }catch(NumberFormatException e){
+          return false;
+       }
+
+       //Refer to go/asdl-sts-guide Test section for knowing the significance of 113 code
+       return returnNum == 113;
     }
 }
diff --git a/hostsidetests/security/src/android/security/cts/KernelConfigTest.java b/hostsidetests/security/src/android/security/cts/KernelConfigTest.java
index 0619ad1..536a41b 100644
--- a/hostsidetests/security/src/android/security/cts/KernelConfigTest.java
+++ b/hostsidetests/security/src/android/security/cts/KernelConfigTest.java
@@ -164,4 +164,20 @@
                     configSet.contains("CONFIG_CPU_SW_DOMAIN_PAN=y"));
         }
     }
+
+    /**
+     * Test that the kernel has KTPI enabled for architectures and kernel versions that support it.
+     *
+     * @throws Exception
+     */
+    @CddTest(requirement="9.7")
+    public void testConfigKTPI() throws Exception {
+        if (CpuFeatures.isArm64(mDevice) && !CpuFeatures.kernelVersionLessThan(mDevice, 4, 4)) {
+            assertTrue("Linux kernel must have KPTI enabled: CONFIG_UNMAP_KERNEL_AT_EL0=y",
+                    configSet.contains("CONFIG_UNMAP_KERNEL_AT_EL0=y"));
+        } else if (CpuFeatures.isX86(mDevice)) {
+            assertTrue("Linux kernel must have KPTI enabled: CONFIG_PAGE_TABLE_ISOLATION=y",
+                    configSet.contains("CONFIG_PAGE_TABLE_ISOLATION=y"));
+        }
+    }
 }
diff --git a/hostsidetests/security/src/android/security/cts/Poc17_03.java b/hostsidetests/security/src/android/security/cts/Poc17_03.java
index 80c959c..576ea5c 100644
--- a/hostsidetests/security/src/android/security/cts/Poc17_03.java
+++ b/hostsidetests/security/src/android/security/cts/Poc17_03.java
@@ -71,15 +71,4 @@
         }
     }
 
-    /**
-     * b/32707507
-     */
-    @SecurityTest
-    public void testPocCVE_2017_0479() throws Exception {
-        AdbUtils.runCommandLine("logcat -c" , getDevice());
-        AdbUtils.runPocNoOutput("CVE-2017-0479", getDevice(), 60);
-        String logcatOut = AdbUtils.runCommandLine("logcat -d", getDevice());
-        assertNotMatchesMultiLine(".*Fatal signal 11 \\(SIGSEGV\\).*>>> /system/bin/" +
-                         "audioserver <<<.*", logcatOut);
-    }
 }
diff --git a/hostsidetests/security/src/android/security/cts/SELinuxHostTest.java b/hostsidetests/security/src/android/security/cts/SELinuxHostTest.java
index 2052e8f..17ef0f9 100644
--- a/hostsidetests/security/src/android/security/cts/SELinuxHostTest.java
+++ b/hostsidetests/security/src/android/security/cts/SELinuxHostTest.java
@@ -1075,10 +1075,10 @@
         assertDomainOne("u:r:ueventd:s0", "/sbin/ueventd");
     }
 
-    /* Devices always have healthd */
+    /* healthd may or may not exist */
     @CddTest(requirement="9.7")
     public void testHealthdDomain() throws DeviceNotAvailableException {
-        assertDomainOne("u:r:healthd:s0", "/system/bin/healthd");
+        assertDomainZeroOrOne("u:r:healthd:s0", "/system/bin/healthd");
     }
 
     /* Servicemanager is always there */
diff --git a/hostsidetests/statsd/apps/statsdapp/AndroidManifest.xml b/hostsidetests/statsd/apps/statsdapp/AndroidManifest.xml
index bf24db0..1e86fa7 100644
--- a/hostsidetests/statsd/apps/statsdapp/AndroidManifest.xml
+++ b/hostsidetests/statsd/apps/statsdapp/AndroidManifest.xml
@@ -31,6 +31,7 @@
     <uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW" />
     <uses-permission android:name="android.permission.DUMP" /> <!-- must be granted via pm grant -->
     <uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
+    <uses-permission android:name="android.permission.CONFIGURE_DISPLAY_BRIGHTNESS" />
 
     <application android:label="@string/app_name">
         <uses-library android:name="android.test.runner" />
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 e5be5fc..719dcb7 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
@@ -26,6 +26,7 @@
 import android.bluetooth.BluetoothAdapter;
 import android.bluetooth.le.BluetoothLeScanner;
 import android.bluetooth.le.ScanCallback;
+import android.bluetooth.le.ScanFilter;
 import android.bluetooth.le.ScanResult;
 import android.bluetooth.le.ScanSettings;
 import android.content.BroadcastReceiver;
@@ -54,6 +55,7 @@
 import android.util.Log;
 import android.util.StatsLog;
 
+import static com.android.compatibility.common.util.SystemUtil.runShellCommand;
 import static org.junit.Assert.assertTrue;
 import static org.junit.Assert.fail;
 import org.junit.Test;
@@ -77,37 +79,28 @@
     }
 
     @Test
-    public void testAppBreadcrumbReported() {
-        StatsLog.logStart(1);
-        sleep(1_000);
-        StatsLog.logStop(1);
-        sleep(1_000);
-        StatsLog.logEvent(1);
-    }
-
-    @Test
     public void testBleScanOpportunistic() {
         ScanSettings scanSettings = new ScanSettings.Builder()
                 .setScanMode(ScanSettings.SCAN_MODE_OPPORTUNISTIC).build();
-        performBleScan(scanSettings, false);
+        performBleScan(scanSettings, null,false);
     }
 
     @Test
     public void testBleScanUnoptimized() {
         ScanSettings scanSettings = new ScanSettings.Builder()
                 .setScanMode(ScanSettings.SCAN_MODE_LOW_LATENCY).build();
-        performBleScan(scanSettings, false);
+        performBleScan(scanSettings, null, false);
     }
 
     @Test
     public void testBleScanResult() {
         ScanSettings scanSettings = new ScanSettings.Builder()
                 .setScanMode(ScanSettings.SCAN_MODE_LOW_LATENCY).build();
-        // TODO: Add an extremely weak ScanFilter to allow background ble scan results.
-        performBleScan(scanSettings, true);
+        ScanFilter.Builder scanFilter = new ScanFilter.Builder();
+        performBleScan(scanSettings, Arrays.asList(scanFilter.build()), true);
     }
 
-    private static void performBleScan(ScanSettings scanSettings, boolean waitForResult) {
+    private static void performBleScan(ScanSettings scanSettings, List<ScanFilter> scanFilters, boolean waitForResult) {
         BluetoothAdapter bluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
         if (bluetoothAdapter == null) {
             Log.e(TAG, "Device does not support Bluetooth");
@@ -146,7 +139,7 @@
             }
         };
 
-        bleScanner.startScan(null, scanSettings, scanCallback);
+        bleScanner.startScan(scanFilters, scanSettings, scanCallback);
         if (waitForResult) {
             waitForReceiver(InstrumentationRegistry.getContext(), 59_000, resultsLatch, null);
         } else {
@@ -275,6 +268,26 @@
     }
 
     @Test
+    public void testScreenBrightness() {
+        Context context = InstrumentationRegistry.getContext();
+        PowerManager pm = context.getSystemService(PowerManager.class);
+        PowerManager.WakeLock wl = pm.newWakeLock(PowerManager.SCREEN_BRIGHT_WAKE_LOCK |
+                PowerManager.ACQUIRE_CAUSES_WAKEUP, "StatsdBrightnessTest");
+        wl.acquire();
+        sleep(500);
+
+        setScreenBrightness(47);
+        sleep(500);
+        setScreenBrightness(100);
+        sleep(500);
+        setScreenBrightness(198);
+        sleep(500);
+
+
+        wl.release();
+    }
+
+    @Test
     public void testSyncState() throws Exception {
 
         Context context = InstrumentationRegistry.getContext();
@@ -457,4 +470,8 @@
             ctx.unregisterReceiver(receiver);
         }
     }
+
+    private static void setScreenBrightness(int brightness) {
+        runShellCommand("settings put system screen_brightness " + brightness);
+    }
 }
diff --git a/hostsidetests/statsd/src/android/cts/statsd/alarm/AlarmTests.java b/hostsidetests/statsd/src/android/cts/statsd/alarm/AlarmTests.java
index 38c35d0..da6a0a4 100644
--- a/hostsidetests/statsd/src/android/cts/statsd/alarm/AlarmTests.java
+++ b/hostsidetests/statsd/src/android/cts/statsd/alarm/AlarmTests.java
@@ -33,7 +33,7 @@
 
     private static final String TAG = "Statsd.AnomalyDetectionTests";
 
-    private static final boolean INCIDENTD_TESTS_ENABLED = true;
+    private static final boolean INCIDENTD_TESTS_ENABLED = false;
 
     // Config constants
     private static final int ALARM_ID = 11;
diff --git a/hostsidetests/statsd/src/android/cts/statsd/alert/AnomalyDetectionTests.java b/hostsidetests/statsd/src/android/cts/statsd/alert/AnomalyDetectionTests.java
index 1567075..bfc3c1d 100644
--- a/hostsidetests/statsd/src/android/cts/statsd/alert/AnomalyDetectionTests.java
+++ b/hostsidetests/statsd/src/android/cts/statsd/alert/AnomalyDetectionTests.java
@@ -45,8 +45,8 @@
 
     private static final String TAG = "Statsd.AnomalyDetectionTests";
 
-    private static final boolean INCIDENTD_TESTS_ENABLED = true;
-    private static final boolean PERFETTO_TESTS_ENABLED = true;
+    private static final boolean INCIDENTD_TESTS_ENABLED = false;
+    private static final boolean PERFETTO_TESTS_ENABLED = false;
 
     private static final int WAIT_AFTER_BREADCRUMB_MS = 2000;
 
diff --git a/hostsidetests/statsd/src/android/cts/statsd/atom/AtomTestCase.java b/hostsidetests/statsd/src/android/cts/statsd/atom/AtomTestCase.java
index 41e51e8..3853f7b 100644
--- a/hostsidetests/statsd/src/android/cts/statsd/atom/AtomTestCase.java
+++ b/hostsidetests/statsd/src/android/cts/statsd/atom/AtomTestCase.java
@@ -434,6 +434,29 @@
         data.subList(0, firstStateIdx).clear();
     }
 
+    /**
+     * Removes all elements from data after to the last occurrence of an element of state. After
+     * this method is called, the last element of data (if non-empty) is guaranteed to be an
+     * element in state.
+     *
+     * @param getStateFromAtom expression that takes in an Atom and returns the state it contains
+     */
+    public void popUntilFindFromEnd(List<EventMetricData> data, Set<Integer> state,
+        Function<Atom, Integer> getStateFromAtom) {
+        int lastStateIdx;
+        for (lastStateIdx = data.size() - 1; lastStateIdx >= 0; lastStateIdx--) {
+            Atom atom = data.get(lastStateIdx).getAtom();
+            if (state.contains(getStateFromAtom.apply(atom))) {
+                break;
+            }
+        }
+        if (lastStateIdx == data.size()-1) {
+            // Last element already is in state, so there's nothing to do.
+            return;
+        }
+        data.subList(lastStateIdx+1, data.size()).clear();
+    }
+
     /** Returns the UID of the host, which should always either be SHELL (2000) or ROOT (0). */
     protected int getHostUid() throws DeviceNotAvailableException {
         String strUid = "";
@@ -596,7 +619,7 @@
             LogUtil.CLog.w("Device does " + (requiredAnswer ? "not " : "") + "have feature "
                     + featureName);
         }
-        return hasIt;
+        return hasIt == requiredAnswer;
     }
 
 }
diff --git a/hostsidetests/statsd/src/android/cts/statsd/atom/DeviceAtomTestCase.java b/hostsidetests/statsd/src/android/cts/statsd/atom/DeviceAtomTestCase.java
index 5d0fddc..c14a89f 100644
--- a/hostsidetests/statsd/src/android/cts/statsd/atom/DeviceAtomTestCase.java
+++ b/hostsidetests/statsd/src/android/cts/statsd/atom/DeviceAtomTestCase.java
@@ -31,8 +31,10 @@
 public class DeviceAtomTestCase extends AtomTestCase {
 
     protected static final String DEVICE_SIDE_TEST_APK = "CtsStatsdApp.apk";
-    protected static final String DEVICE_SIDE_TEST_PACKAGE
-            = "com.android.server.cts.device.statsd";
+    protected static final String DEVICE_SIDE_TEST_PACKAGE =
+            "com.android.server.cts.device.statsd";
+    protected static final long DEVICE_SIDE_TEST_PKG_HASH =
+            Long.parseUnsignedLong("15694052924544098582");
 
     protected static final String CONFIG_NAME = "cts_config";
 
diff --git a/hostsidetests/statsd/src/android/cts/statsd/atom/HostAtomTests.java b/hostsidetests/statsd/src/android/cts/statsd/atom/HostAtomTests.java
index 8a17d7f..b0e8d0a 100644
--- a/hostsidetests/statsd/src/android/cts/statsd/atom/HostAtomTests.java
+++ b/hostsidetests/statsd/src/android/cts/statsd/atom/HostAtomTests.java
@@ -64,6 +64,7 @@
     private static final String FEATURE_BLUETOOTH = "android.hardware.bluetooth";
     private static final String FEATURE_WIFI = "android.hardware.wifi";
     private static final String FEATURE_TELEPHONY = "android.hardware.telephony";
+    private static final String FEATURE_WATCH = "android.hardware.type.watch";
 
     @Override
     protected void setUp() throws Exception {
@@ -249,53 +250,6 @@
                 atom -> atom.getBatteryLevelChanged().getBatteryLevel());
     }
 
-    public void testScreenBrightnessChangedAtom() throws Exception {
-        // Setup: record initial brightness state, set mode to manual and brightness to full.
-        int initialBrightness = getScreenBrightness();
-        boolean isInitialManual = isScreenBrightnessModeManual();
-        turnScreenOn();
-        setScreenBrightnessMode(true);
-        setScreenBrightness(255);
-        Thread.sleep(WAIT_TIME_SHORT);
-
-        final int atomTag = Atom.SCREEN_BRIGHTNESS_CHANGED_FIELD_NUMBER;
-
-        Set<Integer> screenMin = new HashSet<>(Arrays.asList(25));
-        Set<Integer> screen100 = new HashSet<>(Arrays.asList(100));
-        Set<Integer> screen200 = new HashSet<>(Arrays.asList(200));
-        Set<Integer> screenMax = new HashSet<>(Arrays.asList(255));
-
-        // Add state sets to the list in order.
-        List<Set<Integer>> stateSet = Arrays.asList(screenMin, screen100, screen200, screenMax);
-
-        createAndUploadConfig(atomTag);
-        Thread.sleep(WAIT_TIME_SHORT);
-
-        // Trigger events in same order.
-        setScreenBrightness(25);
-        Thread.sleep(WAIT_TIME_SHORT);
-        setScreenBrightness(100);
-        Thread.sleep(WAIT_TIME_SHORT);
-        setScreenBrightness(200);
-        Thread.sleep(WAIT_TIME_SHORT);
-        setScreenBrightness(255);
-        Thread.sleep(WAIT_TIME_SHORT);
-
-
-        // Sorted list of events in order in which they occurred.
-        List<EventMetricData> data = getEventMetricDataList();
-
-        // Restore initial screen brightness
-        setScreenBrightness(initialBrightness);
-        setScreenBrightnessMode(isInitialManual);
-        turnScreenOff();
-        Thread.sleep(WAIT_TIME_SHORT);
-
-        // Assert that the events happened in the expected order.
-        assertStatesOccurred(stateSet, data, WAIT_TIME_SHORT,
-                atom -> atom.getScreenBrightnessChanged().getLevel());
-    }
-
     public void testDeviceIdleModeStateChangedAtom() throws Exception {
         // Setup, leave doze mode.
         leaveDozeMode();
@@ -352,20 +306,21 @@
 
         // Trigger events in same order.
         turnBatterySaverOn();
-        Thread.sleep(WAIT_TIME_SHORT);
+        Thread.sleep(WAIT_TIME_LONG);
         turnBatterySaverOff();
-        Thread.sleep(WAIT_TIME_SHORT);
+        Thread.sleep(WAIT_TIME_LONG);
 
         // Sorted list of events in order in which they occurred.
         List<EventMetricData> data = getEventMetricDataList();
 
         // Assert that the events happened in the expected order.
-        assertStatesOccurred(stateSet, data, WAIT_TIME_SHORT,
+        assertStatesOccurred(stateSet, data, WAIT_TIME_LONG,
                 atom -> atom.getBatterySaverModeStateChanged().getState().getNumber());
     }
 
     @RestrictedBuildTest
     public void testRemainingBatteryCapacity() throws Exception {
+        if (!hasFeature(FEATURE_WATCH, false)) return;
         StatsdConfig.Builder config = getPulledConfig();
         FieldMatcher.Builder dimension = FieldMatcher.newBuilder()
             .setField(Atom.REMAINING_BATTERY_CAPACITY_FIELD_NUMBER)
@@ -392,6 +347,7 @@
 
     @RestrictedBuildTest
     public void testFullBatteryCapacity() throws Exception {
+        if (!hasFeature(FEATURE_WATCH, false)) return;
         StatsdConfig.Builder config = getPulledConfig();
         FieldMatcher.Builder dimension = FieldMatcher.newBuilder()
                 .setField(Atom.FULL_BATTERY_CAPACITY_FIELD_NUMBER)
@@ -419,6 +375,7 @@
 
     @RestrictedBuildTest
     public void testTemperature() throws Exception {
+        if (!hasFeature(FEATURE_WATCH, false)) return;
         StatsdConfig.Builder config = getPulledConfig();
         FieldMatcher.Builder dimension = FieldMatcher.newBuilder()
                 .setField(Atom.TEMPERATURE_FIELD_NUMBER)
@@ -482,6 +439,7 @@
     }
 
     public void testCpuTimePerFreq() throws Exception {
+        if (!hasFeature(FEATURE_WATCH, false)) return;
         StatsdConfig.Builder config = getPulledConfig();
         FieldMatcher.Builder dimension = FieldMatcher.newBuilder()
                 .setField(Atom.CPU_TIME_PER_FREQ_FIELD_NUMBER)
@@ -553,6 +511,7 @@
 
     public void testWifiActivityInfo() throws Exception {
         if (!hasFeature(FEATURE_WIFI, true)) return;
+        if (!hasFeature(FEATURE_WATCH, false)) return;
         StatsdConfig.Builder config = getPulledConfig();
         addGaugeAtom(config, Atom.WIFI_ACTIVITY_INFO_FIELD_NUMBER, null);
 
diff --git a/hostsidetests/statsd/src/android/cts/statsd/atom/ProcStateAtomTests.java b/hostsidetests/statsd/src/android/cts/statsd/atom/ProcStateAtomTests.java
index 925b277..88544c6 100644
--- a/hostsidetests/statsd/src/android/cts/statsd/atom/ProcStateAtomTests.java
+++ b/hostsidetests/statsd/src/android/cts/statsd/atom/ProcStateAtomTests.java
@@ -60,6 +60,8 @@
     private static final int EXTRA_WAIT_TIME_MS = 1_000; // as buffer when proc state changing.
     private static final int STATSD_REPORT_WAIT_TIME_MS = 500; // make sure statsd finishes log.
 
+    private static final String FEATURE_WATCH = "android.hardware.type.watch";
+
     // The tests here are using the BatteryStats definition of 'background'.
     private static final Set<Integer> BG_STATES = new HashSet<>(
             Arrays.asList(
@@ -187,6 +189,7 @@
     }
 
     public void testTopSleeping() throws Exception {
+        if (!hasFeature(FEATURE_WATCH, false)) return;
         Set<Integer> onStates = new HashSet<>(Arrays.asList(
                 ProcessStateEnum.PROCESS_STATE_TOP_SLEEPING_VALUE));
         Set<Integer> offStates = complement(onStates);
diff --git a/hostsidetests/statsd/src/android/cts/statsd/atom/UidAtomTests.java b/hostsidetests/statsd/src/android/cts/statsd/atom/UidAtomTests.java
index 809d682..a472f04 100644
--- a/hostsidetests/statsd/src/android/cts/statsd/atom/UidAtomTests.java
+++ b/hostsidetests/statsd/src/android/cts/statsd/atom/UidAtomTests.java
@@ -24,7 +24,6 @@
 
 import com.android.internal.os.StatsdConfigProto.FieldMatcher;
 import com.android.internal.os.StatsdConfigProto.StatsdConfig;
-import com.android.os.AtomsProto.AppBreadcrumbReported;
 import com.android.os.AtomsProto.AppCrashOccurred;
 import com.android.os.AtomsProto.AppStartOccurred;
 import com.android.os.AtomsProto.Atom;
@@ -34,7 +33,6 @@
 import com.android.os.AtomsProto.CameraStateChanged;
 import com.android.os.AtomsProto.CpuActiveTime;
 import com.android.os.AtomsProto.CpuTimePerUid;
-import com.android.os.AtomsProto.CpuTimePerUidFreq;
 import com.android.os.AtomsProto.FlashlightStateChanged;
 import com.android.os.AtomsProto.ForegroundServiceStateChanged;
 import com.android.os.AtomsProto.GpsScanStateChanged;
@@ -69,6 +67,9 @@
     private static final String FEATURE_CAMERA = "android.hardware.camera";
     private static final String FEATURE_CAMERA_FRONT = "android.hardware.camera.front";
     private static final String FEATURE_AUDIO_OUTPUT = "android.hardware.audio.output";
+    private static final String FEATURE_WATCH = "android.hardware.type.watch";
+
+    private static final boolean DAVEY_ENABLED = false;
 
     @Override
     protected void setUp() throws Exception {
@@ -197,6 +198,7 @@
     }
 
     public void testCpuTimePerUid() throws Exception {
+        if (!hasFeature(FEATURE_WATCH, false)) return;
         StatsdConfig.Builder config = getPulledConfig();
         FieldMatcher.Builder dimension = FieldMatcher.newBuilder()
                 .setField(Atom.CPU_TIME_PER_UID_FIELD_NUMBER)
@@ -230,41 +232,8 @@
     }
 
     @RestrictedBuildTest
-    public void testCpuTimePerUidFreq() throws Exception {
-        StatsdConfig.Builder config = getPulledConfig();
-        FieldMatcher.Builder dimension = FieldMatcher.newBuilder()
-                .setField(Atom.CPU_TIME_PER_UID_FREQ_FIELD_NUMBER)
-                .addChild(FieldMatcher.newBuilder()
-                        .setField(CpuTimePerUidFreq.UID_FIELD_NUMBER));
-        addGaugeAtom(config, Atom.CPU_TIME_PER_UID_FREQ_FIELD_NUMBER, dimension);
-
-        uploadConfig(config);
-
-        runDeviceTests(DEVICE_SIDE_TEST_PACKAGE, ".AtomTests", "testSimpleCpu");
-
-        turnScreenOff();
-        Thread.sleep(WAIT_TIME_SHORT);
-        turnScreenOn();
-        Thread.sleep(WAIT_TIME_SHORT);
-
-        List<Atom> atomList = getGaugeMetricDataList();
-
-        // TODO: We don't have atom matching on gauge yet. Let's refactor this after that feature is
-        // implemented.
-        boolean found = false;
-        int uid = getUid();
-        long timeSpent = 0;
-        for (Atom atom : atomList) {
-            if (atom.getCpuTimePerUidFreq().getUid() == uid) {
-                found = true;
-                timeSpent += atom.getCpuTimePerUidFreq().getTimeMillis();
-            }
-        }
-        assertTrue(timeSpent > 0);
-        assertTrue("found uid " + uid, found);
-    }
-
     public void testCpuActiveTime() throws Exception {
+        if (!hasFeature(FEATURE_WATCH, false)) return;
         StatsdConfig.Builder config = getPulledConfig();
         FieldMatcher.Builder dimension = FieldMatcher.newBuilder()
                 .setField(Atom.CPU_ACTIVE_TIME_FIELD_NUMBER)
@@ -375,6 +344,7 @@
     }
 
     public void testDavey() throws Exception {
+        if (!DAVEY_ENABLED ) return;
         long MAX_DURATION = 2000;
         long MIN_DURATION = 750;
         final int atomTag = Atom.DAVEY_OCCURRED_FIELD_NUMBER;
@@ -421,6 +391,44 @@
         }
     }
 
+    //Note: this test does not have uid, but must run on the device
+    public void testScreenBrightness() throws Exception {
+        int initialBrightness = getScreenBrightness();
+        boolean isInitialManual = isScreenBrightnessModeManual();
+        turnScreenOn();
+        setScreenBrightnessMode(true);
+        setScreenBrightness(200);
+        Thread.sleep(WAIT_TIME_LONG);
+
+        final int atomTag = Atom.SCREEN_BRIGHTNESS_CHANGED_FIELD_NUMBER;
+
+        Set<Integer> screenMin = new HashSet<>(Arrays.asList(47));
+        Set<Integer> screen100 = new HashSet<>(Arrays.asList(100));
+        Set<Integer> screen200 = new HashSet<>(Arrays.asList(198));
+        // Set<Integer> screenMax = new HashSet<>(Arrays.asList(255));
+
+        // Add state sets to the list in order.
+        List<Set<Integer>> stateSet = Arrays.asList(screenMin, screen100, screen200);
+
+        createAndUploadConfig(atomTag);
+        Thread.sleep(WAIT_TIME_SHORT);
+        runDeviceTests(DEVICE_SIDE_TEST_PACKAGE, ".AtomTests", "testScreenBrightness");
+
+        // Sorted list of events in order in which they occurred.
+        List<EventMetricData> data = getEventMetricDataList();
+
+        // Restore initial screen brightness
+        setScreenBrightness(initialBrightness);
+        setScreenBrightnessMode(isInitialManual);
+        turnScreenOff();
+        Thread.sleep(WAIT_TIME_SHORT);
+
+        popUntilFind(data, screenMin, atom->atom.getScreenBrightnessChanged().getLevel());
+        popUntilFindFromEnd(data, screen200, atom->atom.getScreenBrightnessChanged().getLevel());
+        // Assert that the events happened in the expected order.
+        assertStatesOccurred(stateSet, data, WAIT_TIME_SHORT,
+            atom -> atom.getScreenBrightnessChanged().getLevel());
+    }
     public void testSyncState() throws Exception {
         final int atomTag = Atom.SYNC_STATE_CHANGED_FIELD_NUMBER;
         Set<Integer> syncOn = new HashSet<>(Arrays.asList(SyncStateChanged.State.ON_VALUE));
@@ -542,7 +550,7 @@
         final int key = WifiScanStateChanged.STATE_FIELD_NUMBER;
         final int stateOn = WifiScanStateChanged.State.ON_VALUE;
         final int stateOff = WifiScanStateChanged.State.OFF_VALUE;
-        final int minTimeDiffMillis = 500;
+        final int minTimeDiffMillis = 250;
         final int maxTimeDiffMillis = 60_000;
         final boolean demandExactlyTwo = false; // Two scans are performed, so up to 4 atoms logged.
 
@@ -588,6 +596,7 @@
     }
 
     public void testMediaCodecActivity() throws Exception {
+        if (!hasFeature(FEATURE_WATCH, false)) return;
         final int atomTag = Atom.MEDIA_CODEC_STATE_CHANGED_FIELD_NUMBER;
 
         Set<Integer> onState = new HashSet<>(
@@ -614,6 +623,7 @@
     }
 
     public void testPictureInPictureState() throws Exception {
+        if (!hasFeature(FEATURE_WATCH, false)) return;
         final int atomTag = Atom.PICTURE_IN_PICTURE_STATE_CHANGED_FIELD_NUMBER;
 
         Set<Integer> entered = new HashSet<>(
@@ -681,25 +691,4 @@
                 atom.getForegroundState().getNumber());
         assertEquals("com.android.server.cts.device.statsd", atom.getPackageName());
     }
-
-    public void testBreadcrumb() throws Exception {
-        final int atomTag = Atom.APP_BREADCRUMB_REPORTED_FIELD_NUMBER;
-        createAndUploadConfig(atomTag, false);
-        Thread.sleep(WAIT_TIME_SHORT);
-
-        runDeviceTests(DEVICE_SIDE_TEST_PACKAGE, ".AtomTests", "testAppBreadcrumbReported");
-        Thread.sleep(WAIT_TIME_SHORT);
-
-        List<EventMetricData> data = getEventMetricDataList();
-        assertEquals(3, data.size());
-        AppBreadcrumbReported atom = data.get(0).getAtom().getAppBreadcrumbReported();
-        assertTrue(atom.getLabel() == 1);
-        assertTrue(atom.getState().getNumber() == AppBreadcrumbReported.State.START_VALUE);
-        atom = data.get(1).getAtom().getAppBreadcrumbReported();
-        assertTrue(atom.getLabel() == 1);
-        assertTrue(atom.getState().getNumber() == AppBreadcrumbReported.State.STOP_VALUE);
-        atom = data.get(2).getAtom().getAppBreadcrumbReported();
-        assertTrue(atom.getLabel() == 1);
-        assertTrue(atom.getState().getNumber() == AppBreadcrumbReported.State.UNSPECIFIED_VALUE);
-    }
 }
diff --git a/hostsidetests/statsd/src/android/cts/statsd/metadata/MetadataTests.java b/hostsidetests/statsd/src/android/cts/statsd/metadata/MetadataTests.java
index 5cb37d3..60492ff 100644
--- a/hostsidetests/statsd/src/android/cts/statsd/metadata/MetadataTests.java
+++ b/hostsidetests/statsd/src/android/cts/statsd/metadata/MetadataTests.java
@@ -42,12 +42,13 @@
 
     // Tests that anomaly detection for value works.
     public void testConfigTtl() throws Exception {
-        final int TTL_TIME_SEC = 3;
+        final int TTL_TIME_SEC = 8;
         StatsdConfig.Builder config = getBaseConfig();
         config.setTtlInSeconds(TTL_TIME_SEC); // should reset in 3 seconds.
         turnScreenOff();
 
         uploadConfig(config);
+        long startTime = System.currentTimeMillis();
         Thread.sleep(WAIT_TIME_SHORT);
         turnScreenOn();
         Thread.sleep(WAIT_TIME_SHORT);
@@ -67,7 +68,9 @@
         assertTrue("Did not find an active CTS config", foundActiveConfig);
 
         turnScreenOff();
-        Thread.sleep(WAIT_TIME_LONG); // Has been 3 seconds, config should TTL
+        while(System.currentTimeMillis() - startTime < 8_000) {
+            Thread.sleep(10);
+        }
         turnScreenOn(); // Force events to make sure the config TTLs.
         report = getStatsdStatsReport();
         LogUtil.CLog.d("got following statsdstats report: " + report.toString());
@@ -81,7 +84,7 @@
                             stats.hasDeletionTimeSec());
                     assertTrue("Config deletion time should be about " + TTL_TIME_SEC +
                             " after creation",
-                            Math.abs(stats.getDeletionTimeSec() - expectedTime) <= 1);
+                            Math.abs(stats.getDeletionTimeSec() - expectedTime) <= 2);
                 }
                 // There should still be one active config, that is marked as reset.
                 if(!stats.hasDeletionTimeSec()) {
@@ -93,7 +96,7 @@
                     assertEquals("Reset time and creation time should be equal for TTl'd configs",
                             stats.getResetTimeSec(), stats.getCreationTimeSec());
                     assertTrue("Reset config should be created when the original config TTL'd",
-                            Math.abs(stats.getCreationTimeSec() - expectedTime) <= 1);
+                            Math.abs(stats.getCreationTimeSec() - expectedTime) <= 2);
                 }
             }
         }
diff --git a/hostsidetests/statsd/src/android/cts/statsd/metric/CountMetricsTests.java b/hostsidetests/statsd/src/android/cts/statsd/metric/CountMetricsTests.java
index d8d6339..a5c31d0 100644
--- a/hostsidetests/statsd/src/android/cts/statsd/metric/CountMetricsTests.java
+++ b/hostsidetests/statsd/src/android/cts/statsd/metric/CountMetricsTests.java
@@ -45,11 +45,11 @@
         uploadConfig(builder);
 
         doAppBreadcrumbReportedStart(0);
-        Thread.sleep(10);
         doAppBreadcrumbReportedStop(0);
         Thread.sleep(2000);  // Wait for the metrics to propagate to statsd.
 
         StatsLogReport metricReport = getStatsLogReport();
+        LogUtil.CLog.d("Got the following stats log report: \n" + metricReport.toString());
         assertEquals(MetricsUtils.COUNT_METRIC_ID, metricReport.getMetricId());
         assertTrue(metricReport.hasCountMetrics());
 
diff --git a/hostsidetests/statsd/src/android/cts/statsd/metric/GaugeMetricsTests.java b/hostsidetests/statsd/src/android/cts/statsd/metric/GaugeMetricsTests.java
index 958ee9f..be2558e 100644
--- a/hostsidetests/statsd/src/android/cts/statsd/metric/GaugeMetricsTests.java
+++ b/hostsidetests/statsd/src/android/cts/statsd/metric/GaugeMetricsTests.java
@@ -29,6 +29,7 @@
 import com.android.os.AtomsProto.Atom;
 import com.android.os.StatsLog.GaugeMetricData;
 import com.android.os.StatsLog.StatsLogReport;
+import com.android.tradefed.log.LogUtil;
 
 public class GaugeMetricsTests extends DeviceAtomTestCase {
 
@@ -108,6 +109,7 @@
     Thread.sleep(2000);
 
     StatsLogReport metricReport = getStatsLogReport();
+    LogUtil.CLog.d("Got the following gauge metric data: " + metricReport.toString());
     assertEquals(MetricsUtils.GAUGE_METRIC_ID, metricReport.getMetricId());
     assertTrue(metricReport.hasGaugeMetrics());
     StatsLogReport.GaugeMetricDataWrapper gaugeData = metricReport.getGaugeMetrics();
@@ -116,19 +118,16 @@
     int bucketCount = gaugeData.getData(0).getBucketInfoCount();
     GaugeMetricData data = gaugeData.getData(0);
     assertTrue(bucketCount > 2);
-    assertTrue(data.getBucketInfo(0).hasStartBucketElapsedNanos());
-    assertTrue(data.getBucketInfo(0).hasEndBucketElapsedNanos());
+    MetricsUtils.assertBucketTimePresent(data.getBucketInfo(0));
     assertEquals(data.getBucketInfo(0).getAtomCount(), 1);
     assertEquals(data.getBucketInfo(0).getAtom(0).getAppBreadcrumbReported().getLabel(), 0);
     assertEquals(data.getBucketInfo(0).getAtom(0).getAppBreadcrumbReported().getState(),
         AppBreadcrumbReported.State.START);
 
-    assertTrue(data.getBucketInfo(1).hasStartBucketElapsedNanos());
-    assertTrue(data.getBucketInfo(1).hasEndBucketElapsedNanos());
+    MetricsUtils.assertBucketTimePresent(data.getBucketInfo(1));
     assertEquals(data.getBucketInfo(1).getAtomCount(), 1);
 
-    assertTrue(data.getBucketInfo(bucketCount - 1).hasStartBucketElapsedNanos());
-    assertTrue(data.getBucketInfo(bucketCount - 1).hasEndBucketElapsedNanos());
+    MetricsUtils.assertBucketTimePresent(data.getBucketInfo(bucketCount-1));
     assertEquals(data.getBucketInfo(bucketCount - 1).getAtomCount(), 1);
     assertEquals(
         data.getBucketInfo(bucketCount - 1).getAtom(0).getAppBreadcrumbReported().getLabel(), 2);
diff --git a/hostsidetests/statsd/src/android/cts/statsd/metric/MetricsUtils.java b/hostsidetests/statsd/src/android/cts/statsd/metric/MetricsUtils.java
index 9868048..f65eac9 100644
--- a/hostsidetests/statsd/src/android/cts/statsd/metric/MetricsUtils.java
+++ b/hostsidetests/statsd/src/android/cts/statsd/metric/MetricsUtils.java
@@ -21,6 +21,11 @@
 import com.android.internal.os.StatsdConfigProto.SimpleAtomMatcher;
 import com.android.os.AtomsProto.Atom;
 import com.android.os.AtomsProto.AppBreadcrumbReported;
+import com.google.protobuf.Message;
+import com.google.protobuf.Descriptors.Descriptor;
+import com.google.protobuf.Descriptors.FieldDescriptor;
+
+import static org.junit.Assert.assertTrue;
 
 public class MetricsUtils {
     public static final long COUNT_METRIC_ID = 3333;
@@ -81,4 +86,20 @@
     public static long StringToId(String str) {
       return str.hashCode();
     }
+
+    public static void assertBucketTimePresent(Message bucketInfo) {
+        Descriptor descriptor = bucketInfo.getDescriptorForType();
+        boolean found = false;
+        FieldDescriptor bucketNum = descriptor.findFieldByName("bucket_num");
+        FieldDescriptor startMillis = descriptor.findFieldByName("start_bucket_elapsed_millis");
+        FieldDescriptor endMillis = descriptor.findFieldByName("end_bucket_elapsed_millis");
+        if (bucketNum != null && bucketInfo.hasField(bucketNum)) {
+            found = true;
+        } else if (startMillis != null && bucketInfo.hasField(startMillis) &&
+                   endMillis != null && bucketInfo.hasField(endMillis)) {
+            found = true;
+        }
+        assertTrue("Bucket info did not have either bucket num or start and end elapsed millis",
+                found);
+    }
 }
diff --git a/hostsidetests/statsd/src/android/cts/statsd/metric/ValueMetricsTests.java b/hostsidetests/statsd/src/android/cts/statsd/metric/ValueMetricsTests.java
index 21071f9..891025d 100644
--- a/hostsidetests/statsd/src/android/cts/statsd/metric/ValueMetricsTests.java
+++ b/hostsidetests/statsd/src/android/cts/statsd/metric/ValueMetricsTests.java
@@ -48,6 +48,7 @@
 import com.android.os.StatsLog.EventMetricData;
 import com.android.os.StatsLog.GaugeMetricData;
 import com.android.os.StatsLog.StatsLogReport;
+import com.android.tradefed.log.LogUtil;
 
 public class ValueMetricsTests extends DeviceAtomTestCase {
   private static final int APP_BREADCRUMB_REPORTED_A_MATCH_START_ID = 0;
@@ -97,6 +98,7 @@
     Thread.sleep(2000);
 
     StatsLogReport metricReport = getStatsLogReport();
+    LogUtil.CLog.d("Got the following value metric data: " + metricReport.toString());
     assertEquals(MetricsUtils.VALUE_METRIC_ID, metricReport.getMetricId());
     assertTrue(metricReport.hasValueMetrics());
     StatsLogReport.ValueMetricDataWrapper valueData = metricReport.getValueMetrics();
@@ -107,8 +109,7 @@
     ValueMetricData data = valueData.getData(0);
     int totalValue = 0;
     for (ValueBucketInfo bucketInfo : data.getBucketInfoList()) {
-      assertTrue(bucketInfo.hasStartBucketElapsedNanos());
-      assertTrue(bucketInfo.hasEndBucketElapsedNanos());
+      MetricsUtils.assertBucketTimePresent(bucketInfo);
       totalValue += (int) bucketInfo.getValue();
     }
     assertEquals(totalValue, 8);
@@ -172,6 +173,7 @@
     Thread.sleep(1_000);
 
     StatsLogReport metricReport = getStatsLogReport();
+    LogUtil.CLog.d("Got the following value metric data: " + metricReport.toString());
     turnScreenOff();
     assertEquals(MetricsUtils.VALUE_METRIC_ID, metricReport.getMetricId());
     assertTrue(metricReport.hasValueMetrics());
@@ -184,8 +186,7 @@
     ValueMetricData data = valueData.getData(0);
     int totalValue = 0;
     for (ValueBucketInfo bucketInfo : data.getBucketInfoList()) {
-      assertTrue(bucketInfo.hasStartBucketElapsedNanos());
-      assertTrue(bucketInfo.hasEndBucketElapsedNanos());
+      MetricsUtils.assertBucketTimePresent(bucketInfo);
       totalValue += (int) bucketInfo.getValue();
     }
     // At most we lose one full min bucket
@@ -254,6 +255,7 @@
     Thread.sleep(1_000);
 
     StatsLogReport metricReport = getStatsLogReport();
+    LogUtil.CLog.d("Got the following value metric data: " + metricReport.toString());
     turnScreenOff();
     assertEquals(MetricsUtils.VALUE_METRIC_ID, metricReport.getMetricId());
     assertTrue(metricReport.hasValueMetrics());
@@ -266,8 +268,7 @@
     ValueMetricData data = valueData.getData(0);
     int totalValue = 0;
     for (ValueBucketInfo bucketInfo : data.getBucketInfoList()) {
-      assertTrue(bucketInfo.hasStartBucketElapsedNanos());
-      assertTrue(bucketInfo.hasEndBucketElapsedNanos());
+      MetricsUtils.assertBucketTimePresent(bucketInfo);
       totalValue += (int) bucketInfo.getValue();
     }
     // At most we lose one full min bucket
diff --git a/hostsidetests/statsd/src/android/cts/statsd/uidmap/UidMapTests.java b/hostsidetests/statsd/src/android/cts/statsd/uidmap/UidMapTests.java
index 75d7c1e..f7c9df6 100644
--- a/hostsidetests/statsd/src/android/cts/statsd/uidmap/UidMapTests.java
+++ b/hostsidetests/statsd/src/android/cts/statsd/uidmap/UidMapTests.java
@@ -20,10 +20,12 @@
 import android.cts.statsd.atom.DeviceAtomTestCase;
 import com.android.compatibility.common.tradefed.build.CompatibilityBuildHelper;
 import com.android.internal.os.StatsdConfigProto;
+import com.android.os.AtomsProto;
 import com.android.os.StatsLog.ConfigMetricsReportList;
 import com.android.os.StatsLog.ConfigMetricsReport;
 import com.android.os.StatsLog.UidMapping;
 import com.android.os.StatsLog.UidMapping.PackageInfoSnapshot;
+import com.android.tradefed.log.LogUtil;
 
 import java.util.List;
 
@@ -32,7 +34,7 @@
     // Tests that every report has at least one snapshot.
     public void testUidSnapshotIncluded() throws Exception {
         // There should be at least the test app installed during the test setup.
-        uploadConfig(createConfigBuilder().build());
+        createAndUploadConfig(AtomsProto.Atom.UID_PROCESS_STATE_CHANGED_FIELD_NUMBER);
 
         ConfigMetricsReportList reports = getReportList();
         assertTrue(reports.getReportsCount() > 0);
@@ -48,9 +50,10 @@
         }
     }
 
-    private boolean hasMatchingChange(UidMapping uidmap, boolean expectDeletion) {
+    private boolean hasMatchingChange(UidMapping uidmap, int uid, boolean expectDeletion) {
+        LogUtil.CLog.d("The uid we are looking for is " + uid);
         for (UidMapping.Change change : uidmap.getChangesList()) {
-            if (change.getApp().equals(DEVICE_SIDE_TEST_PACKAGE)) {
+            if (change.getAppHash() == DEVICE_SIDE_TEST_PKG_HASH && change.getUid() == uid) {
                 if (change.getDeletion() == expectDeletion) {
                     return true;
                 }
@@ -62,19 +65,23 @@
     // Tests that delta event included during app installation.
     public void testChangeFromInstallation() throws Exception {
         getDevice().uninstallPackage(DEVICE_SIDE_TEST_PACKAGE);
-        uploadConfig(createConfigBuilder().build());
+        createAndUploadConfig(AtomsProto.Atom.UID_PROCESS_STATE_CHANGED_FIELD_NUMBER);
         // Install the package after the config is sent to statsd. The uid map is not guaranteed to
         // be updated if there's no config in statsd.
         CompatibilityBuildHelper buildHelper = new CompatibilityBuildHelper(mCtsBuild);
         final String result = getDevice().installPackage(
                 buildHelper.getTestFile(DEVICE_SIDE_TEST_APK), false, true);
 
+        Thread.sleep(WAIT_TIME_SHORT);
+
         ConfigMetricsReportList reports = getReportList();
         assertTrue(reports.getReportsCount() > 0);
 
         boolean found = false;
+        int uid = getUid();
         for (ConfigMetricsReport report : reports.getReportsList()) {
-            if (hasMatchingChange(report.getUidMap(), false)) {
+            LogUtil.CLog.d("Got the following report: \n" + report.toString());
+            if (hasMatchingChange(report.getUidMap(), uid, false)) {
                 found = true;
             }
         }
@@ -85,16 +92,20 @@
     public void testChangeFromReinstall() throws Exception {
         CompatibilityBuildHelper buildHelper = new CompatibilityBuildHelper(mCtsBuild);
         getDevice().installPackage(buildHelper.getTestFile(DEVICE_SIDE_TEST_APK), false, true);
-        uploadConfig(createConfigBuilder().build());
+        createAndUploadConfig(AtomsProto.Atom.UID_PROCESS_STATE_CHANGED_FIELD_NUMBER);
         // Now enable re-installation.
         getDevice().installPackage(buildHelper.getTestFile(DEVICE_SIDE_TEST_APK), true, true);
 
+        Thread.sleep(WAIT_TIME_SHORT);
+
         ConfigMetricsReportList reports = getReportList();
         assertTrue(reports.getReportsCount() > 0);
 
         boolean found = false;
+        int uid = getUid();
         for (ConfigMetricsReport report : reports.getReportsList()) {
-            if (hasMatchingChange(report.getUidMap(), false)) {
+            LogUtil.CLog.d("Got the following report: \n" + report.toString());
+            if (hasMatchingChange(report.getUidMap(), uid, false)) {
                 found = true;
             }
         }
@@ -104,15 +115,19 @@
     public void testChangeFromUninstall() throws Exception {
         CompatibilityBuildHelper buildHelper = new CompatibilityBuildHelper(mCtsBuild);
         getDevice().installPackage(buildHelper.getTestFile(DEVICE_SIDE_TEST_APK), true, true);
-        uploadConfig(createConfigBuilder().build());
+        createAndUploadConfig(AtomsProto.Atom.UID_PROCESS_STATE_CHANGED_FIELD_NUMBER);
+        int uid = getUid();
         getDevice().uninstallPackage(DEVICE_SIDE_TEST_PACKAGE);
 
+        Thread.sleep(WAIT_TIME_SHORT);
+
         ConfigMetricsReportList reports = getReportList();
         assertTrue(reports.getReportsCount() > 0);
 
         boolean found = false;
         for (ConfigMetricsReport report : reports.getReportsList()) {
-            if (hasMatchingChange(report.getUidMap(), true)) {
+            LogUtil.CLog.d("Got the following report: \n" + report.toString());
+            if (hasMatchingChange(report.getUidMap(), uid, true)) {
                 found = true;
             }
         }
diff --git a/hostsidetests/statsd/src/android/cts/statsd/validation/ValidationTests.java b/hostsidetests/statsd/src/android/cts/statsd/validation/ValidationTests.java
index be1c99b..92957fe 100644
--- a/hostsidetests/statsd/src/android/cts/statsd/validation/ValidationTests.java
+++ b/hostsidetests/statsd/src/android/cts/statsd/validation/ValidationTests.java
@@ -145,12 +145,13 @@
 
 
         final String EXPECTED_TAG = "StatsdPartialWakelock";
+        final long EXPECTED_TAG_HASH = Long.parseUnsignedLong("15814523794762874414");
         final int EXPECTED_UID = getUid();
         final int MIN_DURATION = 350;
         final int MAX_DURATION = 700;
 
         BatteryStatsProto batterystatsProto = getBatteryStatsProto();
-        HashMap<Integer, HashMap<String, Long>> statsdWakelockData = getStatsdWakelockData();
+        HashMap<Integer, HashMap<Long, Long>> statsdWakelockData = getStatsdWakelockData();
 
         // Get the batterystats wakelock time and make sure it's reasonable.
         android.os.TimerProto bsWakelock =
@@ -168,9 +169,10 @@
         // Get the statsd wakelock time and make sure it's reasonable.
         assertTrue("Could not find any wakelocks with uid " + EXPECTED_UID + " in statsd",
                 statsdWakelockData.containsKey(EXPECTED_UID));
-        assertTrue("Did not find any wakelocks with tag " + EXPECTED_TAG + "in statsd",
-                statsdWakelockData.get(EXPECTED_UID).containsKey(EXPECTED_TAG));
-        long statsdDurationMs = statsdWakelockData.get(EXPECTED_UID).get(EXPECTED_TAG) / 1_000_000;
+        assertTrue("Did not find any wakelocks with tag " + EXPECTED_TAG + " in statsd",
+                statsdWakelockData.get(EXPECTED_UID).containsKey(EXPECTED_TAG_HASH));
+        long statsdDurationMs = statsdWakelockData.get(EXPECTED_UID)
+                .get(EXPECTED_TAG_HASH) / 1_000_000;
         assertTrue("Wakelock in statsd with uid " + EXPECTED_UID + " and tag " + EXPECTED_TAG +
                     "was too short. Expected " + MIN_DURATION + ", received " + statsdDurationMs,
                 statsdDurationMs >= MIN_DURATION);
@@ -208,83 +210,89 @@
 
 
         BatteryStatsProto batterystatsProto = getBatteryStatsProto();
-        HashMap<Integer, HashMap<String, Long>> statsdWakelockData = getStatsdWakelockData();
+        HashMap<Integer, HashMap<Long, Long>> statsdWakelockData = getStatsdWakelockData();
+
+        // TODO: this fails because we only have the hashes of the wakelock tags in statsd.
+        // If we want to run this test, we need to fix this.
 
         // Verify batterystats output is reasonable.
-        boolean foundUid = false;
-        for (UidProto uidProto : batterystatsProto.getUidsList()) {
-            if (uidProto.getUid() == EXPECTED_UID) {
-                foundUid = true;
-                CLog.d("Battery stats has the following wakelocks: \n" +
-                        uidProto.getWakelocksList());
-                assertTrue("UidProto has size "  + uidProto.getWakelocksList().size() +
-                        " wakelocks in it. Expected " + NUM_THREADS + " wakelocks.",
-                        uidProto.getWakelocksList().size() == NUM_THREADS);
-
-                for (Wakelock wl : uidProto.getWakelocksList()) {
-                    String tag = wl.getName();
-                    assertTrue("Wakelock tag in batterystats " + tag + " does not contain "
-                            + "expected tag " + EXPECTED_TAG, tag.contains(EXPECTED_TAG));
-                    assertTrue("Wakelock in batterystats with tag " + tag + " does not have any "
-                                    + "partial wakelock data.", wl.hasPartial());
-                    assertTrue("Wakelock in batterystats with tag " + tag + " tag has count " +
-                            wl.getPartial().getCount() + " Expected " + NUM_COUNT_PER_THREAD,
-                            wl.getPartial().getCount() == NUM_COUNT_PER_THREAD);
-                    long bsDurationMs = wl.getPartial().getTotalDurationMs();
-                    assertTrue("Wakelock in batterystats with uid " + EXPECTED_UID + " and tag "
-                            + EXPECTED_TAG + "was too short. Expected " + MIN_DURATION_MS +
-                            ", received " + bsDurationMs, bsDurationMs >= MIN_DURATION_MS);
-                    assertTrue("Wakelock in batterystats with uid " + EXPECTED_UID + " and tag "
-                            + EXPECTED_TAG + "was too long. Expected " + MAX_DURATION_MS +
-                            ", received " + bsDurationMs, bsDurationMs <= MAX_DURATION_MS);
-
-                    // Validate statsd.
-                    long statsdDurationNs = statsdWakelockData.get(EXPECTED_UID).get(tag);
-                    long statsdDurationMs = statsdDurationNs / 1_000_000;
-                    long difference = Math.abs(statsdDurationMs - bsDurationMs);
-                    assertTrue("Unusually large difference in wakelock duration for tag: " + tag +
-                                ". Statsd had duration " + statsdDurationMs +
-                                " and batterystats had duration " + bsDurationMs,
-                                difference <= bsDurationMs / 10);
-
-                }
-            }
-        }
-        assertTrue("Did not find uid " + EXPECTED_UID + " in batterystats.", foundUid);
-
-        // Assert that the wakelock appears in statsd and is correct.
-        assertTrue("Could not find any wakelocks with uid " + EXPECTED_UID + " in statsd",
-                statsdWakelockData.containsKey(EXPECTED_UID));
-        HashMap<String, Long> expectedWakelocks = statsdWakelockData.get(EXPECTED_UID);
-        assertEquals("Expected " + NUM_THREADS + " wakelocks in statsd with UID " + EXPECTED_UID +
-                ". Received " + expectedWakelocks.size(), expectedWakelocks.size(), NUM_THREADS);
+        // boolean foundUid = false;
+        // for (UidProto uidProto : batterystatsProto.getUidsList()) {
+        //     if (uidProto.getUid() == EXPECTED_UID) {
+        //         foundUid = true;
+        //         CLog.d("Battery stats has the following wakelocks: \n" +
+        //                 uidProto.getWakelocksList());
+        //         assertTrue("UidProto has size "  + uidProto.getWakelocksList().size() +
+        //                 " wakelocks in it. Expected " + NUM_THREADS + " wakelocks.",
+        //                 uidProto.getWakelocksList().size() == NUM_THREADS);
+        //
+        //         for (Wakelock wl : uidProto.getWakelocksList()) {
+        //             String tag = wl.getName();
+        //             assertTrue("Wakelock tag in batterystats " + tag + " does not contain "
+        //                     + "expected tag " + EXPECTED_TAG, tag.contains(EXPECTED_TAG));
+        //             assertTrue("Wakelock in batterystats with tag " + tag + " does not have any "
+        //                             + "partial wakelock data.", wl.hasPartial());
+        //             assertTrue("Wakelock in batterystats with tag " + tag + " tag has count " +
+        //                     wl.getPartial().getCount() + " Expected " + NUM_COUNT_PER_THREAD,
+        //                     wl.getPartial().getCount() == NUM_COUNT_PER_THREAD);
+        //             long bsDurationMs = wl.getPartial().getTotalDurationMs();
+        //             assertTrue("Wakelock in batterystats with uid " + EXPECTED_UID + " and tag "
+        //                     + EXPECTED_TAG + "was too short. Expected " + MIN_DURATION_MS +
+        //                     ", received " + bsDurationMs, bsDurationMs >= MIN_DURATION_MS);
+        //             assertTrue("Wakelock in batterystats with uid " + EXPECTED_UID + " and tag "
+        //                     + EXPECTED_TAG + "was too long. Expected " + MAX_DURATION_MS +
+        //                     ", received " + bsDurationMs, bsDurationMs <= MAX_DURATION_MS);
+        //
+        //             // Validate statsd.
+        //             long statsdDurationNs = statsdWakelockData.get(EXPECTED_UID).get(tag);
+        //             long statsdDurationMs = statsdDurationNs / 1_000_000;
+        //             long difference = Math.abs(statsdDurationMs - bsDurationMs);
+        //             assertTrue("Unusually large difference in wakelock duration for tag: " + tag +
+        //                         ". Statsd had duration " + statsdDurationMs +
+        //                         " and batterystats had duration " + bsDurationMs,
+        //                         difference <= bsDurationMs / 10);
+        //
+        //         }
+        //     }
+        // }
+        // assertTrue("Did not find uid " + EXPECTED_UID + " in batterystats.", foundUid);
+        //
+        // // Assert that the wakelock appears in statsd and is correct.
+        // assertTrue("Could not find any wakelocks with uid " + EXPECTED_UID + " in statsd",
+        //         statsdWakelockData.containsKey(EXPECTED_UID));
+        // HashMap<String, Long> expectedWakelocks = statsdWakelockData.get(EXPECTED_UID);
+        // assertEquals("Expected " + NUM_THREADS + " wakelocks in statsd with UID " + EXPECTED_UID +
+        //         ". Received " + expectedWakelocks.size(), expectedWakelocks.size(), NUM_THREADS);
     }
 
 
     // Helper functions
     // TODO: Refactor these into some utils class.
 
-    public HashMap<Integer, HashMap<String, Long>> getStatsdWakelockData() throws Exception {
+    public HashMap<Integer, HashMap<Long, Long>> getStatsdWakelockData() throws Exception {
         StatsLogReport report = getStatsLogReport();
+        CLog.d("Received the following stats log report: \n" + report.toString());
 
         // Stores total duration of each wakelock across buckets.
-        HashMap<Integer, HashMap<String, Long>> statsdWakelockData = new HashMap<>();
+        HashMap<Integer, HashMap<Long, Long>> statsdWakelockData = new HashMap<>();
 
         for (DurationMetricData data : report.getDurationMetrics().getDataList()) {
             // Gets tag and uid.
-            List<DimensionsValue> dims = data.getDimensionsInWhat().getValueTuple().getDimensionsValueList();
+            List<DimensionsValue> dims = data.getDimensionLeafValuesInWhatList();
             assertTrue("Expected 2 dimensions, received " + dims.size(), dims.size() == 2);
-            String tag = null;
+            boolean hasTag = false;
+            long tag = 0;
             int uid = -1;
             long duration = 0;
             for (DimensionsValue dim : dims) {
-                if (dim.getField() == WakelockStateChanged.TAG_FIELD_NUMBER) {
-                    tag = dim.getValueStr();
-                } else if (dim.getField() == WakelockStateChanged.ATTRIBUTION_NODE_FIELD_NUMBER) {
-                    uid = dim.getValueTuple().getDimensionsValue(0).getValueInt();
+                if (dim.hasValueInt()) {
+                    uid = dim.getValueInt();
+                } else if (dim.hasValueStrHash()) {
+                    hasTag = true;
+                    tag = dim.getValueStrHash();
                 }
             }
-            assertTrue("Did not receive a tag for the wakelock", tag != null);
+            assertTrue("Did not receive a tag for the wakelock", hasTag);
             assertTrue("Did not receive a uid for the wakelock", uid != -1);
 
             // Gets duration.
@@ -294,10 +302,10 @@
 
             // Store the info.
             if (statsdWakelockData.containsKey(uid)) {
-                HashMap<String, Long> tagToDuration = statsdWakelockData.get(uid);
+                HashMap<Long, Long> tagToDuration = statsdWakelockData.get(uid);
                 tagToDuration.put(tag, duration);
             } else {
-                HashMap<String, Long> tagToDuration = new HashMap<>();
+                HashMap<Long, Long> tagToDuration = new HashMap<>();
                 tagToDuration.put(tag, duration);
                 statsdWakelockData.put(uid, tagToDuration);
             }
diff --git a/hostsidetests/sustainedperf/src/android/SustainedPerformance/cts/SustainedPerformanceHostTest.java b/hostsidetests/sustainedperf/src/android/SustainedPerformance/cts/SustainedPerformanceHostTest.java
index 702b15bb..411205e 100644
--- a/hostsidetests/sustainedperf/src/android/SustainedPerformance/cts/SustainedPerformanceHostTest.java
+++ b/hostsidetests/sustainedperf/src/android/SustainedPerformance/cts/SustainedPerformanceHostTest.java
@@ -16,19 +16,21 @@
 
 package android.sustainedPerformance.cts;
 
-import com.android.ddmlib.MultiLineReceiver;
+import com.android.compatibility.common.util.CddTest;
 import com.android.ddmlib.IShellOutputReceiver;
+import com.android.ddmlib.Log;
+import com.android.ddmlib.MultiLineReceiver;
 import com.android.tradefed.device.ITestDevice;
 import com.android.tradefed.testtype.DeviceTestCase;
-import com.android.ddmlib.Log;
-import java.util.Scanner;
+import java.util.*;
 import java.util.ArrayList;
 import java.util.Arrays;
+import java.util.Scanner;
 import java.util.concurrent.TimeUnit;
-import java.util.*;
 /**
  * Test to check if device implements Sustained Performance Mode
  */
+@CddTest(requirement="8.5/C-0-1,C-1-1,C-1-2")
 public class SustainedPerformanceHostTest extends DeviceTestCase {
 
     ITestDevice device;
diff --git a/hostsidetests/theme/assets/P/260dpi.zip b/hostsidetests/theme/assets/28/260dpi.zip
similarity index 91%
rename from hostsidetests/theme/assets/P/260dpi.zip
rename to hostsidetests/theme/assets/28/260dpi.zip
index 68423a45..ac8e5e8 100644
--- a/hostsidetests/theme/assets/P/260dpi.zip
+++ b/hostsidetests/theme/assets/28/260dpi.zip
Binary files differ
diff --git a/hostsidetests/theme/assets/P/280dpi.zip b/hostsidetests/theme/assets/28/280dpi.zip
similarity index 87%
rename from hostsidetests/theme/assets/P/280dpi.zip
rename to hostsidetests/theme/assets/28/280dpi.zip
index 9a09eb4..b415b85 100644
--- a/hostsidetests/theme/assets/P/280dpi.zip
+++ b/hostsidetests/theme/assets/28/280dpi.zip
Binary files differ
diff --git a/hostsidetests/theme/assets/P/300dpi.zip b/hostsidetests/theme/assets/28/300dpi.zip
similarity index 86%
rename from hostsidetests/theme/assets/P/300dpi.zip
rename to hostsidetests/theme/assets/28/300dpi.zip
index 35390b9d..9d1761b 100644
--- a/hostsidetests/theme/assets/P/300dpi.zip
+++ b/hostsidetests/theme/assets/28/300dpi.zip
Binary files differ
diff --git a/hostsidetests/theme/assets/P/340dpi.zip b/hostsidetests/theme/assets/28/340dpi.zip
similarity index 93%
rename from hostsidetests/theme/assets/P/340dpi.zip
rename to hostsidetests/theme/assets/28/340dpi.zip
index a65cc9f..ad774a9 100644
--- a/hostsidetests/theme/assets/P/340dpi.zip
+++ b/hostsidetests/theme/assets/28/340dpi.zip
Binary files differ
diff --git a/hostsidetests/theme/assets/P/360dpi.zip b/hostsidetests/theme/assets/28/360dpi.zip
similarity index 92%
rename from hostsidetests/theme/assets/P/360dpi.zip
rename to hostsidetests/theme/assets/28/360dpi.zip
index a7be2b6..3e1f801 100644
--- a/hostsidetests/theme/assets/P/360dpi.zip
+++ b/hostsidetests/theme/assets/28/360dpi.zip
Binary files differ
diff --git a/hostsidetests/theme/assets/P/400dpi.zip b/hostsidetests/theme/assets/28/400dpi.zip
similarity index 93%
rename from hostsidetests/theme/assets/P/400dpi.zip
rename to hostsidetests/theme/assets/28/400dpi.zip
index f8e62bb..b2b893c 100644
--- a/hostsidetests/theme/assets/P/400dpi.zip
+++ b/hostsidetests/theme/assets/28/400dpi.zip
Binary files differ
diff --git a/hostsidetests/theme/assets/P/420dpi.zip b/hostsidetests/theme/assets/28/420dpi.zip
similarity index 85%
rename from hostsidetests/theme/assets/P/420dpi.zip
rename to hostsidetests/theme/assets/28/420dpi.zip
index 3d70848..cf83d88 100644
--- a/hostsidetests/theme/assets/P/420dpi.zip
+++ b/hostsidetests/theme/assets/28/420dpi.zip
Binary files differ
diff --git a/hostsidetests/theme/assets/28/440dpi.zip b/hostsidetests/theme/assets/28/440dpi.zip
new file mode 100644
index 0000000..267e564
--- /dev/null
+++ b/hostsidetests/theme/assets/28/440dpi.zip
Binary files differ
diff --git a/hostsidetests/theme/assets/P/560dpi.zip b/hostsidetests/theme/assets/28/560dpi.zip
similarity index 91%
rename from hostsidetests/theme/assets/P/560dpi.zip
rename to hostsidetests/theme/assets/28/560dpi.zip
index e1527ed..2398c80 100644
--- a/hostsidetests/theme/assets/P/560dpi.zip
+++ b/hostsidetests/theme/assets/28/560dpi.zip
Binary files differ
diff --git a/hostsidetests/theme/assets/P/hdpi.zip b/hostsidetests/theme/assets/28/hdpi.zip
similarity index 90%
rename from hostsidetests/theme/assets/P/hdpi.zip
rename to hostsidetests/theme/assets/28/hdpi.zip
index 59c6efc..e273ad4 100644
--- a/hostsidetests/theme/assets/P/hdpi.zip
+++ b/hostsidetests/theme/assets/28/hdpi.zip
Binary files differ
diff --git a/hostsidetests/theme/assets/P/ldpi.zip b/hostsidetests/theme/assets/28/ldpi.zip
similarity index 84%
rename from hostsidetests/theme/assets/P/ldpi.zip
rename to hostsidetests/theme/assets/28/ldpi.zip
index 8e408af..19b7c35 100644
--- a/hostsidetests/theme/assets/P/ldpi.zip
+++ b/hostsidetests/theme/assets/28/ldpi.zip
Binary files differ
diff --git a/hostsidetests/theme/assets/P/mdpi.zip b/hostsidetests/theme/assets/28/mdpi.zip
similarity index 93%
rename from hostsidetests/theme/assets/P/mdpi.zip
rename to hostsidetests/theme/assets/28/mdpi.zip
index 9aebe9d..2ee430b 100644
--- a/hostsidetests/theme/assets/P/mdpi.zip
+++ b/hostsidetests/theme/assets/28/mdpi.zip
Binary files differ
diff --git a/hostsidetests/theme/assets/P/tvdpi.zip b/hostsidetests/theme/assets/28/tvdpi.zip
similarity index 83%
rename from hostsidetests/theme/assets/P/tvdpi.zip
rename to hostsidetests/theme/assets/28/tvdpi.zip
index 55525fb..0b0eb65 100644
--- a/hostsidetests/theme/assets/P/tvdpi.zip
+++ b/hostsidetests/theme/assets/28/tvdpi.zip
Binary files differ
diff --git a/hostsidetests/theme/assets/P/xhdpi.zip b/hostsidetests/theme/assets/28/xhdpi.zip
similarity index 96%
rename from hostsidetests/theme/assets/P/xhdpi.zip
rename to hostsidetests/theme/assets/28/xhdpi.zip
index 3fecabe..2820209 100644
--- a/hostsidetests/theme/assets/P/xhdpi.zip
+++ b/hostsidetests/theme/assets/28/xhdpi.zip
Binary files differ
diff --git a/hostsidetests/theme/assets/P/xxhdpi.zip b/hostsidetests/theme/assets/28/xxhdpi.zip
similarity index 97%
rename from hostsidetests/theme/assets/P/xxhdpi.zip
rename to hostsidetests/theme/assets/28/xxhdpi.zip
index 14d7680..72bb49a 100644
--- a/hostsidetests/theme/assets/P/xxhdpi.zip
+++ b/hostsidetests/theme/assets/28/xxhdpi.zip
Binary files differ
diff --git a/hostsidetests/theme/assets/P/xxxhdpi.zip b/hostsidetests/theme/assets/28/xxxhdpi.zip
similarity index 98%
rename from hostsidetests/theme/assets/P/xxxhdpi.zip
rename to hostsidetests/theme/assets/28/xxxhdpi.zip
index aa8d087..2233800 100644
--- a/hostsidetests/theme/assets/P/xxxhdpi.zip
+++ b/hostsidetests/theme/assets/28/xxxhdpi.zip
Binary files differ
diff --git a/hostsidetests/theme/generate_images.py b/hostsidetests/theme/generate_images.py
index 5dcc76f..d8df3bf 100755
--- a/hostsidetests/theme/generate_images.py
+++ b/hostsidetests/theme/generate_images.py
@@ -41,6 +41,7 @@
     360: "360dpi",
     400: "400dpi",
     420: "420dpi",
+    440: "440dpi",
     480: "xxhdpi",
     560: "560dpi",
     640: "xxxhdpi",
diff --git a/run_unit_tests.sh b/run_unit_tests.sh
index 3f29832..e31af09 100755
--- a/run_unit_tests.sh
+++ b/run_unit_tests.sh
@@ -67,9 +67,13 @@
 echo
 
 ############### Run the host side tests ###############
-${CTS_DIR}/common/host-side/tradefed/tests/run_tests.sh
-${CTS_DIR}/common/host-side/manifest-generator/tests/run_tests.sh
-${CTS_DIR}/common/host-side/util/tests/run_tests.sh
-${CTS_DIR}/common/util/tests/run_tests.sh
+# TODO: Change it to the new harness repo once harness
+# code is moved to its own repo. [fix-harness-dir]
+${CTS_DIR}/harness/common/host-side/tradefed/tests/run_tests.sh
+${CTS_DIR}/harness/common/host-side/manifest-generator/tests/run_tests.sh
+${CTS_DIR}/harness/common/host-side/util/tests/run_tests.sh
+${CTS_DIR}/harness/common/util/tests/run_tests.sh
 
-${CTS_DIR}/tools/cts-tradefed/tests/run_tests.sh
+# TODO: Change it to the new harness repo once harness
+# code is moved to its own repo. [fix-harness-dir]
+${CTS_DIR}/harness/tools/cts-tradefed/tests/run_tests.sh
diff --git a/tests/JobScheduler/src/android/jobscheduler/cts/DeviceIdleJobsTest.java b/tests/JobScheduler/src/android/jobscheduler/cts/DeviceIdleJobsTest.java
index 68efcd8..0a78c54 100644
--- a/tests/JobScheduler/src/android/jobscheduler/cts/DeviceIdleJobsTest.java
+++ b/tests/JobScheduler/src/android/jobscheduler/cts/DeviceIdleJobsTest.java
@@ -59,6 +59,7 @@
     private static final long BACKGROUND_JOBS_EXPECTED_DELAY = 3_000;
     private static final long POLL_INTERVAL = 500;
     private static final long DEFAULT_WAIT_TIMEOUT = 1000;
+    private static final long SHELL_TIMEOUT = 3_000;
 
     enum Bucket {
         ACTIVE,
@@ -226,7 +227,7 @@
     private void toggleDeviceIdleState(final boolean idle) throws Exception {
         mUiDevice.executeShellCommand("cmd deviceidle " + (idle ? "force-idle" : "unforce"));
         assertTrue("Could not change device idle state to " + idle,
-                waitUntilTrue(DEFAULT_WAIT_TIMEOUT, () -> {
+                waitUntilTrue(SHELL_TIMEOUT, () -> {
                     synchronized (DeviceIdleJobsTest.this) {
                         return mDeviceInDoze == idle;
                     }
@@ -279,7 +280,7 @@
         if (interrupted) {
             Thread.currentThread().interrupt();
         }
-        return waitUntilTrue(DEFAULT_WAIT_TIMEOUT, () -> !isTestAppTempWhitelisted());
+        return waitUntilTrue(SHELL_TIMEOUT, () -> !isTestAppTempWhitelisted());
     }
 
     private boolean awaitJobStart(long maxWait) throws Exception {
diff --git a/tests/accessibility/AndroidManifest.xml b/tests/accessibility/AndroidManifest.xml
index 9a9f727..da993ed 100644
--- a/tests/accessibility/AndroidManifest.xml
+++ b/tests/accessibility/AndroidManifest.xml
@@ -17,7 +17,8 @@
  -->
 
 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
-          package="android.view.accessibility.cts">
+          package="android.view.accessibility.cts"
+          android:targetSandboxVersion="2">
 
     <uses-permission android:name="android.permission.DISABLE_KEYGUARD" />
     <uses-permission android:name="android.permission.WRITE_SECURE_SETTINGS" />
diff --git a/tests/accessibility/AndroidTest.xml b/tests/accessibility/AndroidTest.xml
index 5ea8df1..6d5bac28 100644
--- a/tests/accessibility/AndroidTest.xml
+++ b/tests/accessibility/AndroidTest.xml
@@ -16,12 +16,16 @@
 <configuration description="Config for CTS Accessibility test cases">
     <option name="test-suite-tag" value="cts" />
     <option name="config-descriptor:metadata" key="component" value="framework" />
+    <target_preparer class="com.android.tradefed.targetprep.RunCommandTargetPreparer">
+        <option name="run-command" value="cmd accessibility set-bind-instant-service-allowed true" />
+        <option name="teardown-command" value="cmd accessibility set-bind-instant-service-allowed false" />
+    </target_preparer>
     <target_preparer class="com.android.tradefed.targetprep.suite.SuiteApkInstaller">
         <option name="cleanup-apks" value="true" />
         <option name="test-file-name" value="CtsAccessibilityTestCases.apk" />
     </target_preparer>
     <test class="com.android.tradefed.testtype.AndroidJUnitTest" >
         <option name="package" value="android.view.accessibility.cts" />
-        <option name="runtime-hint" value="8m" />
+        <option name="runtime-hint" value="8m"/>
     </test>
 </configuration>
diff --git a/tests/accessibility/src/android/view/accessibility/cts/AccessibilityManagerTest.java b/tests/accessibility/src/android/view/accessibility/cts/AccessibilityManagerTest.java
index ccb5a6d..8c87d78 100644
--- a/tests/accessibility/src/android/view/accessibility/cts/AccessibilityManagerTest.java
+++ b/tests/accessibility/src/android/view/accessibility/cts/AccessibilityManagerTest.java
@@ -58,6 +58,7 @@
                 getInstrumentation().getContext().getSystemService(Service.ACCESSIBILITY_SERVICE);
         mTargetContext = getInstrumentation().getTargetContext();
         mHandler = new Handler(mTargetContext.getMainLooper());
+        ServiceControlUtils.turnAccessibilityOff(getInstrumentation());
     }
 
     @Override
diff --git a/tests/accessibilityservice/Android.mk b/tests/accessibilityservice/Android.mk
index 4f23a25..44dee81 100644
--- a/tests/accessibilityservice/Android.mk
+++ b/tests/accessibilityservice/Android.mk
@@ -19,9 +19,10 @@
 LOCAL_MODULE_TAGS := optional
 
 LOCAL_STATIC_JAVA_LIBRARIES := \
-	ctstestrunner \
-	mockito-target-minus-junit4 \
-	compatibility-device-util
+    ctstestrunner \
+    mockito-target-minus-junit4 \
+    compatibility-device-util \
+    platform-test-annotations
 
 LOCAL_JAVA_LIBRARIES := android.test.runner.stubs android.test.base.stubs
 
diff --git a/tests/accessibilityservice/AndroidManifest.xml b/tests/accessibilityservice/AndroidManifest.xml
index 086bbcd..5214410 100644
--- a/tests/accessibilityservice/AndroidManifest.xml
+++ b/tests/accessibilityservice/AndroidManifest.xml
@@ -16,7 +16,8 @@
  -->
 
 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
-          package="android.accessibilityservice.cts">
+          package="android.accessibilityservice.cts"
+          android:targetSandboxVersion="2">
 
     <uses-permission android:name="android.permission.DISABLE_KEYGUARD" />
     <uses-permission android:name="android.permission.WRITE_SECURE_SETTINGS" />
@@ -62,9 +63,13 @@
             android:name=".AccessibilityGestureDispatchTest$GestureDispatchActivity"
             android:screenOrientation="portrait" />
 
+        <activity
+            android:label="@string/accessibility_soft_keyboard_modes_activity"
+            android:name=".AccessibilitySoftKeyboardModesTest$SoftKeyboardModesActivity" />
+
         <service
-            android:name=".StubGestureAccessibilityService"
-            android:permission="android.permission.BIND_ACCESSIBILITY_SERVICE">
+                android:name=".StubGestureAccessibilityService"
+                android:permission="android.permission.BIND_ACCESSIBILITY_SERVICE">
             <intent-filter>
                 <action android:name="android.accessibilityservice.AccessibilityService" />
                 <category android:name="android.accessibilityservice.category.FEEDBACK_GENERIC" />
@@ -76,21 +81,17 @@
         </service>
 
         <service
-            android:name=".AccessibilityGestureDetectorTest$StubService"
-            android:permission="android.permission.BIND_ACCESSIBILITY_SERVICE">
+                android:name=".AccessibilityGestureDetectorTest$StubService"
+                android:permission="android.permission.BIND_ACCESSIBILITY_SERVICE">
             <intent-filter>
                 <action android:name="android.accessibilityservice.AccessibilityService" />
                 <category android:name="android.accessibilityservice.category.FEEDBACK_GENERIC" />
             </intent-filter>
             <meta-data
-                android:name="android.accessibilityservice"
-                android:resource="@xml/stub_gesture_detect_a11y_service" />
+                    android:name="android.accessibilityservice"
+                    android:resource="@xml/stub_gesture_detect_a11y_service" />
         </service>
 
-        <activity
-            android:label="@string/accessibility_soft_keyboard_modes_activity"
-            android:name=".AccessibilitySoftKeyboardModesTest$SoftKeyboardModesActivity" />
-
         <service
             android:name=".InstrumentedAccessibilityService"
             android:label="@string/title_soft_keyboard_modes_accessibility_service"
diff --git a/tests/accessibilityservice/AndroidTest.xml b/tests/accessibilityservice/AndroidTest.xml
index 0454a298..20a8bff 100644
--- a/tests/accessibilityservice/AndroidTest.xml
+++ b/tests/accessibilityservice/AndroidTest.xml
@@ -16,6 +16,10 @@
 <configuration description="Config for CTS accessibility service test cases">
     <option name="test-suite-tag" value="cts" />
     <option name="config-descriptor:metadata" key="component" value="framework" />
+    <target_preparer class="com.android.tradefed.targetprep.RunCommandTargetPreparer">
+        <option name="run-command" value="cmd accessibility set-bind-instant-service-allowed true" />
+        <option name="teardown-command" value="cmd accessibility set-bind-instant-service-allowed false" />
+    </target_preparer>
     <target_preparer class="com.android.tradefed.targetprep.suite.SuiteApkInstaller">
         <option name="cleanup-apks" value="true" />
         <option name="test-file-name" value="CtsAccessibilityServiceTestCases.apk" />
diff --git a/tests/accessibilityservice/src/android/accessibilityservice/cts/AccessibilityButtonTest.java b/tests/accessibilityservice/src/android/accessibilityservice/cts/AccessibilityButtonTest.java
index 359c6ac..5e1fd3b 100644
--- a/tests/accessibilityservice/src/android/accessibilityservice/cts/AccessibilityButtonTest.java
+++ b/tests/accessibilityservice/src/android/accessibilityservice/cts/AccessibilityButtonTest.java
@@ -16,6 +16,7 @@
 
 import android.accessibilityservice.AccessibilityButtonController;
 import android.app.Instrumentation;
+import android.platform.test.annotations.AppModeFull;
 import android.support.test.InstrumentationRegistry;
 import android.support.test.runner.AndroidJUnit4;
 
@@ -62,6 +63,7 @@
     }
 
     @Test
+    @AppModeFull
     public void testCallbackRegistrationUnregistration_serviceDoesNotCrash() {
         mButtonController.registerAccessibilityButtonCallback(mStubCallback);
         mButtonController.unregisterAccessibilityButtonCallback(mStubCallback);
diff --git a/tests/accessibilityservice/src/android/accessibilityservice/cts/AccessibilityEndToEndTest.java b/tests/accessibilityservice/src/android/accessibilityservice/cts/AccessibilityEndToEndTest.java
index a3793ae..d535fab 100644
--- a/tests/accessibilityservice/src/android/accessibilityservice/cts/AccessibilityEndToEndTest.java
+++ b/tests/accessibilityservice/src/android/accessibilityservice/cts/AccessibilityEndToEndTest.java
@@ -50,6 +50,7 @@
 import android.content.pm.PackageManager;
 import android.content.res.Configuration;
 import android.os.Process;
+import android.platform.test.annotations.AppModeFull;
 import android.platform.test.annotations.Presubmit;
 import android.test.suitebuilder.annotation.MediumTest;
 import android.text.TextUtils;
@@ -337,6 +338,7 @@
     }
 
     @MediumTest
+    @AppModeFull
     @SuppressWarnings("deprecation")
     @Presubmit
     public void testTypeNotificationStateChangedAccessibilityEvent() throws Throwable {
@@ -480,6 +482,7 @@
         }
     }
 
+    @AppModeFull
     @MediumTest
     @Presubmit
     public void testPackageNameCannotBeFakedAppWidget() throws Exception {
diff --git a/tests/accessibilityservice/src/android/accessibilityservice/cts/AccessibilityFingerprintGestureTest.java b/tests/accessibilityservice/src/android/accessibilityservice/cts/AccessibilityFingerprintGestureTest.java
index 0e9c181..fbd2361 100644
--- a/tests/accessibilityservice/src/android/accessibilityservice/cts/AccessibilityFingerprintGestureTest.java
+++ b/tests/accessibilityservice/src/android/accessibilityservice/cts/AccessibilityFingerprintGestureTest.java
@@ -29,6 +29,7 @@
 import android.app.Instrumentation;
 import android.hardware.fingerprint.FingerprintManager;
 import android.os.CancellationSignal;
+import android.platform.test.annotations.AppModeFull;
 import android.support.test.InstrumentationRegistry;
 import android.support.test.rule.ActivityTestRule;
 import android.support.test.runner.AndroidJUnit4;
@@ -45,6 +46,7 @@
  * Verify that a service listening for fingerprint gestures gets called back when apps
  * use the fingerprint sensor to authenticate.
  */
+@AppModeFull
 @RunWith(AndroidJUnit4.class)
 public class AccessibilityFingerprintGestureTest {
     private static final int FINGERPRINT_CALLBACK_TIMEOUT = 3000;
diff --git a/tests/accessibilityservice/src/android/accessibilityservice/cts/AccessibilityGestureDetectorTest.java b/tests/accessibilityservice/src/android/accessibilityservice/cts/AccessibilityGestureDetectorTest.java
index 6ac693f..01d841e 100644
--- a/tests/accessibilityservice/src/android/accessibilityservice/cts/AccessibilityGestureDetectorTest.java
+++ b/tests/accessibilityservice/src/android/accessibilityservice/cts/AccessibilityGestureDetectorTest.java
@@ -27,6 +27,7 @@
 import android.content.pm.PackageManager;
 import android.graphics.Path;
 import android.graphics.Point;
+import android.platform.test.annotations.AppModeFull;
 import android.support.test.InstrumentationRegistry;
 import android.support.test.runner.AndroidJUnit4;
 import android.util.DisplayMetrics;
@@ -103,6 +104,7 @@
     }
 
     @Test
+    @AppModeFull
     public void testRecognizeGesturePath() {
         if (!mHasTouchScreen || !mScreenBigEnough) {
             return;
diff --git a/tests/accessibilityservice/src/android/accessibilityservice/cts/AccessibilityGestureDispatchTest.java b/tests/accessibilityservice/src/android/accessibilityservice/cts/AccessibilityGestureDispatchTest.java
index 60867cd..cdd109c 100644
--- a/tests/accessibilityservice/src/android/accessibilityservice/cts/AccessibilityGestureDispatchTest.java
+++ b/tests/accessibilityservice/src/android/accessibilityservice/cts/AccessibilityGestureDispatchTest.java
@@ -45,6 +45,7 @@
 import android.graphics.PointF;
 import android.os.Bundle;
 import android.os.SystemClock;
+import android.platform.test.annotations.AppModeFull;
 import android.test.ActivityInstrumentationTestCase2;
 import android.util.Log;
 import android.view.Display;
@@ -65,6 +66,7 @@
 /**
  * Verify that gestures dispatched from an accessibility service show up in the current UI
  */
+@AppModeFull
 public class AccessibilityGestureDispatchTest extends
         ActivityInstrumentationTestCase2<AccessibilityGestureDispatchTest.GestureDispatchActivity> {
     private static final String TAG = AccessibilityGestureDispatchTest.class.getSimpleName();
diff --git a/tests/accessibilityservice/src/android/accessibilityservice/cts/AccessibilityGlobalActionsTest.java b/tests/accessibilityservice/src/android/accessibilityservice/cts/AccessibilityGlobalActionsTest.java
index 95e4753..5c45080 100644
--- a/tests/accessibilityservice/src/android/accessibilityservice/cts/AccessibilityGlobalActionsTest.java
+++ b/tests/accessibilityservice/src/android/accessibilityservice/cts/AccessibilityGlobalActionsTest.java
@@ -18,6 +18,7 @@
 
 import android.accessibilityservice.AccessibilityService;
 import android.os.SystemClock;
+import android.platform.test.annotations.AppModeFull;
 import android.platform.test.annotations.Presubmit;
 import android.test.InstrumentationTestCase;
 import android.test.suitebuilder.annotation.MediumTest;
@@ -28,6 +29,7 @@
  * Test global actions
  */
 @Presubmit
+@AppModeFull
 public class AccessibilityGlobalActionsTest extends InstrumentationTestCase {
     /**
      * Timeout required for pending Binder calls or event processing to
@@ -151,5 +153,4 @@
                 TIMEOUT_ACCESSIBILITY_STATE_IDLE,
                 TIMEOUT_ASYNC_PROCESSING);
     }
-
 }
diff --git a/tests/accessibilityservice/src/android/accessibilityservice/cts/AccessibilityMagnificationTest.java b/tests/accessibilityservice/src/android/accessibilityservice/cts/AccessibilityMagnificationTest.java
index 8446702..c574541 100644
--- a/tests/accessibilityservice/src/android/accessibilityservice/cts/AccessibilityMagnificationTest.java
+++ b/tests/accessibilityservice/src/android/accessibilityservice/cts/AccessibilityMagnificationTest.java
@@ -29,6 +29,7 @@
 import android.app.Instrumentation;
 import android.content.Context;
 import android.graphics.Region;
+import android.platform.test.annotations.AppModeFull;
 import android.test.InstrumentationTestCase;
 import android.util.DisplayMetrics;
 import android.view.WindowManager;
@@ -38,6 +39,7 @@
 /**
  * Class for testing {@link AccessibilityServiceInfo}.
  */
+@AppModeFull
 public class AccessibilityMagnificationTest extends InstrumentationTestCase {
 
     /** Maximum timeout when waiting for a magnification callback. */
diff --git a/tests/accessibilityservice/src/android/accessibilityservice/cts/AccessibilitySettingsTest.java b/tests/accessibilityservice/src/android/accessibilityservice/cts/AccessibilitySettingsTest.java
index 6575034..f01251a 100644
--- a/tests/accessibilityservice/src/android/accessibilityservice/cts/AccessibilitySettingsTest.java
+++ b/tests/accessibilityservice/src/android/accessibilityservice/cts/AccessibilitySettingsTest.java
@@ -19,6 +19,7 @@
 import android.content.Intent;
 import android.content.pm.PackageManager;
 import android.content.pm.ResolveInfo;
+import android.platform.test.annotations.AppModeFull;
 import android.platform.test.annotations.Presubmit;
 import android.provider.Settings;
 import android.test.AndroidTestCase;
@@ -34,6 +35,7 @@
 public class AccessibilitySettingsTest extends AndroidTestCase {
 
     @MediumTest
+    @AppModeFull
     public void testAccessibilitySettingsIntentHandled() throws Throwable {
         PackageManager packageManager = mContext.getPackageManager();
         Intent intent = new Intent(Settings.ACTION_ACCESSIBILITY_SETTINGS);
diff --git a/tests/accessibilityservice/src/android/accessibilityservice/cts/AccessibilitySoftKeyboardModesTest.java b/tests/accessibilityservice/src/android/accessibilityservice/cts/AccessibilitySoftKeyboardModesTest.java
index c179409..caae032 100644
--- a/tests/accessibilityservice/src/android/accessibilityservice/cts/AccessibilitySoftKeyboardModesTest.java
+++ b/tests/accessibilityservice/src/android/accessibilityservice/cts/AccessibilitySoftKeyboardModesTest.java
@@ -26,6 +26,7 @@
 import android.os.IBinder;
 import android.os.ResultReceiver;
 import android.os.SystemClock;
+import android.platform.test.annotations.AppModeFull;
 import android.test.ActivityInstrumentationTestCase2;
 import android.view.View;
 import android.view.accessibility.AccessibilityEvent;
@@ -42,6 +43,7 @@
 /**
  * Test cases for testing the accessibility APIs for interacting with the soft keyboard show mode.
  */
+@AppModeFull
 public class AccessibilitySoftKeyboardModesTest extends ActivityInstrumentationTestCase2
         <AccessibilitySoftKeyboardModesTest.SoftKeyboardModesActivity> {
 
diff --git a/tests/accessibilityservice/src/android/accessibilityservice/cts/AccessibilityVolumeTest.java b/tests/accessibilityservice/src/android/accessibilityservice/cts/AccessibilityVolumeTest.java
index c718718..b53df79 100644
--- a/tests/accessibilityservice/src/android/accessibilityservice/cts/AccessibilityVolumeTest.java
+++ b/tests/accessibilityservice/src/android/accessibilityservice/cts/AccessibilityVolumeTest.java
@@ -20,6 +20,7 @@
 import android.app.Instrumentation;
 import android.content.pm.PackageManager;
 import android.media.AudioManager;
+import android.platform.test.annotations.AppModeFull;
 import android.platform.test.annotations.Presubmit;
 import android.support.test.InstrumentationRegistry;
 import android.support.test.runner.AndroidJUnit4;
@@ -63,6 +64,7 @@
     }
 
     @Test
+    @AppModeFull
     public void testChangeAccessibilityVolume_inAccessibilityService_shouldWork() {
         if (mSingleVolume) {
             return;
diff --git a/tests/accessibilityservice/src/android/accessibilityservice/cts/AccessibilityWindowQueryTest.java b/tests/accessibilityservice/src/android/accessibilityservice/cts/AccessibilityWindowQueryTest.java
index c827364..ea98078 100755
--- a/tests/accessibilityservice/src/android/accessibilityservice/cts/AccessibilityWindowQueryTest.java
+++ b/tests/accessibilityservice/src/android/accessibilityservice/cts/AccessibilityWindowQueryTest.java
@@ -47,6 +47,7 @@
 import android.content.pm.PackageManager;
 import android.content.res.Resources;
 import android.graphics.Rect;
+import android.platform.test.annotations.AppModeFull;
 import android.test.suitebuilder.annotation.MediumTest;
 import android.view.Gravity;
 import android.view.View;
@@ -76,6 +77,7 @@
  * These APIs allow exploring the screen and requesting an action to be performed
  * on a given view from an AccessibilityService.
  */
+@AppModeFull
 public class AccessibilityWindowQueryTest
         extends AccessibilityActivityTestCase<AccessibilityWindowQueryActivity> {
     private static String CONTENT_VIEW_RES_NAME =
diff --git a/tests/accessibilityservice/src/android/accessibilityservice/cts/GestureDescriptionTest.java b/tests/accessibilityservice/src/android/accessibilityservice/cts/GestureDescriptionTest.java
index 4c1d064..92821b80 100644
--- a/tests/accessibilityservice/src/android/accessibilityservice/cts/GestureDescriptionTest.java
+++ b/tests/accessibilityservice/src/android/accessibilityservice/cts/GestureDescriptionTest.java
@@ -18,6 +18,7 @@
 import android.accessibilityservice.GestureDescription.StrokeDescription;
 import android.graphics.Path;
 import android.graphics.PathMeasure;
+import android.platform.test.annotations.AppModeFull;
 import android.platform.test.annotations.Presubmit;
 import android.test.InstrumentationTestCase;
 
@@ -25,6 +26,7 @@
  * Tests for creating gesture descriptions.
  */
 @Presubmit
+@AppModeFull
 public class GestureDescriptionTest extends InstrumentationTestCase {
     static final int NOMINAL_PATH_DURATION = 100;
     private Path mNominalPath;
diff --git a/tests/accessibilityservice/src/android/accessibilityservice/cts/InstrumentedAccessibilityService.java b/tests/accessibilityservice/src/android/accessibilityservice/cts/InstrumentedAccessibilityService.java
index 53a70b3..fe595a4f 100644
--- a/tests/accessibilityservice/src/android/accessibilityservice/cts/InstrumentedAccessibilityService.java
+++ b/tests/accessibilityservice/src/android/accessibilityservice/cts/InstrumentedAccessibilityService.java
@@ -143,7 +143,6 @@
         if (enabledServices != null) {
             assertFalse("Service is already enabled", enabledServices.contains(serviceName));
         }
-
         final AccessibilityManager manager = (AccessibilityManager) context.getSystemService(
                 Context.ACCESSIBILITY_SERVICE);
         final List<AccessibilityServiceInfo> serviceInfos =
diff --git a/tests/accessibilityservice/src/android/accessibilityservice/cts/MagnificationGestureHandlerTest.java b/tests/accessibilityservice/src/android/accessibilityservice/cts/MagnificationGestureHandlerTest.java
index a9bd769..2e89f06 100644
--- a/tests/accessibilityservice/src/android/accessibilityservice/cts/MagnificationGestureHandlerTest.java
+++ b/tests/accessibilityservice/src/android/accessibilityservice/cts/MagnificationGestureHandlerTest.java
@@ -52,6 +52,7 @@
 import android.content.pm.PackageManager;
 import android.graphics.PointF;
 import android.os.SystemClock;
+import android.platform.test.annotations.AppModeFull;
 import android.provider.Settings;
 import android.support.test.InstrumentationRegistry;
 import android.support.test.rule.ActivityTestRule;
@@ -73,6 +74,7 @@
  * Class for testing magnification.
  */
 @RunWith(AndroidJUnit4.class)
+@AppModeFull
 public class MagnificationGestureHandlerTest {
 
     private static final double MIN_SCALE = 1.2;
diff --git a/tests/accessibilityservice/test-apps/WidgetProvider/AndroidManifest.xml b/tests/accessibilityservice/test-apps/WidgetProvider/AndroidManifest.xml
index 4a06f03..e1628bf 100644
--- a/tests/accessibilityservice/test-apps/WidgetProvider/AndroidManifest.xml
+++ b/tests/accessibilityservice/test-apps/WidgetProvider/AndroidManifest.xml
@@ -16,7 +16,8 @@
  -->
 
 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
-          package="foo.bar.baz">
+          package="foo.bar.baz"
+          android:targetSandboxVersion="2">
 
     <application>
         <receiver android:name="foo.bar.baz.MyAppWidgetProvider" >
diff --git a/tests/app/src/android/app/cts/ActivityManagerProcessStateTest.java b/tests/app/src/android/app/cts/ActivityManagerProcessStateTest.java
index 171fb11..c852bec 100644
--- a/tests/app/src/android/app/cts/ActivityManagerProcessStateTest.java
+++ b/tests/app/src/android/app/cts/ActivityManagerProcessStateTest.java
@@ -33,6 +33,8 @@
 import android.content.Context;
 import android.content.Intent;
 import android.content.pm.ApplicationInfo;
+import android.content.pm.PackageManager;
+import android.content.res.Configuration;
 import android.os.IBinder;
 import android.os.Parcel;
 import android.os.PowerManager;
@@ -1063,11 +1065,33 @@
         }
     }
 
+    private boolean supportsCantSaveState() {
+        if (mContext.getPackageManager().hasSystemFeature(
+                PackageManager.FEATURE_CANT_SAVE_STATE)) {
+            return true;
+        }
+
+        // Most types of devices need to support this.
+        int mode = mContext.getResources().getConfiguration().uiMode
+                & Configuration.UI_MODE_TYPE_MASK;
+        if (mode != Configuration.UI_MODE_TYPE_WATCH
+                && mode != Configuration.UI_MODE_TYPE_APPLIANCE) {
+            // Most devices must support the can't save state feature.
+            throw new IllegalStateException("Devices that are not watches or appliances must "
+                    + "support FEATURE_CANT_SAVE_STATE");
+        }
+        return false;
+    }
+
     /**
      * Test that a single "can't save state" app has the proper process management
      * semantics.
      */
     public void testCantSaveStateLaunchAndBackground() throws Exception {
+        if (!supportsCantSaveState()) {
+            return;
+        }
+
         final Intent activityIntent = new Intent();
         activityIntent.setPackage(CANT_SAVE_STATE_1_PACKAGE_NAME);
         activityIntent.setAction(Intent.ACTION_MAIN);
@@ -1188,6 +1212,10 @@
      * Test that switching between two "can't save state" apps is handled properly.
      */
     public void testCantSaveStateLaunchAndSwitch() throws Exception {
+        if (!supportsCantSaveState()) {
+            return;
+        }
+
         final Intent activity1Intent = new Intent();
         activity1Intent.setPackage(CANT_SAVE_STATE_1_PACKAGE_NAME);
         activity1Intent.setAction(Intent.ACTION_MAIN);
diff --git a/tests/app/src/android/app/cts/NotificationManagerTest.java b/tests/app/src/android/app/cts/NotificationManagerTest.java
index e6d2712..1e4d9d9 100644
--- a/tests/app/src/android/app/cts/NotificationManagerTest.java
+++ b/tests/app/src/android/app/cts/NotificationManagerTest.java
@@ -24,6 +24,7 @@
 import static android.app.NotificationManager.Policy.SUPPRESSED_EFFECT_SCREEN_OFF;
 import static android.app.NotificationManager.Policy.SUPPRESSED_EFFECT_SCREEN_ON;
 import static android.app.NotificationManager.Policy.SUPPRESSED_EFFECT_STATUS_BAR;
+import static android.content.pm.PackageManager.FEATURE_WATCH;
 
 import android.app.ActivityManager;
 import android.app.Instrumentation;
@@ -38,6 +39,7 @@
 import android.content.ComponentName;
 import android.content.Context;
 import android.content.Intent;
+import android.content.pm.PackageManager;
 import android.graphics.Bitmap;
 import android.graphics.drawable.Icon;
 import android.media.AudioAttributes;
@@ -70,6 +72,7 @@
     final boolean DEBUG = false;
     final String NOTIFICATION_CHANNEL_ID = "NotificationManagerTest";
 
+    private PackageManager mPackageManager;
     private NotificationManager mNotificationManager;
     private ActivityManager mActivityManager;
     private String mId;
@@ -87,6 +90,7 @@
         mNotificationManager.createNotificationChannel(new NotificationChannel(
                 NOTIFICATION_CHANNEL_ID, "name", NotificationManager.IMPORTANCE_DEFAULT));
         mActivityManager = (ActivityManager) mContext.getSystemService(Context.ACTIVITY_SERVICE);
+        mPackageManager = mContext.getPackageManager();
         // delay between tests so notifications aren't dropped by the rate limiter
         try {
             Thread.sleep(500);
@@ -466,6 +470,10 @@
     }
 
     public void testSuspendPackage() throws Exception {
+        if (mActivityManager.isLowRamDevice() && !mPackageManager.hasSystemFeature(FEATURE_WATCH)) {
+            return;
+        }
+
         toggleListenerAccess(MockNotificationListener.getId(),
                 InstrumentationRegistry.getInstrumentation(), true);
         Thread.sleep(500); // wait for listener to be allowed
diff --git a/tests/app/src/android/app/cts/SystemFeaturesTest.java b/tests/app/src/android/app/cts/SystemFeaturesTest.java
index fb31878..37e286e 100644
--- a/tests/app/src/android/app/cts/SystemFeaturesTest.java
+++ b/tests/app/src/android/app/cts/SystemFeaturesTest.java
@@ -39,6 +39,7 @@
 import android.net.sip.SipManager;
 import android.net.wifi.WifiManager;
 import android.nfc.NfcAdapter;
+import android.os.Build;
 import android.telephony.TelephonyManager;
 import android.test.InstrumentationTestCase;
 
@@ -99,6 +100,11 @@
 
         for (String featureName : notOfficialFeatures) {
             if (featureName != null) {
+                if (!Build.VERSION.CODENAME.equals("REL") &&
+                    featureName.equals("android.software.preview_sdk")) {
+                    // Skips preview_sdk in non-release build.
+                    continue;
+                }
                 assertFalse("Use a different namespace than 'android' for " + featureName,
                         featureName.startsWith("android"));
             }
@@ -488,7 +494,8 @@
         if (!mPackageManager.hasSystemFeature(PackageManager.FEATURE_AUTOMOTIVE) &&
                 !mPackageManager.hasSystemFeature(PackageManager.FEATURE_TELEVISION) &&
                 !mPackageManager.hasSystemFeature(PackageManager.FEATURE_WATCH) &&
-                !mPackageManager.hasSystemFeature(PackageManager.FEATURE_EMBEDDED)) {
+                !mPackageManager.hasSystemFeature(PackageManager.FEATURE_EMBEDDED) &&
+                !mPackageManager.hasSystemFeature(PackageManager.FEATURE_PC)) {
             // USB accessory mode is only a requirement for devices with USB ports supporting
             // peripheral mode. As there is no public API to distinguish a device with only host
             // mode support from having both peripheral and host support, the test may have
diff --git a/tests/autofillservice/AndroidManifest.xml b/tests/autofillservice/AndroidManifest.xml
index 2af9b90..1221128 100644
--- a/tests/autofillservice/AndroidManifest.xml
+++ b/tests/autofillservice/AndroidManifest.xml
@@ -15,7 +15,8 @@
  * limitations under the License.
 -->
 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
-    package="android.autofillservice.cts" >
+    package="android.autofillservice.cts"
+    android:targetSandboxVersion="2">
 
     <uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW"/>
     <uses-permission android:name="android.permission.MANAGE_ACTIVITY_STACKS"/>
diff --git a/tests/autofillservice/AndroidTest.xml b/tests/autofillservice/AndroidTest.xml
index e8cfc3c..a94da63 100644
--- a/tests/autofillservice/AndroidTest.xml
+++ b/tests/autofillservice/AndroidTest.xml
@@ -22,6 +22,12 @@
     <option name="test-file-name" value="CtsAutoFillServiceTestCases.apk" />
   </target_preparer>
 
+  <!--  TODO: preparer below should be enabled only when running as cts-instant -->
+  <target_preparer class="com.android.tradefed.targetprep.RunCommandTargetPreparer">
+    <option name="run-command" value="cmd autofill set bind-instant-service-allowed true" />
+    <option name="teardown-command" value="cmd autofill set bind-instant-service-allowed false" />
+  </target_preparer>
+
   <test class="com.android.tradefed.testtype.AndroidJUnitTest">
     <option name="package" value="android.autofillservice.cts" />
     <!-- 20x default timeout of 600sec -->
diff --git a/tests/autofillservice/src/android/autofillservice/cts/AuthenticationTest.java b/tests/autofillservice/src/android/autofillservice/cts/AuthenticationTest.java
index ddd0191..6e3308d 100644
--- a/tests/autofillservice/src/android/autofillservice/cts/AuthenticationTest.java
+++ b/tests/autofillservice/src/android/autofillservice/cts/AuthenticationTest.java
@@ -35,6 +35,7 @@
 import android.autofillservice.cts.InstrumentedAutoFillService.SaveRequest;
 import android.content.IntentSender;
 import android.os.Bundle;
+import android.platform.test.annotations.AppModeFull;
 import android.support.test.uiautomator.UiObject2;
 import android.view.View;
 import android.view.autofill.AutofillValue;
@@ -52,6 +53,7 @@
     }
 
     @Test
+    @AppModeFull // testDatasetAuthTwoFields() is enough to test ephemeral apps support
     public void testDatasetAuthTwoFieldsUserCancelsFirstAttempt() throws Exception {
         datasetAuthTwoFields(true);
     }
@@ -134,6 +136,7 @@
     }
 
     @Test
+    @AppModeFull // testDatasetAuthTwoFields() is enough to test ephemeral apps support
     public void testDatasetAuthTwoFieldsReplaceResponse() throws Exception {
         // Set service.
         enableService();
@@ -195,6 +198,7 @@
     }
 
     @Test
+    @AppModeFull // testDatasetAuthTwoFields() is enough to test ephemeral apps support
     public void testDatasetAuthTwoFieldsNoValues() throws Exception {
         // Set service.
         enableService();
@@ -238,6 +242,7 @@
     }
 
     @Test
+    @AppModeFull // testDatasetAuthTwoFields() is enough to test ephemeral apps support
     public void testDatasetAuthTwoDatasets() throws Exception {
         // Set service.
         enableService();
@@ -292,11 +297,13 @@
     }
 
     @Test
+    @AppModeFull // testDatasetAuthTwoFields() is enough to test ephemeral apps support
     public void testDatasetAuthMixedSelectAuth() throws Exception {
         datasetAuthMixedTest(true);
     }
 
     @Test
+    @AppModeFull // testDatasetAuthTwoFields() is enough to test ephemeral apps support
     public void testDatasetAuthMixedSelectNonAuth() throws Exception {
         datasetAuthMixedTest(false);
     }
@@ -356,6 +363,7 @@
     }
 
     @Test
+    @AppModeFull // testDatasetAuthFilteringUsingRegex() is enough to test ephemeral apps support
     public void testDatasetAuthNoFiltering() throws Exception {
         // Set service.
         enableService();
@@ -413,6 +421,7 @@
     }
 
     @Test
+    @AppModeFull // testDatasetAuthFilteringUsingRegex() is enough to test ephemeral apps support
     public void testDatasetAuthFilteringUsingAutofillValue() throws Exception {
         // Set service.
         enableService();
@@ -568,11 +577,13 @@
     }
 
     @Test
+    @AppModeFull // testDatasetAuthFilteringUsingRegex() is enough to test ephemeral apps support
     public void testDatasetAuthMixedFilteringSelectAuth() throws Exception {
         datasetAuthMixedFilteringTest(true);
     }
 
     @Test
+    @AppModeFull // testDatasetAuthFilteringUsingRegex() is enough to test ephemeral apps support
     public void testDatasetAuthMixedFilteringSelectNonAuth() throws Exception {
         datasetAuthMixedFilteringTest(false);
     }
@@ -657,11 +668,13 @@
     }
 
     @Test
+    @AppModeFull // testDatasetAuthClientStateSetOnIntentOnly() is enough to test ephemeral apps
     public void testDatasetAuthClientStateSetOnFillResponseOnly() throws Exception {
         fillDatasetAuthWithClientState(ClientStateLocation.FILL_RESPONSE_ONLY);
     }
 
     @Test
+    @AppModeFull // testDatasetAuthClientStateSetOnIntentOnly() is enough to test ephemeral apps
     public void testDatasetAuthClientStateSetOnIntentAndFillResponse() throws Exception {
         fillDatasetAuthWithClientState(ClientStateLocation.BOTH);
     }
@@ -730,6 +743,7 @@
     }
 
     @Test
+    @AppModeFull // testFillResponseAuthBothFields() is enough to test ephemeral apps support
     public void testFillResponseAuthBothFieldsUserCancelsFirstAttempt() throws Exception {
         fillResponseAuthBothFields(true);
     }
@@ -823,6 +837,7 @@
     }
 
     @Test
+    @AppModeFull // testFillResponseAuthBothFields() is enough to test ephemeral apps support
     public void testFillResponseAuthJustOneField() throws Exception {
         // Set service.
         enableService();
@@ -887,6 +902,7 @@
     }
 
     @Test
+    @AppModeFull // testFillResponseAuthBothFields() is enough to test ephemeral apps support
     public void testFillResponseAuthWhenAppCallsCancel() throws Exception {
         // Set service.
         enableService();
@@ -939,11 +955,13 @@
     }
 
     @Test
+    @AppModeFull // testFillResponseAuthBothFields() is enough to test ephemeral apps support
     public void testFillResponseAuthServiceHasNoDataButCanSave() throws Exception {
         fillResponseAuthServiceHasNoDataTest(true);
     }
 
     @Test
+    @AppModeFull // testFillResponseAuthBothFields() is enough to test ephemeral apps support
     public void testFillResponseAuthServiceHasNoData() throws Exception {
         fillResponseAuthServiceHasNoDataTest(false);
     }
@@ -1016,11 +1034,13 @@
     }
 
     @Test
+    @AppModeFull // testFillResponseAuthClientStateSetOnIntentOnly() is enough to test ephemeral
     public void testFillResponseAuthClientStateSetOnFillResponseOnly() throws Exception {
         fillResponseAuthWithClientState(ClientStateLocation.FILL_RESPONSE_ONLY);
     }
 
     @Test
+    @AppModeFull // testFillResponseAuthClientStateSetOnIntentOnly() is enough to test ephemeral
     public void testFillResponseAuthClientStateSetOnIntentAndFillResponse() throws Exception {
         fillResponseAuthWithClientState(ClientStateLocation.BOTH);
     }
diff --git a/tests/autofillservice/src/android/autofillservice/cts/AutofillValueTest.java b/tests/autofillservice/src/android/autofillservice/cts/AutofillValueTest.java
index c267c1f..a63afe4 100644
--- a/tests/autofillservice/src/android/autofillservice/cts/AutofillValueTest.java
+++ b/tests/autofillservice/src/android/autofillservice/cts/AutofillValueTest.java
@@ -21,8 +21,7 @@
 import static org.testng.Assert.assertThrows;
 
 import android.icu.util.Calendar;
-import androidx.annotation.NonNull;
-import androidx.annotation.Nullable;
+import android.platform.test.annotations.AppModeFull;
 import android.view.View;
 import android.view.autofill.AutofillValue;
 import android.widget.CompoundButton;
@@ -33,6 +32,9 @@
 import android.widget.Spinner;
 import android.widget.TimePicker;
 
+import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
+
 import org.junit.Before;
 import org.junit.Rule;
 import org.junit.Test;
@@ -51,6 +53,7 @@
  *  redundant tests and add more tests (like triggering autofill using different views) to
  *  CheckoutActivityTest.
  */
+@AppModeFull // Unit test
 public class AutofillValueTest extends AutoFillServiceTestCase {
     @Rule
     public final AutofillActivityTestRule<AllAutofillableViewsActivity> mActivityRule =
diff --git a/tests/autofillservice/src/android/autofillservice/cts/BatchUpdatesTest.java b/tests/autofillservice/src/android/autofillservice/cts/BatchUpdatesTest.java
index f17f7dc..805db4e 100644
--- a/tests/autofillservice/src/android/autofillservice/cts/BatchUpdatesTest.java
+++ b/tests/autofillservice/src/android/autofillservice/cts/BatchUpdatesTest.java
@@ -21,6 +21,7 @@
 import static org.mockito.Mockito.mock;
 import static org.testng.Assert.assertThrows;
 
+import android.platform.test.annotations.AppModeFull;
 import android.service.autofill.BatchUpdates;
 import android.service.autofill.InternalTransformation;
 import android.service.autofill.Transformation;
@@ -31,6 +32,7 @@
 import org.junit.runner.RunWith;
 
 @RunWith(AndroidJUnit4.class)
+@AppModeFull // Unit test
 public class BatchUpdatesTest {
 
     private final BatchUpdates.Builder mBuilder = new BatchUpdates.Builder();
diff --git a/tests/autofillservice/src/android/autofillservice/cts/CharSequenceTransformationTest.java b/tests/autofillservice/src/android/autofillservice/cts/CharSequenceTransformationTest.java
index 065edbc..accf6d9b 100644
--- a/tests/autofillservice/src/android/autofillservice/cts/CharSequenceTransformationTest.java
+++ b/tests/autofillservice/src/android/autofillservice/cts/CharSequenceTransformationTest.java
@@ -25,6 +25,7 @@
 import static org.mockito.Mockito.when;
 import static org.testng.Assert.assertThrows;
 
+import android.platform.test.annotations.AppModeFull;
 import android.service.autofill.CharSequenceTransformation;
 import android.service.autofill.ValueFinder;
 import android.support.test.runner.AndroidJUnit4;
@@ -37,6 +38,7 @@
 import java.util.regex.Pattern;
 
 @RunWith(AndroidJUnit4.class)
+@AppModeFull // Unit test
 public class CharSequenceTransformationTest {
 
     @Test
diff --git a/tests/autofillservice/src/android/autofillservice/cts/CheckoutActivityTest.java b/tests/autofillservice/src/android/autofillservice/cts/CheckoutActivityTest.java
index a3ce455..6739a73 100644
--- a/tests/autofillservice/src/android/autofillservice/cts/CheckoutActivityTest.java
+++ b/tests/autofillservice/src/android/autofillservice/cts/CheckoutActivityTest.java
@@ -42,6 +42,7 @@
 import android.autofillservice.cts.CannedFillResponse.CannedDataset;
 import android.autofillservice.cts.InstrumentedAutoFillService.FillRequest;
 import android.autofillservice.cts.InstrumentedAutoFillService.SaveRequest;
+import android.platform.test.annotations.AppModeFull;
 import android.service.autofill.CharSequenceTransformation;
 import android.service.autofill.CustomDescription;
 import android.service.autofill.ImageTransformation;
@@ -114,6 +115,7 @@
     }
 
     @Test
+    @AppModeFull // testAutofill() is enough to test ephemeral apps support
     public void testAutofillDynamicAdapter() throws Exception {
         // Set activity.
         mActivity.onCcExpiration((v) -> v.setAdapter(new ArrayAdapter<String>(getContext(),
@@ -156,6 +158,7 @@
     // TODO: this should be a pure unit test exercising onProvideAutofillStructure(),
     // but that would require creating a custom ViewStructure.
     @Test
+    @AppModeFull // Unit test
     public void testGetAutofillOptionsSorted() throws Exception {
         // Set service.
         enableService();
@@ -245,11 +248,13 @@
     }
 
     @Test
+    @AppModeFull // Service-specific test
     public void testCustomizedSaveUi() throws Exception {
         customizedSaveUi(false);
     }
 
     @Test
+    @AppModeFull // Service-specific test
     public void testCustomizedSaveUiWithContentDescription() throws Exception {
         customizedSaveUi(true);
     }
diff --git a/tests/autofillservice/src/android/autofillservice/cts/CustomDescriptionDateTest.java b/tests/autofillservice/src/android/autofillservice/cts/CustomDescriptionDateTest.java
index 7ac759b..7858278 100644
--- a/tests/autofillservice/src/android/autofillservice/cts/CustomDescriptionDateTest.java
+++ b/tests/autofillservice/src/android/autofillservice/cts/CustomDescriptionDateTest.java
@@ -24,6 +24,7 @@
 
 import android.autofillservice.cts.CannedFillResponse.CannedDataset;
 import android.icu.text.SimpleDateFormat;
+import android.platform.test.annotations.AppModeFull;
 import android.service.autofill.CustomDescription;
 import android.service.autofill.DateTransformation;
 import android.service.autofill.DateValueSanitizer;
@@ -38,6 +39,7 @@
 
 import java.util.Calendar;
 
+@AppModeFull // Service-specific test
 public class CustomDescriptionDateTest extends AutoFillServiceTestCase {
 
     @Rule
diff --git a/tests/autofillservice/src/android/autofillservice/cts/CustomDescriptionTest.java b/tests/autofillservice/src/android/autofillservice/cts/CustomDescriptionTest.java
index e08d7b5..08050e0 100644
--- a/tests/autofillservice/src/android/autofillservice/cts/CustomDescriptionTest.java
+++ b/tests/autofillservice/src/android/autofillservice/cts/CustomDescriptionTest.java
@@ -24,20 +24,22 @@
 import static com.google.common.truth.Truth.assertThat;
 import static com.google.common.truth.Truth.assertWithMessage;
 
+import android.platform.test.annotations.AppModeFull;
 import android.service.autofill.BatchUpdates;
 import android.service.autofill.CharSequenceTransformation;
 import android.service.autofill.CustomDescription;
 import android.service.autofill.ImageTransformation;
 import android.service.autofill.RegexValidator;
 import android.service.autofill.Validator;
-import androidx.annotation.NonNull;
-import androidx.annotation.Nullable;
 import android.support.test.uiautomator.By;
 import android.support.test.uiautomator.UiObject2;
 import android.view.View;
 import android.view.autofill.AutofillId;
 import android.widget.RemoteViews;
 
+import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
+
 import org.junit.Before;
 import org.junit.Rule;
 import org.junit.Test;
@@ -45,6 +47,7 @@
 import java.util.function.BiFunction;
 import java.util.regex.Pattern;
 
+@AppModeFull // Service-specific test
 public class CustomDescriptionTest extends AutoFillServiceTestCase {
     @Rule
     public final AutofillActivityTestRule<LoginActivity> mActivityRule =
diff --git a/tests/autofillservice/src/android/autofillservice/cts/CustomDescriptionUnitTest.java b/tests/autofillservice/src/android/autofillservice/cts/CustomDescriptionUnitTest.java
index 2a50b6e..ee6e8e0 100644
--- a/tests/autofillservice/src/android/autofillservice/cts/CustomDescriptionUnitTest.java
+++ b/tests/autofillservice/src/android/autofillservice/cts/CustomDescriptionUnitTest.java
@@ -19,6 +19,7 @@
 import static org.mockito.Mockito.mock;
 import static org.testng.Assert.assertThrows;
 
+import android.platform.test.annotations.AppModeFull;
 import android.service.autofill.BatchUpdates;
 import android.service.autofill.CustomDescription;
 import android.service.autofill.InternalValidator;
@@ -31,6 +32,7 @@
 import org.junit.runner.RunWith;
 
 @RunWith(AndroidJUnit4.class)
+@AppModeFull // Unit test
 public class CustomDescriptionUnitTest {
 
     private final CustomDescription.Builder mBuilder =
diff --git a/tests/autofillservice/src/android/autofillservice/cts/DatasetFilteringTest.java b/tests/autofillservice/src/android/autofillservice/cts/DatasetFilteringTest.java
index 451b002..81b3fa2 100644
--- a/tests/autofillservice/src/android/autofillservice/cts/DatasetFilteringTest.java
+++ b/tests/autofillservice/src/android/autofillservice/cts/DatasetFilteringTest.java
@@ -21,7 +21,7 @@
 
 import android.autofillservice.cts.CannedFillResponse.CannedDataset;
 import android.content.IntentSender;
-import android.os.SystemClock;
+import android.platform.test.annotations.AppModeFull;
 
 import org.junit.AfterClass;
 import org.junit.BeforeClass;
@@ -46,10 +46,13 @@
 
     private static void sendKeyEvents(String keyCode) {
         runShellCommand("input keyevent " + keyCode);
-        // TODO wait mechanism for window size change
-        SystemClock.sleep(200);
     }
 
+    private void changeUsername(CharSequence username) {
+        mActivity.onUsername((v) -> v.setText(username));
+    }
+
+
     @Test
     public void testFilter() throws Exception {
         final String aa = "Two A's";
@@ -82,24 +85,24 @@
         mUiBot.assertDatasets(aa, ab, b);
 
         // Only two datasets start with 'a'
-        mActivity.onUsername((v) -> v.setText("a"));
+        changeUsername("a");
         mUiBot.assertDatasets(aa, ab);
 
         // Only one dataset start with 'aa'
-        mActivity.onUsername((v) -> v.setText("aa"));
+        changeUsername("aa");
         mUiBot.assertDatasets(aa);
 
         // Only two datasets start with 'a'
-        mActivity.onUsername((v) -> v.setText("a"));
+        changeUsername("a");
         mUiBot.assertDatasets(aa, ab);
 
         // With no filter text all datasets should be shown
-        mActivity.onUsername((v) -> v.setText(""));
+        changeUsername("");
         mUiBot.assertDatasets(aa, ab, b);
 
         // No dataset start with 'aaa'
         final MyAutofillCallback callback = mActivity.registerCallback();
-        mActivity.onUsername((v) -> v.setText("aaa"));
+        changeUsername("aaa");
         callback.assertUiHiddenEvent(mActivity.getUsername());
         mUiBot.assertNoDatasets();
     }
@@ -161,6 +164,7 @@
     }
 
     @Test
+    @AppModeFull // testFilter() is enough to test ephemeral apps support
     public void testFilter_nullValuesAlwaysMatched() throws Exception {
         final String aa = "Two A's";
         final String ab = "A and B";
@@ -192,27 +196,28 @@
         mUiBot.assertDatasets(aa, ab, b);
 
         // Two datasets start with 'a' and one with null value always shown
-        mActivity.onUsername((v) -> v.setText("a"));
+        changeUsername("a");
         mUiBot.assertDatasets(aa, ab, b);
 
         // One dataset start with 'aa' and one with null value always shown
-        mActivity.onUsername((v) -> v.setText("aa"));
+        changeUsername("aa");
         mUiBot.assertDatasets(aa, b);
 
         // Two datasets start with 'a' and one with null value always shown
-        mActivity.onUsername((v) -> v.setText("a"));
+        changeUsername("a");
         mUiBot.assertDatasets(aa, ab, b);
 
         // With no filter text all datasets should be shown
-        mActivity.onUsername((v) -> v.setText(""));
+        changeUsername("");
         mUiBot.assertDatasets(aa, ab, b);
 
         // No dataset start with 'aaa' and one with null value always shown
-        mActivity.onUsername((v) -> v.setText("aaa"));
+        changeUsername("aaa");
         mUiBot.assertDatasets(b);
     }
 
     @Test
+    @AppModeFull // testFilter() is enough to test ephemeral apps support
     public void testFilter_differentPrefixes() throws Exception {
         final String a = "aaa";
         final String b = "bra";
@@ -243,17 +248,18 @@
         // With no filter text all datasets should be shown
         mUiBot.assertDatasets(a, b, c);
 
-        mActivity.onUsername((v) -> v.setText("a"));
+        changeUsername("a");
         mUiBot.assertDatasets(a);
 
-        mActivity.onUsername((v) -> v.setText("b"));
+        changeUsername("b");
         mUiBot.assertDatasets(b);
 
-        mActivity.onUsername((v) -> v.setText("c"));
+        changeUsername("c");
         mUiBot.assertDatasets(c);
     }
 
     @Test
+    @AppModeFull // testFilter() is enough to test ephemeral apps support
     public void testFilter_usingRegex() throws Exception {
         // Dataset presentations.
         final String aa = "Two A's";
@@ -286,29 +292,30 @@
         mUiBot.assertDatasets(aa, ab, b);
 
         // Only two datasets start with 'a'
-        mActivity.onUsername((v) -> v.setText("a"));
+        changeUsername("a");
         mUiBot.assertDatasets(aa, ab);
 
         // Only one dataset start with 'aa'
-        mActivity.onUsername((v) -> v.setText("aa"));
+        changeUsername("aa");
         mUiBot.assertDatasets(aa);
 
         // Only two datasets start with 'a'
-        mActivity.onUsername((v) -> v.setText("a"));
+        changeUsername("a");
         mUiBot.assertDatasets(aa, ab);
 
         // With no filter text all datasets should be shown
-        mActivity.onUsername((v) -> v.setText(""));
+        changeUsername("");
         mUiBot.assertDatasets(aa, ab, b);
 
         // No dataset start with 'aaa'
         final MyAutofillCallback callback = mActivity.registerCallback();
-        mActivity.onUsername((v) -> v.setText("aaa"));
+        changeUsername("aaa");
         callback.assertUiHiddenEvent(mActivity.getUsername());
         mUiBot.assertNoDatasets();
     }
 
     @Test
+    @AppModeFull // testFilter() is enough to test ephemeral apps support
     public void testFilter_disabledUsingNullRegex() throws Exception {
         // Dataset presentations.
         final String unfilterable = "Unfilterabled";
@@ -344,33 +351,34 @@
         mUiBot.assertDatasets(unfilterable, aOrW, w);
 
         // Only one dataset start with 'a'
-        mActivity.onUsername((v) -> v.setText("a"));
+        changeUsername("a");
         mUiBot.assertDatasets(aOrW);
 
         // No dataset starts with 'aa'
-        mActivity.onUsername((v) -> v.setText("aa"));
+        changeUsername("aa");
         mUiBot.assertNoDatasets();
 
         // Only one datasets start with 'a'
-        mActivity.onUsername((v) -> v.setText("a"));
+        changeUsername("a");
         mUiBot.assertDatasets(aOrW);
 
         // With no filter text all datasets should be shown
-        mActivity.onUsername((v) -> v.setText(""));
+        changeUsername("");
         mUiBot.assertDatasets(unfilterable, aOrW, w);
 
         // Only one datasets start with 'w'
-        mActivity.onUsername((v) -> v.setText("w"));
+        changeUsername("w");
         mUiBot.assertDatasets(w);
 
         // No dataset start with 'aaa'
         final MyAutofillCallback callback = mActivity.registerCallback();
-        mActivity.onUsername((v) -> v.setText("aaa"));
+        changeUsername("aaa");
         callback.assertUiHiddenEvent(mActivity.getUsername());
         mUiBot.assertNoDatasets();
     }
 
     @Test
+    @AppModeFull // testFilter() is enough to test ephemeral apps support
     public void testFilter_mixPlainAndRegex() throws Exception {
         final String plain = "Plain";
         final String regexPlain = "RegexPlain";
@@ -413,15 +421,16 @@
         mUiBot.assertDatasets(plain, regexPlain, authRegex, kitchnSync);
 
         // All datasets start with 'a'
-        mActivity.onUsername((v) -> v.setText("a"));
+        changeUsername("a");
         mUiBot.assertDatasets(plain, regexPlain, authRegex, kitchnSync);
 
         // Only the regex datasets should start with 'ab'
-        mActivity.onUsername((v) -> v.setText("ab"));
+        changeUsername("ab");
         mUiBot.assertDatasets(regexPlain, authRegex, kitchnSync);
     }
 
     @Test
+    @AppModeFull // testFilter_usingKeyboard() is enough to test ephemeral apps support
     public void testFilter_mixPlainAndRegex_usingKeyboard() throws Exception {
         final String plain = "Plain";
         final String regexPlain = "RegexPlain";
diff --git a/tests/autofillservice/src/android/autofillservice/cts/DatasetTest.java b/tests/autofillservice/src/android/autofillservice/cts/DatasetTest.java
index 90d4193..2554a5b 100644
--- a/tests/autofillservice/src/android/autofillservice/cts/DatasetTest.java
+++ b/tests/autofillservice/src/android/autofillservice/cts/DatasetTest.java
@@ -21,6 +21,7 @@
 import static org.mockito.Mockito.mock;
 import static org.testng.Assert.assertThrows;
 
+import android.platform.test.annotations.AppModeFull;
 import android.service.autofill.Dataset;
 import android.support.test.runner.AndroidJUnit4;
 import android.view.autofill.AutofillId;
@@ -33,6 +34,7 @@
 import java.util.regex.Pattern;
 
 @RunWith(AndroidJUnit4.class)
+@AppModeFull // Unit test
 public class DatasetTest {
 
     private final AutofillId mId = new AutofillId(42);
diff --git a/tests/autofillservice/src/android/autofillservice/cts/DatePickerCalendarActivityTest.java b/tests/autofillservice/src/android/autofillservice/cts/DatePickerCalendarActivityTest.java
index 40c11d3..f0c3e04 100644
--- a/tests/autofillservice/src/android/autofillservice/cts/DatePickerCalendarActivityTest.java
+++ b/tests/autofillservice/src/android/autofillservice/cts/DatePickerCalendarActivityTest.java
@@ -15,8 +15,11 @@
  */
 package android.autofillservice.cts;
 
+import android.platform.test.annotations.AppModeFull;
+
 import org.junit.Rule;
 
+@AppModeFull // Unit test
 public class DatePickerCalendarActivityTest extends DatePickerTestCase<DatePickerCalendarActivity> {
 
     @Rule
diff --git a/tests/autofillservice/src/android/autofillservice/cts/DatePickerSpinnerActivityTest.java b/tests/autofillservice/src/android/autofillservice/cts/DatePickerSpinnerActivityTest.java
index 0497f87..0fb026a 100644
--- a/tests/autofillservice/src/android/autofillservice/cts/DatePickerSpinnerActivityTest.java
+++ b/tests/autofillservice/src/android/autofillservice/cts/DatePickerSpinnerActivityTest.java
@@ -15,8 +15,11 @@
  */
 package android.autofillservice.cts;
 
+import android.platform.test.annotations.AppModeFull;
+
 import org.junit.Rule;
 
+@AppModeFull // Unit test
 public class DatePickerSpinnerActivityTest extends DatePickerTestCase<DatePickerSpinnerActivity> {
 
     @Rule
diff --git a/tests/autofillservice/src/android/autofillservice/cts/DateTransformationTest.java b/tests/autofillservice/src/android/autofillservice/cts/DateTransformationTest.java
index 52016ed..8f2d0ee 100644
--- a/tests/autofillservice/src/android/autofillservice/cts/DateTransformationTest.java
+++ b/tests/autofillservice/src/android/autofillservice/cts/DateTransformationTest.java
@@ -26,6 +26,7 @@
 
 import android.icu.text.SimpleDateFormat;
 import android.icu.util.Calendar;
+import android.platform.test.annotations.AppModeFull;
 import android.service.autofill.DateTransformation;
 import android.service.autofill.ValueFinder;
 import android.view.autofill.AutofillId;
@@ -38,6 +39,7 @@
 import org.mockito.junit.MockitoJUnitRunner;
 
 @RunWith(MockitoJUnitRunner.class)
+@AppModeFull // Unit test
 public class DateTransformationTest {
 
     @Mock private ValueFinder mValueFinder;
diff --git a/tests/autofillservice/src/android/autofillservice/cts/DateValueSanitizerTest.java b/tests/autofillservice/src/android/autofillservice/cts/DateValueSanitizerTest.java
index 38386af..6f59302 100644
--- a/tests/autofillservice/src/android/autofillservice/cts/DateValueSanitizerTest.java
+++ b/tests/autofillservice/src/android/autofillservice/cts/DateValueSanitizerTest.java
@@ -22,6 +22,7 @@
 
 import android.icu.text.SimpleDateFormat;
 import android.icu.util.Calendar;
+import android.platform.test.annotations.AppModeFull;
 import android.service.autofill.DateValueSanitizer;
 import android.support.test.runner.AndroidJUnit4;
 import android.util.Log;
@@ -33,6 +34,7 @@
 import java.util.Date;
 
 @RunWith(AndroidJUnit4.class)
+@AppModeFull // Unit test
 public class DateValueSanitizerTest {
 
     private static final String TAG = "DateValueSanitizerTest";
diff --git a/tests/autofillservice/src/android/autofillservice/cts/DisableAutofillTest.java b/tests/autofillservice/src/android/autofillservice/cts/DisableAutofillTest.java
index c210b2f..2f4de15 100644
--- a/tests/autofillservice/src/android/autofillservice/cts/DisableAutofillTest.java
+++ b/tests/autofillservice/src/android/autofillservice/cts/DisableAutofillTest.java
@@ -19,6 +19,7 @@
 import android.autofillservice.cts.CannedFillResponse.CannedDataset;
 import android.content.Intent;
 import android.os.SystemClock;
+import android.platform.test.annotations.AppModeFull;
 import android.service.autofill.FillResponse;
 import android.util.Log;
 
@@ -191,6 +192,7 @@
     }
 
     @Test
+    @AppModeFull // testDisableApp() is enough to test ephemeral apps support
     public void testDisableAppThenWaitToReenableIt() throws Exception {
         // Set service.
         enableService();
@@ -216,6 +218,7 @@
     }
 
     @Test
+    @AppModeFull // testDisableApp() is enough to test ephemeral apps support
     public void testDisableAppThenResetServiceToReenableIt() throws Exception {
         enableService();
         sReplier.addResponse(new CannedFillResponse.Builder()
@@ -259,6 +262,7 @@
     }
 
     @Test
+    @AppModeFull // testDisableActivity() is enough to test ephemeral apps support
     public void testDisableActivityThenWaitToReenableIt() throws Exception {
         // Set service.
         enableService();
@@ -287,6 +291,7 @@
     }
 
     @Test
+    @AppModeFull // testDisableActivity() is enough to test ephemeral apps support
     public void testDisableActivityThenResetServiceToReenableIt() throws Exception {
         enableService();
         sReplier.addResponse(new CannedFillResponse.Builder()
diff --git a/tests/autofillservice/src/android/autofillservice/cts/DuplicateIdActivityTest.java b/tests/autofillservice/src/android/autofillservice/cts/DuplicateIdActivityTest.java
index 567aeba..29ec2b1 100644
--- a/tests/autofillservice/src/android/autofillservice/cts/DuplicateIdActivityTest.java
+++ b/tests/autofillservice/src/android/autofillservice/cts/DuplicateIdActivityTest.java
@@ -33,10 +33,6 @@
 import org.junit.Rule;
 import org.junit.Test;
 
-/**
- * This is the test case covering most scenarios - other test cases will cover characteristics
- * specific to that test's activity (for example, custom views).
- */
 public class DuplicateIdActivityTest extends AutoFillServiceTestCase {
     private static final String LOG_TAG = DuplicateIdActivityTest.class.getSimpleName();
     @Rule
diff --git a/tests/autofillservice/src/android/autofillservice/cts/FieldsClassificationTest.java b/tests/autofillservice/src/android/autofillservice/cts/FieldsClassificationTest.java
index b664a30..1ba93c4 100644
--- a/tests/autofillservice/src/android/autofillservice/cts/FieldsClassificationTest.java
+++ b/tests/autofillservice/src/android/autofillservice/cts/FieldsClassificationTest.java
@@ -18,6 +18,7 @@
 import static android.autofillservice.cts.Helper.assertFillEventForContextCommitted;
 import static android.autofillservice.cts.Helper.assertFillEventForFieldsClassification;
 import static android.provider.Settings.Secure.AUTOFILL_FEATURE_FIELD_CLASSIFICATION;
+import static android.provider.Settings.Secure.AUTOFILL_USER_DATA_MAX_CATEGORY_COUNT;
 import static android.provider.Settings.Secure.AUTOFILL_USER_DATA_MAX_FIELD_CLASSIFICATION_IDS_SIZE;
 import static android.provider.Settings.Secure.AUTOFILL_USER_DATA_MAX_USER_DATA_SIZE;
 import static android.provider.Settings.Secure.AUTOFILL_USER_DATA_MAX_VALUE_LENGTH;
@@ -28,6 +29,7 @@
 import android.autofillservice.cts.Helper.FieldClassificationResult;
 import android.autofillservice.cts.common.SettingsStateChangerRule;
 import android.content.Context;
+import android.platform.test.annotations.AppModeFull;
 import android.service.autofill.FillEventHistory.Event;
 import android.service.autofill.UserData;
 import android.support.test.InstrumentationRegistry;
@@ -42,6 +44,7 @@
 
 import java.util.List;
 
+@AppModeFull // Service-specific test
 public class FieldsClassificationTest extends AutoFillServiceTestCase {
 
     private static final Context sContext = InstrumentationRegistry.getContext();
@@ -67,6 +70,10 @@
     public static final SettingsStateChangerRule sUserDataMaxValueChanger =
             new SettingsStateChangerRule(sContext, AUTOFILL_USER_DATA_MAX_VALUE_LENGTH, "50");
 
+    @ClassRule
+    public static final SettingsStateChangerRule sUserDataMaxCategoryChanger =
+            new SettingsStateChangerRule(sContext, AUTOFILL_USER_DATA_MAX_CATEGORY_COUNT, "42");
+
     @Rule
     public final AutofillActivityTestRule<GridActivity> mActivityRule =
             new AutofillActivityTestRule<GridActivity>(GridActivity.class);
@@ -132,6 +139,7 @@
         assertThat(UserData.getMaxUserDataSize()).isEqualTo(9);
         assertThat(UserData.getMinValueLength()).isEqualTo(5);
         assertThat(UserData.getMaxValueLength()).isEqualTo(50);
+        assertThat(UserData.getMaxCategoryCount()).isEqualTo(42);
     }
 
     @Test
diff --git a/tests/autofillservice/src/android/autofillservice/cts/FillEventHistoryTest.java b/tests/autofillservice/src/android/autofillservice/cts/FillEventHistoryTest.java
index 4196870..b27ad83 100644
--- a/tests/autofillservice/src/android/autofillservice/cts/FillEventHistoryTest.java
+++ b/tests/autofillservice/src/android/autofillservice/cts/FillEventHistoryTest.java
@@ -43,6 +43,7 @@
 import android.content.Intent;
 import android.content.IntentSender;
 import android.os.Bundle;
+import android.platform.test.annotations.AppModeFull;
 import android.service.autofill.FillEventHistory;
 import android.service.autofill.FillEventHistory.Event;
 import android.service.autofill.FillResponse;
@@ -63,6 +64,7 @@
 /**
  * Test that uses {@link LoginActivity} to test {@link FillEventHistory}.
  */
+@AppModeFull // Service-specific test
 public class FillEventHistoryTest extends AutoFillServiceTestCase {
 
     @Rule
diff --git a/tests/autofillservice/src/android/autofillservice/cts/FillResponseTest.java b/tests/autofillservice/src/android/autofillservice/cts/FillResponseTest.java
index 7181b01..70d7471 100644
--- a/tests/autofillservice/src/android/autofillservice/cts/FillResponseTest.java
+++ b/tests/autofillservice/src/android/autofillservice/cts/FillResponseTest.java
@@ -25,6 +25,7 @@
 
 import android.content.IntentSender;
 import android.os.Bundle;
+import android.platform.test.annotations.AppModeFull;
 import android.service.autofill.Dataset;
 import android.service.autofill.FillResponse;
 import android.service.autofill.SaveInfo;
@@ -39,6 +40,7 @@
 import org.mockito.junit.MockitoJUnitRunner;
 
 @RunWith(MockitoJUnitRunner.class)
+@AppModeFull // Unit test
 public class FillResponseTest {
 
     private final AutofillId mAutofillId = new AutofillId(42);
diff --git a/tests/autofillservice/src/android/autofillservice/cts/ImageTransformationTest.java b/tests/autofillservice/src/android/autofillservice/cts/ImageTransformationTest.java
index 935be23..f0f5470 100644
--- a/tests/autofillservice/src/android/autofillservice/cts/ImageTransformationTest.java
+++ b/tests/autofillservice/src/android/autofillservice/cts/ImageTransformationTest.java
@@ -24,6 +24,7 @@
 import static org.mockito.Mockito.when;
 import static org.testng.Assert.assertThrows;
 
+import android.platform.test.annotations.AppModeFull;
 import android.service.autofill.ImageTransformation;
 import android.service.autofill.ValueFinder;
 import android.support.test.runner.AndroidJUnit4;
@@ -36,6 +37,7 @@
 import java.util.regex.Pattern;
 
 @RunWith(AndroidJUnit4.class)
+@AppModeFull // Unit test
 public class ImageTransformationTest {
 
     @Test
diff --git a/tests/autofillservice/src/android/autofillservice/cts/InitializedCheckoutActivityTest.java b/tests/autofillservice/src/android/autofillservice/cts/InitializedCheckoutActivityTest.java
index 07c67eb9..c96bbbc 100644
--- a/tests/autofillservice/src/android/autofillservice/cts/InitializedCheckoutActivityTest.java
+++ b/tests/autofillservice/src/android/autofillservice/cts/InitializedCheckoutActivityTest.java
@@ -28,6 +28,7 @@
 import static android.autofillservice.cts.Helper.findNodeByResourceId;
 
 import android.autofillservice.cts.InstrumentedAutoFillService.FillRequest;
+import android.platform.test.annotations.AppModeFull;
 
 import org.junit.Before;
 import org.junit.Rule;
@@ -36,6 +37,7 @@
 /**
  * Test case for an activity containing non-TextField views with initial values set on XML.
  */
+@AppModeFull // CheckoutActivityTest() is enough to test ephemeral apps support
 public class InitializedCheckoutActivityTest extends AutoFillServiceTestCase {
 
     @Rule
diff --git a/tests/autofillservice/src/android/autofillservice/cts/LoginActivityTest.java b/tests/autofillservice/src/android/autofillservice/cts/LoginActivityTest.java
index 475abc5..fa8fa1b 100644
--- a/tests/autofillservice/src/android/autofillservice/cts/LoginActivityTest.java
+++ b/tests/autofillservice/src/android/autofillservice/cts/LoginActivityTest.java
@@ -73,6 +73,7 @@
 import android.graphics.Rect;
 import android.os.Bundle;
 import android.os.SystemClock;
+import android.platform.test.annotations.AppModeFull;
 import android.service.autofill.SaveInfo;
 import android.support.test.uiautomator.UiObject2;
 import android.util.Log;
@@ -123,11 +124,13 @@
     }
 
     @Test
+    @AppModeFull // testAutoFillOneDataset() is enough to test ephemeral apps support
     public void testAutofillManuallyAfterServiceReturnedNoDatasets() throws Exception {
         autofillAfterServiceReturnedNoDatasets(true);
     }
 
     @Test
+    @AppModeFull // testAutoFillOneDataset() is enough to test ephemeral apps support
     public void testAutofillAutomaticallyAfterServiceReturnedNoDatasets() throws Exception {
         autofillAfterServiceReturnedNoDatasets(false);
     }
@@ -174,11 +177,13 @@
     }
 
     @Test
+    @AppModeFull // testAutoFillOneDataset() is enough to test ephemeral apps support
     public void testAutofillManuallyAndSaveAfterServiceReturnedNoDatasets() throws Exception {
         autofillAndSaveAfterServiceReturnedNoDatasets(true);
     }
 
     @Test
+    @AppModeFull // testAutoFillOneDataset() is enough to test ephemeral apps support
     public void testAutofillAutomaticallyAndSaveAfterServiceReturnedNoDatasets() throws Exception {
         autofillAndSaveAfterServiceReturnedNoDatasets(false);
     }
@@ -212,6 +217,7 @@
      * workflow was requested.
      */
     @Test
+    @AppModeFull // testAutoFillNoDatasets() is enough to test ephemeral apps support
     public void testMultipleIterationsAfterServiceReturnedNoDatasets() throws Exception {
         // Set service.
         enableService();
@@ -254,6 +260,7 @@
     }
 
     @Test
+    @AppModeFull // testAutofillManuallyOneDataset() is enough to test ephemeral apps support
     public void testAutofillManuallyAlwaysCallServiceAgain() throws Exception {
         // Set service.
         enableService();
@@ -287,11 +294,13 @@
     }
 
     @Test
+    @AppModeFull // testAutoFillOneDataset_withHeaderAndFooter() is enough to test ephemeral apps
     public void testAutoFillOneDataset_withHeader() throws Exception {
         autofillOneDatasetTest(BorderType.HEADER_ONLY);
     }
 
     @Test
+    @AppModeFull // testAutoFillOneDataset_withHeaderAndFooter() is enough to test ephemeral apps
     public void testAutoFillOneDataset_withFooter() throws Exception {
         autofillOneDatasetTest(BorderType.FOOTER_ONLY);
     }
@@ -447,6 +456,7 @@
     }
 
     @Test
+    @AppModeFull // testAutoFillOneDataset() is enough to test ephemeral apps
     public void testAutoFillTwoDatasetsSameNumberOfFields() throws Exception {
         // Set service.
         enableService();
@@ -485,11 +495,13 @@
     }
 
     @Test
+    @AppModeFull // testAutoFillOneDataset() is enough to test ephemeral apps
     public void testAutoFillTwoDatasetsUnevenNumberOfFieldsFillsAll() throws Exception {
         autoFillTwoDatasetsUnevenNumberOfFieldsTest(true);
     }
 
     @Test
+    @AppModeFull // testAutoFillOneDataset() is enough to test ephemeral apps
     public void testAutoFillTwoDatasetsUnevenNumberOfFieldsFillsOne() throws Exception {
         autoFillTwoDatasetsUnevenNumberOfFieldsTest(false);
     }
@@ -541,6 +553,7 @@
     }
 
     @Test
+    @AppModeFull // testAutoFillOneDataset() is enough to test ephemeral apps
     public void testAutoFillDatasetWithoutFieldIsIgnored() throws Exception {
         // Set service.
         enableService();
@@ -735,6 +748,7 @@
     }
 
     @Test
+    @AppModeFull // testAutofillCallbacks() is enough to test ephemeral apps
     public void testAutofillCallbackDisabled() throws Exception {
         // Set service.
         disableService();
@@ -750,11 +764,13 @@
     }
 
     @Test
+    @AppModeFull // testAutofillCallbacks() is enough to test ephemeral apps
     public void testAutofillCallbackNoDatasets() throws Exception {
         callbackUnavailableTest(NO_RESPONSE);
     }
 
     @Test
+    @AppModeFull // testAutofillCallbacks() is enough to test ephemeral apps
     public void testAutofillCallbackNoDatasetsButSaveInfo() throws Exception {
         callbackUnavailableTest(new CannedFillResponse.Builder()
                 .setRequiredSavableIds(SAVE_DATA_TYPE_PASSWORD, ID_USERNAME, ID_PASSWORD)
@@ -967,16 +983,19 @@
     }
 
     @Test
+    @AppModeFull // testAutoFillOneDataset() is enough to test ephemeral apps
     public void testAutoFillMultipleDatasetsPickFirst() throws Exception {
         multipleDatasetsTest(1);
     }
 
     @Test
+    @AppModeFull // testAutoFillOneDataset() is enough to test ephemeral apps
     public void testAutoFillMultipleDatasetsPickSecond() throws Exception {
         multipleDatasetsTest(2);
     }
 
     @Test
+    @AppModeFull // testAutoFillOneDataset() is enough to test ephemeral apps
     public void testAutoFillMultipleDatasetsPickThird() throws Exception {
         multipleDatasetsTest(3);
     }
@@ -1080,6 +1099,7 @@
      * and password) and the dataset itself, and each dataset has the same number of fields.
      */
     @Test
+    @AppModeFull // testAutofillOneDatasetCustomPresentation() is enough to test ephemeral apps
     public void testAutofillMultipleDatasetsCustomPresentations() throws Exception {
         // Set service.
         enableService();
@@ -1124,6 +1144,7 @@
      * and password), and each dataset has the same number of fields.
      */
     @Test
+    @AppModeFull // testAutofillOneDatasetCustomPresentation() is enough to test ephemeral apps
     public void testAutofillMultipleDatasetsCustomPresentationSameFields() throws Exception {
         // Set service.
         enableService();
@@ -1167,6 +1188,7 @@
      * and password), but each dataset has a different number of fields.
      */
     @Test
+    @AppModeFull // testAutofillOneDatasetCustomPresentation() is enough to test ephemeral apps
     public void testAutofillMultipleDatasetsCustomPresentationFirstDatasetMissingSecondField()
             throws Exception {
         // Set service.
@@ -1209,6 +1231,7 @@
      * and password), but each dataset has a different number of fields.
      */
     @Test
+    @AppModeFull // testAutofillOneDatasetCustomPresentation() is enough to test ephemeral apps
     public void testAutofillMultipleDatasetsCustomPresentationSecondDatasetMissingFirstField()
             throws Exception {
         // Set service.
@@ -1247,11 +1270,13 @@
     }
 
     @Test
+    @AppModeFull // testAutoFillOneDatasetAndSave() is enough to test ephemeral apps
     public void testSaveOnly() throws Exception {
         saveOnlyTest(false);
     }
 
     @Test
+    @AppModeFull // testAutoFillOneDatasetAndSave() is enough to test ephemeral apps
     public void testSaveOnlyTriggeredManually() throws Exception {
         saveOnlyTest(false);
     }
@@ -1369,11 +1394,13 @@
     }
 
     @Test
+    @AppModeFull // testAutoFillOneDatasetAndSave() is enough to test ephemeral apps
     public void testSaveOnlyPreFilled() throws Exception {
         saveOnlyTestPreFilled(false);
     }
 
     @Test
+    @AppModeFull // testAutoFillOneDatasetAndSave() is enough to test ephemeral apps
     public void testSaveOnlyTriggeredManuallyPreFilled() throws Exception {
         saveOnlyTestPreFilled(true);
     }
@@ -1432,6 +1459,7 @@
     }
 
     @Test
+    @AppModeFull // testAutoFillOneDatasetAndSave() is enough to test ephemeral apps
     public void testSaveOnlyTwoRequiredFieldsOnePrefilled() throws Exception {
         enableService();
 
@@ -1478,6 +1506,7 @@
     }
 
     @Test
+    @AppModeFull // testAutoFillOneDatasetAndSave() is enough to test ephemeral apps
     public void testSaveOnlyOptionalField() throws Exception {
         enableService();
 
@@ -1520,16 +1549,19 @@
     }
 
     @Test
+    @AppModeFull // testAutoFillOneDatasetAndSave() is enough to test ephemeral apps
     public void testSaveNoRequiredField_NoneFilled() throws Exception {
         optionalOnlyTest(FilledFields.NONE);
     }
 
     @Test
+    @AppModeFull // testAutoFillOneDatasetAndSave() is enough to test ephemeral apps
     public void testSaveNoRequiredField_OneFilled() throws Exception {
         optionalOnlyTest(FilledFields.USERNAME_ONLY);
     }
 
     @Test
+    @AppModeFull // testAutoFillOneDatasetAndSave() is enough to test ephemeral apps
     public void testSaveNoRequiredField_BothFilled() throws Exception {
         optionalOnlyTest(FilledFields.BOTH);
     }
@@ -1598,31 +1630,37 @@
     }
 
     @Test
+    @AppModeFull // testAutoFillOneDatasetAndSave() is enough to test ephemeral apps
     public void testGenericSave() throws Exception {
         customizedSaveTest(SAVE_DATA_TYPE_GENERIC);
     }
 
     @Test
+    @AppModeFull // testAutoFillOneDatasetAndSave() is enough to test ephemeral apps
     public void testCustomizedSavePassword() throws Exception {
         customizedSaveTest(SAVE_DATA_TYPE_PASSWORD);
     }
 
     @Test
+    @AppModeFull // testAutoFillOneDatasetAndSave() is enough to test ephemeral apps
     public void testCustomizedSaveAddress() throws Exception {
         customizedSaveTest(SAVE_DATA_TYPE_ADDRESS);
     }
 
     @Test
+    @AppModeFull // testAutoFillOneDatasetAndSave() is enough to test ephemeral apps
     public void testCustomizedSaveCreditCard() throws Exception {
         customizedSaveTest(SAVE_DATA_TYPE_CREDIT_CARD);
     }
 
     @Test
+    @AppModeFull // testAutoFillOneDatasetAndSave() is enough to test ephemeral apps
     public void testCustomizedSaveUsername() throws Exception {
         customizedSaveTest(SAVE_DATA_TYPE_USERNAME);
     }
 
     @Test
+    @AppModeFull // testAutoFillOneDatasetAndSave() is enough to test ephemeral apps
     public void testCustomizedSaveEmailAddress() throws Exception {
         customizedSaveTest(SAVE_DATA_TYPE_EMAIL_ADDRESS);
     }
@@ -1711,6 +1749,7 @@
     }
 
     @Test
+    @AppModeFull // Service-specific test
     public void testDisableSelf() throws Exception {
         enableService();
 
@@ -1817,6 +1856,7 @@
     }
 
     @Test
+    @AppModeFull // Unit test
     public void testGetTextInputType() throws Exception {
         // Set service.
         enableService();
@@ -1839,6 +1879,7 @@
     }
 
     @Test
+    @AppModeFull // Unit test
     public void testNoContainers() throws Exception {
         // Set service.
         enableService();
@@ -1907,11 +1948,13 @@
     }
 
     @Test
+    @AppModeFull // testAutofillManuallyOneDataset() is enough to test ephemeral apps support
     public void testAutofillManuallyTwoDatasetsPickFirst() throws Exception {
         autofillManuallyTwoDatasets(true);
     }
 
     @Test
+    @AppModeFull // testAutofillManuallyOneDataset() is enough to test ephemeral apps support
     public void testAutofillManuallyTwoDatasetsPickSecond() throws Exception {
         autofillManuallyTwoDatasets(false);
     }
@@ -1955,6 +1998,7 @@
     }
 
     @Test
+    @AppModeFull // testAutofillManuallyOneDataset() is enough to test ephemeral apps support
     public void testAutofillManuallyPartialField() throws Exception {
         // Set service.
         enableService();
@@ -1989,6 +2033,7 @@
     }
 
     @Test
+    @AppModeFull // testAutofillManuallyOneDataset() is enough to test ephemeral apps support
     public void testAutofillManuallyAgainAfterAutomaticallyAutofilledBefore() throws Exception {
         // Set service.
         enableService();
@@ -2049,6 +2094,7 @@
     }
 
     @Test
+    @AppModeFull // testAutofillManuallyOneDataset() is enough to test ephemeral apps support
     public void testAutofillManuallyAgainAfterManuallyAutofilledBefore() throws Exception {
         // Set service.
         enableService();
@@ -2320,11 +2366,13 @@
 
     // TODO(b/70682223): add a new test to make sure service with BIND_AUTOFILL permission works
     @Test
+    @AppModeFull // Service-specific test
     public void testServiceIsDisabledWhenNewServiceInfoIsInvalid() throws Exception {
         serviceIsDisabledWhenNewServiceIsInvalid(BadAutofillService.SERVICE_NAME);
     }
 
     @Test
+    @AppModeFull // Service-specific test
     public void testServiceIsDisabledWhenNewServiceNameIsInvalid() throws Exception {
         serviceIsDisabledWhenNewServiceIsInvalid("Y_U_NO_VALID");
     }
@@ -2457,6 +2505,7 @@
     }
 
     @Test
+    @AppModeFull // Unit test
     public void testNewTextAttributes() throws Exception {
         enableService();
         sReplier.addResponse(NO_RESPONSE);
diff --git a/tests/autofillservice/src/android/autofillservice/cts/LoginWithStringsActivityTest.java b/tests/autofillservice/src/android/autofillservice/cts/LoginWithStringsActivityTest.java
index 73ab7d9..8474d28d 100644
--- a/tests/autofillservice/src/android/autofillservice/cts/LoginWithStringsActivityTest.java
+++ b/tests/autofillservice/src/android/autofillservice/cts/LoginWithStringsActivityTest.java
@@ -37,12 +37,14 @@
 import android.autofillservice.cts.InstrumentedAutoFillService.FillRequest;
 import android.autofillservice.cts.InstrumentedAutoFillService.SaveRequest;
 import android.os.Bundle;
+import android.platform.test.annotations.AppModeFull;
 import android.view.View;
 
 import org.junit.Before;
 import org.junit.Rule;
 import org.junit.Test;
 
+@AppModeFull // LoginActivityTest is enough to test ephemeral apps support
 public class LoginWithStringsActivityTest extends AutoFillServiceTestCase {
 
     @Rule
diff --git a/tests/autofillservice/src/android/autofillservice/cts/LuhnChecksumValidatorTest.java b/tests/autofillservice/src/android/autofillservice/cts/LuhnChecksumValidatorTest.java
index 09600a8..0da2208 100644
--- a/tests/autofillservice/src/android/autofillservice/cts/LuhnChecksumValidatorTest.java
+++ b/tests/autofillservice/src/android/autofillservice/cts/LuhnChecksumValidatorTest.java
@@ -22,6 +22,7 @@
 import static org.mockito.Mockito.when;
 import static org.testng.Assert.assertThrows;
 
+import android.platform.test.annotations.AppModeFull;
 import android.service.autofill.LuhnChecksumValidator;
 import android.service.autofill.ValueFinder;
 import android.support.test.runner.AndroidJUnit4;
@@ -31,6 +32,7 @@
 import org.junit.runner.RunWith;
 
 @RunWith(AndroidJUnit4.class)
+@AppModeFull // Unit test
 public class LuhnChecksumValidatorTest {
 
     @Test
diff --git a/tests/autofillservice/src/android/autofillservice/cts/MultiWindowLoginActivityTest.java b/tests/autofillservice/src/android/autofillservice/cts/MultiWindowLoginActivityTest.java
index 59ab7ce..0796028 100644
--- a/tests/autofillservice/src/android/autofillservice/cts/MultiWindowLoginActivityTest.java
+++ b/tests/autofillservice/src/android/autofillservice/cts/MultiWindowLoginActivityTest.java
@@ -28,6 +28,7 @@
 import android.app.Activity;
 import android.app.ActivityManager;
 import android.content.Intent;
+import android.platform.test.annotations.AppModeFull;
 import android.view.View;
 
 import org.junit.Before;
@@ -36,6 +37,7 @@
 
 import java.util.concurrent.TimeoutException;
 
+@AppModeFull // This test requires android.permission.MANAGE_ACTIVITY_STACKS
 public class MultiWindowLoginActivityTest extends AutoFillServiceTestCase {
 
     @Rule
diff --git a/tests/autofillservice/src/android/autofillservice/cts/OptionalSaveActivityTest.java b/tests/autofillservice/src/android/autofillservice/cts/OptionalSaveActivityTest.java
index bb29e30..5aaedde 100644
--- a/tests/autofillservice/src/android/autofillservice/cts/OptionalSaveActivityTest.java
+++ b/tests/autofillservice/src/android/autofillservice/cts/OptionalSaveActivityTest.java
@@ -28,6 +28,8 @@
 import android.app.assist.AssistStructure;
 import android.autofillservice.cts.CannedFillResponse.CannedDataset;
 import android.autofillservice.cts.InstrumentedAutoFillService.SaveRequest;
+import android.platform.test.annotations.AppModeFull;
+
 import androidx.annotation.NonNull;
 import androidx.annotation.Nullable;
 
@@ -46,6 +48,7 @@
  *   <li>Favorite Color: don't care - LOL
  * </ul>
  */
+@AppModeFull // Service-specific test
 public class OptionalSaveActivityTest extends AutoFillServiceTestCase {
 
     private static final boolean EXPECT_NO_SAVE_UI = false;
diff --git a/tests/autofillservice/src/android/autofillservice/cts/PartitionedActivityTest.java b/tests/autofillservice/src/android/autofillservice/cts/PartitionedActivityTest.java
index 8023bf4..d37bd16 100644
--- a/tests/autofillservice/src/android/autofillservice/cts/PartitionedActivityTest.java
+++ b/tests/autofillservice/src/android/autofillservice/cts/PartitionedActivityTest.java
@@ -47,6 +47,7 @@
 import android.autofillservice.cts.InstrumentedAutoFillService.SaveRequest;
 import android.content.IntentSender;
 import android.os.Bundle;
+import android.platform.test.annotations.AppModeFull;
 import android.service.autofill.FillResponse;
 
 import org.junit.Before;
@@ -58,6 +59,7 @@
 /**
  * Test case for an activity containing multiple partitions.
  */
+@AppModeFull // Service-specific test
 public class PartitionedActivityTest extends AutoFillServiceTestCase {
 
     @Rule
diff --git a/tests/autofillservice/src/android/autofillservice/cts/PreFilledLoginActivityTest.java b/tests/autofillservice/src/android/autofillservice/cts/PreFilledLoginActivityTest.java
index 0f571ef..7ca496b 100644
--- a/tests/autofillservice/src/android/autofillservice/cts/PreFilledLoginActivityTest.java
+++ b/tests/autofillservice/src/android/autofillservice/cts/PreFilledLoginActivityTest.java
@@ -28,6 +28,7 @@
 
 import android.autofillservice.cts.InstrumentedAutoFillService.FillRequest;
 import android.autofillservice.cts.InstrumentedAutoFillService.SaveRequest;
+import android.platform.test.annotations.AppModeFull;
 
 import org.junit.Before;
 import org.junit.Rule;
@@ -36,6 +37,7 @@
 /**
  * Covers scenarios where the behavior is different because some fields were pre-filled.
  */
+@AppModeFull // LoginActivityTest is enough to test ephemeral apps support
 public class PreFilledLoginActivityTest extends AutoFillServiceTestCase {
 
     @Rule
diff --git a/tests/autofillservice/src/android/autofillservice/cts/RegexValidatorTest.java b/tests/autofillservice/src/android/autofillservice/cts/RegexValidatorTest.java
index f7ac268..f0e68a6 100644
--- a/tests/autofillservice/src/android/autofillservice/cts/RegexValidatorTest.java
+++ b/tests/autofillservice/src/android/autofillservice/cts/RegexValidatorTest.java
@@ -22,6 +22,7 @@
 import static org.mockito.Mockito.when;
 import static org.testng.Assert.assertThrows;
 
+import android.platform.test.annotations.AppModeFull;
 import android.service.autofill.RegexValidator;
 import android.service.autofill.ValueFinder;
 import android.support.test.runner.AndroidJUnit4;
@@ -33,6 +34,7 @@
 import java.util.regex.Pattern;
 
 @RunWith(AndroidJUnit4.class)
+@AppModeFull // Unit test
 public class RegexValidatorTest {
 
     @Test
diff --git a/tests/autofillservice/src/android/autofillservice/cts/RetryRuleTest.java b/tests/autofillservice/src/android/autofillservice/cts/RetryRuleTest.java
index 6367c11..3d182ed 100644
--- a/tests/autofillservice/src/android/autofillservice/cts/RetryRuleTest.java
+++ b/tests/autofillservice/src/android/autofillservice/cts/RetryRuleTest.java
@@ -18,6 +18,7 @@
 
 import static com.google.common.truth.Truth.assertThat;
 
+import android.platform.test.annotations.AppModeFull;
 import android.support.test.runner.AndroidJUnit4;
 
 import org.junit.Test;
@@ -26,6 +27,7 @@
 import org.junit.runners.model.Statement;
 
 @RunWith(AndroidJUnit4.class)
+@AppModeFull // Unit test
 public class RetryRuleTest {
 
     private final Description mDescription = Description.createSuiteDescription("Whatever");
diff --git a/tests/autofillservice/src/android/autofillservice/cts/SafeCleanerRuleTest.java b/tests/autofillservice/src/android/autofillservice/cts/SafeCleanerRuleTest.java
index dde0a38..f41b001 100644
--- a/tests/autofillservice/src/android/autofillservice/cts/SafeCleanerRuleTest.java
+++ b/tests/autofillservice/src/android/autofillservice/cts/SafeCleanerRuleTest.java
@@ -22,6 +22,7 @@
 import static org.testng.Assert.expectThrows;
 
 import android.autofillservice.cts.SafeCleanerRule.Dumper;
+import android.platform.test.annotations.AppModeFull;
 
 import com.google.common.collect.ImmutableList;
 
@@ -36,6 +37,7 @@
 import java.util.concurrent.Callable;
 
 @RunWith(MockitoJUnitRunner.class)
+@AppModeFull // Unit test
 public class SafeCleanerRuleTest {
 
     private static class FailureStatement extends Statement {
diff --git a/tests/autofillservice/src/android/autofillservice/cts/SaveInfoTest.java b/tests/autofillservice/src/android/autofillservice/cts/SaveInfoTest.java
index d34eda1..a13f4a0 100644
--- a/tests/autofillservice/src/android/autofillservice/cts/SaveInfoTest.java
+++ b/tests/autofillservice/src/android/autofillservice/cts/SaveInfoTest.java
@@ -19,6 +19,7 @@
 import static org.mockito.Mockito.mock;
 import static org.testng.Assert.assertThrows;
 
+import android.platform.test.annotations.AppModeFull;
 import android.service.autofill.InternalSanitizer;
 import android.service.autofill.Sanitizer;
 import android.service.autofill.SaveInfo;
@@ -29,6 +30,7 @@
 import org.junit.runner.RunWith;
 
 @RunWith(AndroidJUnit4.class)
+@AppModeFull // Unit test
 public class SaveInfoTest {
 
     private  final AutofillId mId = new AutofillId(42);
diff --git a/tests/autofillservice/src/android/autofillservice/cts/SessionLifecycleTest.java b/tests/autofillservice/src/android/autofillservice/cts/SessionLifecycleTest.java
index 3ea8f36..9b03d0a 100644
--- a/tests/autofillservice/src/android/autofillservice/cts/SessionLifecycleTest.java
+++ b/tests/autofillservice/src/android/autofillservice/cts/SessionLifecycleTest.java
@@ -41,6 +41,7 @@
 import android.content.IntentSender;
 import android.os.Bundle;
 import android.os.SystemClock;
+import android.platform.test.annotations.AppModeFull;
 import android.support.test.uiautomator.UiObject2;
 import android.view.autofill.AutofillValue;
 
@@ -53,6 +54,7 @@
 /**
  * Test the lifecycle of a autofill session
  */
+@AppModeFull // This test requires android.permission.WRITE_EXTERNAL_STORAGE
 public class SessionLifecycleTest extends AutoFillServiceTestCase {
     private static final String ID_BUTTON = "button";
     private static final String ID_CANCEL = "cancel";
diff --git a/tests/autofillservice/src/android/autofillservice/cts/SimpleSaveActivityTest.java b/tests/autofillservice/src/android/autofillservice/cts/SimpleSaveActivityTest.java
index b24b56d..82632f2 100644
--- a/tests/autofillservice/src/android/autofillservice/cts/SimpleSaveActivityTest.java
+++ b/tests/autofillservice/src/android/autofillservice/cts/SimpleSaveActivityTest.java
@@ -38,6 +38,7 @@
 import android.content.Intent;
 import android.graphics.Bitmap;
 import android.os.Bundle;
+import android.platform.test.annotations.AppModeFull;
 import android.service.autofill.BatchUpdates;
 import android.service.autofill.CustomDescription;
 import android.service.autofill.FillEventHistory;
@@ -183,6 +184,7 @@
     }
 
     @Test
+    @AppModeFull // testAutoFillOneDatasetAndSave() is enough to test ephemeral apps support
     public void testSave() throws Exception {
         saveTest(false);
     }
@@ -538,13 +540,6 @@
         autofillExpecation.assertAutoFilled();
     }
 
-    private void startWelcomeActivityOnNewTask() throws Exception {
-        final Intent intent = new Intent(mContext, WelcomeActivity.class)
-                .setFlags(Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS | Intent.FLAG_ACTIVITY_NEW_TASK);
-        mWelcomeActivityRule.launchActivity(intent);
-        WelcomeActivity.assertShowingDefaultMessage(mUiBot);
-    }
-
     @Override
     protected void saveUiRestoredAfterTappingLinkTest(PostSaveLinkTappedAction type)
             throws Exception {
@@ -753,6 +748,7 @@
     }
 
     @Test
+    @AppModeFull // Service-specific test
     public void testSelectedDatasetsAreSentOnSaveRequest() throws Exception {
         startActivity();
 
@@ -911,6 +907,7 @@
     }
 
     @Test
+    @AppModeFull // testSanitizeOnSaveWhenAppChangeValues() is enough to test ephemeral apps support
     public void testSanitizeOnSaveNoChange() throws Exception {
         startActivity();
 
@@ -948,6 +945,7 @@
     }
 
     @Test
+    @AppModeFull // testSanitizeOnSaveWhenAppChangeValues() is enough to test ephemeral apps support
     public void testDontSaveWhenSanitizedValueForRequiredFieldDidntChange() throws Exception {
         startActivity();
 
@@ -985,6 +983,7 @@
     }
 
     @Test
+    @AppModeFull // testSanitizeOnSaveWhenAppChangeValues() is enough to test ephemeral apps support
     public void testDontSaveWhenSanitizedValueForOptionalFieldDidntChange() throws Exception {
         startActivity();
 
@@ -1017,6 +1016,7 @@
     }
 
     @Test
+    @AppModeFull // testSanitizeOnSaveWhenAppChangeValues() is enough to test ephemeral apps support
     public void testDontSaveWhenRequiredFieldFailedSanitization() throws Exception {
         startActivity();
 
@@ -1051,6 +1051,7 @@
     }
 
     @Test
+    @AppModeFull // testSanitizeOnSaveWhenAppChangeValues() is enough to test ephemeral apps support
     public void testDontSaveWhenOptionalFieldFailedSanitization() throws Exception {
         startActivity();
 
@@ -1086,6 +1087,7 @@
     }
 
     @Test
+    @AppModeFull // testSanitizeOnSaveWhenAppChangeValues() is enough to test ephemeral apps support
     public void testDontSaveWhenInitialValueAndNoUserInputAndServiceDatasets() throws Throwable {
         // Prepare activitiy.
         startActivity();
diff --git a/tests/autofillservice/src/android/autofillservice/cts/TextValueSanitizerTest.java b/tests/autofillservice/src/android/autofillservice/cts/TextValueSanitizerTest.java
index 572e3b1..d08c7e7 100644
--- a/tests/autofillservice/src/android/autofillservice/cts/TextValueSanitizerTest.java
+++ b/tests/autofillservice/src/android/autofillservice/cts/TextValueSanitizerTest.java
@@ -20,6 +20,7 @@
 
 import static org.testng.Assert.assertThrows;
 
+import android.platform.test.annotations.AppModeFull;
 import android.service.autofill.TextValueSanitizer;
 import android.support.test.runner.AndroidJUnit4;
 import android.view.autofill.AutofillValue;
@@ -30,6 +31,7 @@
 import java.util.regex.Pattern;
 
 @RunWith(AndroidJUnit4.class)
+@AppModeFull // Unit test
 public class TextValueSanitizerTest {
 
     @Test
diff --git a/tests/autofillservice/src/android/autofillservice/cts/TimePickerClockActivityTest.java b/tests/autofillservice/src/android/autofillservice/cts/TimePickerClockActivityTest.java
index 8135eba..903011f 100644
--- a/tests/autofillservice/src/android/autofillservice/cts/TimePickerClockActivityTest.java
+++ b/tests/autofillservice/src/android/autofillservice/cts/TimePickerClockActivityTest.java
@@ -15,8 +15,11 @@
  */
 package android.autofillservice.cts;
 
+import android.platform.test.annotations.AppModeFull;
+
 import org.junit.Rule;
 
+@AppModeFull // Unit test
 public class TimePickerClockActivityTest extends TimePickerTestCase<TimePickerClockActivity> {
 
     @Rule
diff --git a/tests/autofillservice/src/android/autofillservice/cts/TimePickerSpinnerActivityTest.java b/tests/autofillservice/src/android/autofillservice/cts/TimePickerSpinnerActivityTest.java
index 2d97f03..07e4592 100644
--- a/tests/autofillservice/src/android/autofillservice/cts/TimePickerSpinnerActivityTest.java
+++ b/tests/autofillservice/src/android/autofillservice/cts/TimePickerSpinnerActivityTest.java
@@ -15,8 +15,11 @@
  */
 package android.autofillservice.cts;
 
+import android.platform.test.annotations.AppModeFull;
+
 import org.junit.Rule;
 
+@AppModeFull // Unit test
 public class TimePickerSpinnerActivityTest extends TimePickerTestCase<TimePickerSpinnerActivity> {
 
     @Rule
diff --git a/tests/autofillservice/src/android/autofillservice/cts/UiBot.java b/tests/autofillservice/src/android/autofillservice/cts/UiBot.java
index 17819fe..747b370 100644
--- a/tests/autofillservice/src/android/autofillservice/cts/UiBot.java
+++ b/tests/autofillservice/src/android/autofillservice/cts/UiBot.java
@@ -99,7 +99,6 @@
     private static final BySelector DATASET_HEADER_SELECTOR =
             By.res("android", RESOURCE_ID_DATASET_HEADER);
 
-    private static final boolean DONT_DUMP_ON_ERROR = false;
     private static final boolean DUMP_ON_ERROR = true;
 
     /** Pass to {@link #setScreenOrientation(int)} to change the display to portrait mode */
@@ -170,10 +169,20 @@
      * @return the dataset picker object.
      */
     UiObject2 assertDatasets(String...names) throws Exception {
-        final UiObject2 picker = findDatasetPicker(UI_DATASET_PICKER_TIMEOUT);
-        assertWithMessage("wrong dataset names").that(getChildrenAsText(picker))
-                .containsExactlyElementsIn(Arrays.asList(names)).inOrder();
-        return picker;
+        // TODO: change run() so it can rethrow the original message
+        return UI_DATASET_PICKER_TIMEOUT.run("assertDatasets: " + Arrays.toString(names), () -> {
+            final UiObject2 picker = findDatasetPicker(UI_DATASET_PICKER_TIMEOUT);
+            try {
+                // TODO: use a library to check it contains, instead of asserThat + catch exception
+                assertWithMessage("wrong dataset names").that(getChildrenAsText(picker))
+                        .containsExactlyElementsIn(Arrays.asList(names)).inOrder();
+                return picker;
+            } catch (AssertionError e) {
+                // Value mismatch - most likely UI didn't change yet, try again
+                Log.w(TAG, "datasets don't match yet: " + e.getMessage());
+                return null;
+            }
+        });
     }
 
     /**
@@ -182,10 +191,20 @@
      * @return the dataset picker object.
      */
     UiObject2 assertDatasetsContains(String...names) throws Exception {
-        final UiObject2 picker = findDatasetPicker(UI_DATASET_PICKER_TIMEOUT);
-        assertWithMessage("wrong dataset names").that(getChildrenAsText(picker))
+        // TODO: change run() so it can rethrow the original message
+        return UI_DATASET_PICKER_TIMEOUT.run("assertDatasets: " + Arrays.toString(names), () -> {
+            final UiObject2 picker = findDatasetPicker(UI_DATASET_PICKER_TIMEOUT);
+            try {
+                // TODO: use a library to check it contains, instead of asserThat + catch exception
+                assertWithMessage("wrong dataset names").that(getChildrenAsText(picker))
                 .containsAllIn(Arrays.asList(names)).inOrder();
-        return picker;
+                return picker;
+            } catch (AssertionError e) {
+                // Value mismatch - most likely UI didn't change yet, try again
+                Log.w(TAG, "datasets don't match yet: " + e.getMessage());
+                return null;
+            }
+        });
     }
 
     /**
diff --git a/tests/autofillservice/src/android/autofillservice/cts/UserDataTest.java b/tests/autofillservice/src/android/autofillservice/cts/UserDataTest.java
index 59f57cf..354bbc9 100644
--- a/tests/autofillservice/src/android/autofillservice/cts/UserDataTest.java
+++ b/tests/autofillservice/src/android/autofillservice/cts/UserDataTest.java
@@ -28,6 +28,7 @@
 
 import android.autofillservice.cts.common.SettingsStateChangerRule;
 import android.content.Context;
+import android.platform.test.annotations.AppModeFull;
 import android.service.autofill.UserData;
 import android.support.test.InstrumentationRegistry;
 
@@ -40,6 +41,7 @@
 import org.mockito.junit.MockitoJUnitRunner;
 
 @RunWith(MockitoJUnitRunner.class)
+@AppModeFull // Unit test
 public class UserDataTest {
 
     private static final Context sContext = InstrumentationRegistry.getContext();
diff --git a/tests/autofillservice/src/android/autofillservice/cts/ValidatorTest.java b/tests/autofillservice/src/android/autofillservice/cts/ValidatorTest.java
index 829302d..622e127 100644
--- a/tests/autofillservice/src/android/autofillservice/cts/ValidatorTest.java
+++ b/tests/autofillservice/src/android/autofillservice/cts/ValidatorTest.java
@@ -25,6 +25,7 @@
 import static org.mockito.Mockito.doReturn;
 import static org.mockito.Mockito.mock;
 
+import android.platform.test.annotations.AppModeFull;
 import android.service.autofill.InternalValidator;
 import android.service.autofill.LuhnChecksumValidator;
 import android.service.autofill.ValueFinder;
@@ -38,6 +39,7 @@
 /**
  * Simple integration test to verify that the UI is only shown if the validator passes.
  */
+@AppModeFull // Service-specific test
 public class ValidatorTest extends AutoFillServiceTestCase {
     @Rule
     public final AutofillActivityTestRule<LoginActivity> mActivityRule =
diff --git a/tests/autofillservice/src/android/autofillservice/cts/ValidatorsTest.java b/tests/autofillservice/src/android/autofillservice/cts/ValidatorsTest.java
index 6c7979d..9f5b69c 100644
--- a/tests/autofillservice/src/android/autofillservice/cts/ValidatorsTest.java
+++ b/tests/autofillservice/src/android/autofillservice/cts/ValidatorsTest.java
@@ -27,6 +27,7 @@
 import static org.mockito.Mockito.verify;
 import static org.testng.Assert.assertThrows;
 
+import android.platform.test.annotations.AppModeFull;
 import android.service.autofill.InternalValidator;
 import android.service.autofill.Validator;
 import android.service.autofill.ValueFinder;
@@ -37,6 +38,7 @@
 import org.mockito.junit.MockitoJUnitRunner;
 
 @RunWith(MockitoJUnitRunner.class)
+@AppModeFull // Unit test
 public class ValidatorsTest extends AutoFillServiceTestCase {
 
     @Mock private Validator mInvalidValidator;
diff --git a/tests/autofillservice/src/android/autofillservice/cts/ViewAttributesTest.java b/tests/autofillservice/src/android/autofillservice/cts/ViewAttributesTest.java
index 45a00bf..84370ca 100644
--- a/tests/autofillservice/src/android/autofillservice/cts/ViewAttributesTest.java
+++ b/tests/autofillservice/src/android/autofillservice/cts/ViewAttributesTest.java
@@ -21,14 +21,16 @@
 import static com.google.common.truth.Truth.assertThat;
 
 import android.app.assist.AssistStructure;
-import androidx.annotation.IdRes;
-import androidx.annotation.NonNull;
-import androidx.annotation.Nullable;
+import android.platform.test.annotations.AppModeFull;
 import android.support.test.runner.AndroidJUnit4;
 import android.view.View;
 import android.view.autofill.AutofillValue;
 import android.widget.EditText;
 
+import androidx.annotation.IdRes;
+import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
+
 import org.junit.Before;
 import org.junit.Rule;
 import org.junit.Test;
@@ -37,6 +39,7 @@
 import java.util.function.Consumer;
 
 @RunWith(AndroidJUnit4.class)
+@AppModeFull // Unit test
 public class ViewAttributesTest extends AutoFillServiceTestCase {
     @Rule
     public final AutofillActivityTestRule<ViewAttributesTestActivity> mActivityRule =
diff --git a/tests/autofillservice/src/android/autofillservice/cts/VirtualContainerActivityCompatModeTest.java b/tests/autofillservice/src/android/autofillservice/cts/VirtualContainerActivityCompatModeTest.java
index e1bc0bd..b50fb22 100644
--- a/tests/autofillservice/src/android/autofillservice/cts/VirtualContainerActivityCompatModeTest.java
+++ b/tests/autofillservice/src/android/autofillservice/cts/VirtualContainerActivityCompatModeTest.java
@@ -41,6 +41,7 @@
 import android.autofillservice.cts.common.SettingsStateChangerRule;
 import android.content.Context;
 import android.os.SystemClock;
+import android.platform.test.annotations.AppModeFull;
 import android.service.autofill.SaveInfo;
 import android.support.test.InstrumentationRegistry;
 
@@ -126,6 +127,7 @@
     }
 
     @Test
+    @AppModeFull // testMultipleUrlBars_firstDoesNotExist() is enough to test ephemeral apps support
     public void testMultipleUrlBars_bothExist() throws Exception {
         SettingsHelper.syncSet(sContext, NAMESPACE_GLOBAL, AUTOFILL_COMPAT_MODE_ALLOWED_PACKAGES,
                 SERVICE_PACKAGE + "[my_url_bar,my_url_bar2]");
@@ -152,6 +154,7 @@
     }
 
     @Test
+    @AppModeFull // testMultipleUrlBars_firstDoesNotExist() is enough to test ephemeral apps support
     public void testFocusOnUrlBarIsIgnored() throws Throwable {
         // Set service.
         enableService();
@@ -173,6 +176,7 @@
     }
 
     @Test
+    @AppModeFull // testMultipleUrlBars_firstDoesNotExist() is enough to test ephemeral apps support
     public void testUrlBarChangeIgnoredWhenServiceCanSave() throws Throwable {
         // Set service.
         enableService();
@@ -225,6 +229,7 @@
     }
 
     @Test
+    @AppModeFull // testMultipleUrlBars_firstDoesNotExist() is enough to test ephemeral apps support
     public void testUrlBarChangeCancelSessionWhenServiceCannotSave() throws Throwable {
         // Set service.
         enableService();
@@ -242,7 +247,7 @@
         // Trigger auto-fill.
         focusToUsernameExpectNoWindowEvent();
         sReplier.getNextFillRequest();
-        mUiBot.assertDatasets("The Dude");
+        assertDatasetShown(mActivity.mUsername, "The Dude");
 
         // Fill in some stuff
         mActivity.mUsername.setText("foo");
@@ -264,6 +269,7 @@
     }
 
     @Test
+    @AppModeFull // testMultipleUrlBars_firstDoesNotExist() is enough to test ephemeral apps support
     public void testUrlBarChangeCancelSessionWhenServiceReturnsNullResponse() throws Throwable {
         // Set service.
         enableService();
diff --git a/tests/autofillservice/src/android/autofillservice/cts/VirtualContainerActivityTest.java b/tests/autofillservice/src/android/autofillservice/cts/VirtualContainerActivityTest.java
index 5fd507f..84cb1f6 100644
--- a/tests/autofillservice/src/android/autofillservice/cts/VirtualContainerActivityTest.java
+++ b/tests/autofillservice/src/android/autofillservice/cts/VirtualContainerActivityTest.java
@@ -42,6 +42,7 @@
 import android.autofillservice.cts.VirtualContainerView.Line;
 import android.autofillservice.cts.VirtualContainerView.VisibilityIntegrationMode;
 import android.graphics.Rect;
+import android.platform.test.annotations.AppModeFull;
 import android.service.autofill.SaveInfo;
 import android.support.test.uiautomator.UiObject2;
 import android.text.InputType;
@@ -108,6 +109,7 @@
     }
 
     @Test
+    @AppModeFull // testAutofillSync() is enough to test ephemeral apps support
     public void testAutofillAsync() throws Exception {
         skipTestOnCompatMode();
 
@@ -243,6 +245,7 @@
     }
 
     @Test
+    @AppModeFull // testAutofillSync() is enough to test ephemeral apps support
     public void testAutofillTwoDatasets() throws Exception {
         // Set service.
         enableService();
@@ -315,11 +318,13 @@
     }
 
     @Test
+    @AppModeFull // testAutofillManuallyOneDataset() is enough to test ephemeral apps support
     public void testAutofillManuallyTwoDatasetsPickFirst() throws Exception {
         autofillManuallyTwoDatasets(true);
     }
 
     @Test
+    @AppModeFull // testAutofillManuallyOneDataset() is enough to test ephemeral apps support
     public void testAutofillManuallyTwoDatasetsPickSecond() throws Exception {
         autofillManuallyTwoDatasets(false);
     }
@@ -352,11 +357,12 @@
 
         // Trigger auto-fill.
         mActivity.getSystemService(AutofillManager.class).requestAutofill(
-                mActivity.mCustomView, mActivity.mUsername.text.id, mActivity.mUsername.bounds);
+                mActivity.mCustomView, mActivity.mUsername.text.id,
+                mActivity.mUsername.getAbsCoordinates());
         sReplier.getNextFillRequest();
 
         // Auto-fill it.
-        final UiObject2 picker = mUiBot.assertDatasets("The Dude", "Jenny");
+        final UiObject2 picker = assertDatasetShown(mActivity.mUsername, "The Dude", "Jenny");
         mUiBot.selectDataset(picker, pickFirst ? "The Dude" : "Jenny");
 
         // Check the results.
@@ -390,6 +396,7 @@
     }
 
     @Test
+    @AppModeFull // testAutofillCallbacks() is enough to test ephemeral apps support
     public void testAutofillCallbackDisabled() throws Throwable {
         // Set service.
         disableService();
@@ -403,6 +410,7 @@
     }
 
     @Test
+    @AppModeFull // testAutofillCallbacks() is enough to test ephemeral apps support
     public void testAutofillCallbackNoDatasets() throws Throwable {
         // Set service.
         enableService();
@@ -423,6 +431,7 @@
     }
 
     @Test
+    @AppModeFull // testAutofillCallbacks() is enough to test ephemeral apps support
     public void testAutofillCallbackNoDatasetsButSaveInfo() throws Throwable {
         // Set service.
         enableService();
@@ -613,6 +622,7 @@
     }
 
     @Test
+    @AppModeFull // testSaveNotShown_noUserInput() is enough to test ephemeral apps support
     public void testSaveNotShown_initialValues_noUserInput() throws Throwable {
         // Prepare activitiy.
         mActivity.mUsername.setText("foo");
@@ -637,6 +647,7 @@
     }
 
     @Test
+    @AppModeFull // testSaveNotShown_noUserInput() is enough to test ephemeral apps support
     public void testSaveNotShown_initialValues_noUserInput_serviceDatasets() throws Throwable {
         // Prepare activitiy.
         mActivity.mUsername.setText("foo");
@@ -667,6 +678,7 @@
     }
 
     @Test
+    @AppModeFull // testSaveNotShown_noUserInput() is enough to test ephemeral apps support
     public void testSaveNotShown_userInputMatchesDatasets() throws Throwable {
         // Prepare activitiy.
         mActivity.mUsername.setText("foo");
@@ -725,23 +737,23 @@
         sReplier.getNextFillRequest();
 
         // With no filter text all datasets should be shown
-        mUiBot.assertDatasets(aa, ab, b);
+        assertDatasetShown(mActivity.mUsername, aa, ab, b);
 
         // Only two datasets start with 'a'
         mActivity.mUsername.setText("a");
-        mUiBot.assertDatasets(aa, ab);
+        assertDatasetShown(mActivity.mUsername, aa, ab);
 
         // Only one dataset start with 'aa'
         mActivity.mUsername.setText("aa");
-        mUiBot.assertDatasets(aa);
+        assertDatasetShown(mActivity.mUsername, aa);
 
         // Only two datasets start with 'a'
         mActivity.mUsername.setText("a");
-        mUiBot.assertDatasets(aa, ab);
+        assertDatasetShown(mActivity.mUsername, aa, ab);
 
         // With no filter text all datasets should be shown
         mActivity.mUsername.setText("");
-        mUiBot.assertDatasets(aa, ab, b);
+        assertDatasetShown(mActivity.mUsername, aa, ab, b);
 
         // No dataset start with 'aaa'
         final MyAutofillCallback callback = mActivity.registerCallback();
@@ -753,9 +765,11 @@
     /**
      * Asserts the dataset picker is properly displayed in a give line.
      */
-    protected void assertDatasetShown(Line line, String... expectedDatasets) throws Exception {
+    protected UiObject2 assertDatasetShown(Line line, String... expectedDatasets)
+            throws Exception {
         boolean autofillViewBoundsMatches = !Helper.isAutofillWindowFullScreen(mContext);
-        final Rect pickerBounds = mUiBot.assertDatasets(expectedDatasets).getVisibleBounds();
+        final UiObject2 datasetPicker = mUiBot.assertDatasets(expectedDatasets);
+        final Rect pickerBounds = datasetPicker.getVisibleBounds();
         final Rect fieldBounds = line.getAbsCoordinates();
         if (autofillViewBoundsMatches) {
             assertWithMessage("vertical coordinates don't match; picker=%s, field=%s", pickerBounds,
@@ -763,6 +777,7 @@
             assertWithMessage("horizontal coordinates don't match; picker=%s, field=%s",
                     pickerBounds, fieldBounds).that(pickerBounds.left).isEqualTo(fieldBounds.left);
         }
+        return datasetPicker;
     }
 
     protected void assertLabel(ViewNode node, String expectedValue) {
diff --git a/tests/autofillservice/src/android/autofillservice/cts/WebViewActivityTest.java b/tests/autofillservice/src/android/autofillservice/cts/WebViewActivityTest.java
index aa17972..a777497 100644
--- a/tests/autofillservice/src/android/autofillservice/cts/WebViewActivityTest.java
+++ b/tests/autofillservice/src/android/autofillservice/cts/WebViewActivityTest.java
@@ -27,6 +27,7 @@
 import android.autofillservice.cts.CannedFillResponse.CannedDataset;
 import android.autofillservice.cts.InstrumentedAutoFillService.FillRequest;
 import android.autofillservice.cts.InstrumentedAutoFillService.SaveRequest;
+import android.platform.test.annotations.AppModeFull;
 import android.support.test.uiautomator.UiObject2;
 import android.view.KeyEvent;
 import android.view.ViewStructure.HtmlInfo;
@@ -67,6 +68,7 @@
     }
 
     @Test
+    @AppModeFull // testAutofillOneDataset() is enough to test ephemeral apps support
     public void testAutofillNoDatasets() throws Exception {
         // Set service.
         enableService();
@@ -92,6 +94,7 @@
 
     @Ignore("blocked on b/74793485")
     @Test
+    @AppModeFull // testAutofillOneDataset() is enough to test ephemeral apps support
     public void testAutofillOneDataset_usingAppContext() throws Exception {
         autofillOneDatasetTest(true);
     }
@@ -311,6 +314,7 @@
     }
 
     @Test
+    @AppModeFull // testAutofillAndSave() is enough to test ephemeral apps support
     public void testAutofillAndSave_withExternalViews_loadWebViewFirst() throws Exception {
         // Set service.
         enableService();
@@ -435,9 +439,9 @@
 
 
     @Test
+    @Ignore("blocked on b/69461853")
+    @AppModeFull // testAutofillAndSave() is enough to test ephemeral apps support
     public void testAutofillAndSave_withExternalViews_loadExternalViewsFirst() throws Exception {
-        if (true) return; // TODO(b/69461853): re-enable once WebView fixes it
-
         // Set service.
         enableService();
 
diff --git a/tests/autofillservice/src/android/autofillservice/cts/common/SettingsHelper.java b/tests/autofillservice/src/android/autofillservice/cts/common/SettingsHelper.java
index 1c1ffba..219c55b 100644
--- a/tests/autofillservice/src/android/autofillservice/cts/common/SettingsHelper.java
+++ b/tests/autofillservice/src/android/autofillservice/cts/common/SettingsHelper.java
@@ -96,7 +96,14 @@
     public static void syncDelete(@NonNull Context context, @NonNull String namespace,
             @NonNull String key) {
 
-        final OneTimeSettingsListener observer = new OneTimeSettingsListener(context, key);
+        final String currentValue = get(namespace, key);
+        if (currentValue == null || currentValue.equals("null")) {
+            // Already set, ignore
+            return;
+        }
+
+        final OneTimeSettingsListener observer = new OneTimeSettingsListener(context, namespace,
+                key);
         delete(namespace, key);
         observer.assertCalled();
 
diff --git a/tests/autofillservice/src/android/autofillservice/cts/common/StateChangerRuleTest.java b/tests/autofillservice/src/android/autofillservice/cts/common/StateChangerRuleTest.java
index 9c2018e..6604cf4 100644
--- a/tests/autofillservice/src/android/autofillservice/cts/common/StateChangerRuleTest.java
+++ b/tests/autofillservice/src/android/autofillservice/cts/common/StateChangerRuleTest.java
@@ -28,6 +28,8 @@
 import static org.testng.Assert.assertThrows;
 import static org.testng.Assert.expectThrows;
 
+import android.platform.test.annotations.AppModeFull;
+
 import org.junit.Test;
 import org.junit.runner.Description;
 import org.junit.runner.RunWith;
@@ -36,6 +38,7 @@
 import org.mockito.junit.MockitoJUnitRunner;
 
 @RunWith(MockitoJUnitRunner.class)
+@AppModeFull // Unit test
 public class StateChangerRuleTest {
 
     private final RuntimeException mRuntimeException = new RuntimeException("D'OH");
diff --git a/tests/autofillservice/src/android/autofillservice/cts/common/StateKeeperRuleTest.java b/tests/autofillservice/src/android/autofillservice/cts/common/StateKeeperRuleTest.java
index 6424d3c..97db0a7 100644
--- a/tests/autofillservice/src/android/autofillservice/cts/common/StateKeeperRuleTest.java
+++ b/tests/autofillservice/src/android/autofillservice/cts/common/StateKeeperRuleTest.java
@@ -28,6 +28,8 @@
 import static org.testng.Assert.assertThrows;
 import static org.testng.Assert.expectThrows;
 
+import android.platform.test.annotations.AppModeFull;
+
 import org.junit.Test;
 import org.junit.runner.Description;
 import org.junit.runner.RunWith;
@@ -36,6 +38,7 @@
 import org.mockito.junit.MockitoJUnitRunner;
 
 @RunWith(MockitoJUnitRunner.class)
+@AppModeFull // Unit test
 public class StateKeeperRuleTest {
 
     private final RuntimeException mRuntimeException = new RuntimeException("D'OH");
diff --git a/tests/camera/src/android/hardware/camera2/cts/CameraManagerTest.java b/tests/camera/src/android/hardware/camera2/cts/CameraManagerTest.java
index 81335c0..170cc3f 100644
--- a/tests/camera/src/android/hardware/camera2/cts/CameraManagerTest.java
+++ b/tests/camera/src/android/hardware/camera2/cts/CameraManagerTest.java
@@ -144,6 +144,7 @@
          * Test: that if the device has front or rear facing cameras, then there
          * must be matched system features.
          */
+        boolean externalCameraConnected = false;
         for (int i = 0; i < ids.length; i++) {
             CameraCharacteristics props = mCameraManager.getCameraCharacteristics(ids[i]);
             assertNotNull("Can't get camera characteristics for camera " + ids[i], props);
@@ -156,6 +157,7 @@
                 assertTrue("System doesn't have back camera feature",
                         mPackageManager.hasSystemFeature(PackageManager.FEATURE_CAMERA));
             } else if (lensFacing == CameraCharacteristics.LENS_FACING_EXTERNAL) {
+                externalCameraConnected = true;
                 assertTrue("System doesn't have external camera feature",
                         mPackageManager.hasSystemFeature(PackageManager.FEATURE_CAMERA_EXTERNAL));
             } else {
@@ -163,6 +165,12 @@
             }
         }
 
+        // Test an external camera is connected if FEATURE_CAMERA_EXTERNAL is advertised
+        if (mPackageManager.hasSystemFeature(PackageManager.FEATURE_CAMERA_EXTERNAL)) {
+            assertTrue("External camera is not connected on device with FEATURE_CAMERA_EXTERNAL",
+                    externalCameraConnected);
+        }
+
         /**
          * Test: that if there is one camera device, then the system must have some
          * specific features.
diff --git a/tests/camera/src/android/hardware/camera2/cts/CaptureRequestTest.java b/tests/camera/src/android/hardware/camera2/cts/CaptureRequestTest.java
index 50e3484..28a625d 100644
--- a/tests/camera/src/android/hardware/camera2/cts/CaptureRequestTest.java
+++ b/tests/camera/src/android/hardware/camera2/cts/CaptureRequestTest.java
@@ -167,6 +167,7 @@
                         physicalIds);
                 requestBuilder.addTarget(surface);
                 captureRequestOriginal = requestBuilder.build();
+                p = Parcel.obtain();
                 captureRequestOriginal.writeToParcel(p, 0);
                 p.setDataPosition(0);
                 captureRequestParcelled = CaptureRequest.CREATOR.createFromParcel(p);
@@ -176,6 +177,7 @@
                 p.recycle();
 
                 // Check various invalid cases
+                p = Parcel.obtain();
                 p.writeInt(-1);
                 p.setDataPosition(0);
                 try {
@@ -186,6 +188,7 @@
                 }
                 p.recycle();
 
+                p = Parcel.obtain();
                 p.writeInt(0);
                 p.setDataPosition(0);
                 try {
@@ -196,6 +199,7 @@
                 }
                 p.recycle();
 
+                p = Parcel.obtain();
                 p.writeInt(1);
                 p.setDataPosition(0);
                 try {
@@ -204,6 +208,7 @@
                 } catch (RuntimeException e) {
                     // Expected
                 }
+                p.recycle();
             } finally {
                 closeDevice();
             }
@@ -798,6 +803,10 @@
         for (String id : mCameraIds) {
             try {
                 openDevice(id);
+                if (mStaticInfo.isHardwareLevelLegacy()) {
+                    Log.i(TAG, "Camera " + id + " is legacy, skipping");
+                    continue;
+                }
                 if (!mStaticInfo.isColorOutputSupported()) {
                     Log.i(TAG, "Camera " + id + " does not support color outputs, skipping");
                     continue;
diff --git a/tests/camera/src/android/hardware/camera2/cts/LogicalCameraDeviceTest.java b/tests/camera/src/android/hardware/camera2/cts/LogicalCameraDeviceTest.java
index be4e772..50d027d 100644
--- a/tests/camera/src/android/hardware/camera2/cts/LogicalCameraDeviceTest.java
+++ b/tests/camera/src/android/hardware/camera2/cts/LogicalCameraDeviceTest.java
@@ -99,6 +99,10 @@
             try {
                 Log.i(TAG, "Testing Camera " + id);
                 openDevice(id);
+                if (mStaticInfo.isHardwareLevelLegacy()) {
+                    Log.i(TAG, "Camera " + id + " is legacy, skipping");
+                    continue;
+                }
 
                 Size yuvSize = mOrderedPreviewSizes.get(0);
                 // Create a YUV image reader.
@@ -412,6 +416,10 @@
                 Log.i(TAG, "Testing Camera " + id);
                 openDevice(id);
 
+                if (mStaticInfo.isHardwareLevelLegacy()) {
+                    Log.i(TAG, "Camera " + id + " is legacy, skipping");
+                    continue;
+                }
                 if (!mStaticInfo.isColorOutputSupported()) {
                     Log.i(TAG, "Camera " + id + " does not support color outputs, skipping");
                     continue;
diff --git a/tests/camera/src/android/hardware/camera2/cts/testcases/Camera2AndroidTestCase.java b/tests/camera/src/android/hardware/camera2/cts/testcases/Camera2AndroidTestCase.java
index 777e0cd..4513c5c 100644
--- a/tests/camera/src/android/hardware/camera2/cts/testcases/Camera2AndroidTestCase.java
+++ b/tests/camera/src/android/hardware/camera2/cts/testcases/Camera2AndroidTestCase.java
@@ -49,6 +49,7 @@
 
 import java.nio.ByteBuffer;
 import java.util.ArrayList;
+import java.util.Arrays;
 import java.util.HashMap;
 import java.util.List;
 
@@ -124,6 +125,14 @@
 
     @Override
     protected void tearDown() throws Exception {
+        String[] cameraIdsPostTest = mCameraManager.getCameraIdList();
+        assertNotNull("Camera ids shouldn't be null", cameraIdsPostTest);
+        Log.i(TAG, "Camera ids in setup:" + Arrays.toString(mCameraIds));
+        Log.i(TAG, "Camera ids in tearDown:" + Arrays.toString(cameraIdsPostTest));
+        assertTrue(
+                "Number of cameras changed from " + mCameraIds.length + " to " +
+                cameraIdsPostTest.length,
+                mCameraIds.length == cameraIdsPostTest.length);
         mHandlerThread.quitSafely();
         mHandler = null;
         closeDefaultImageReader();
diff --git a/tests/camera/src/android/hardware/camera2/cts/testcases/Camera2MultiViewTestCase.java b/tests/camera/src/android/hardware/camera2/cts/testcases/Camera2MultiViewTestCase.java
index 66324da..48c84ce 100644
--- a/tests/camera/src/android/hardware/camera2/cts/testcases/Camera2MultiViewTestCase.java
+++ b/tests/camera/src/android/hardware/camera2/cts/testcases/Camera2MultiViewTestCase.java
@@ -115,6 +115,14 @@
 
     @Override
     protected void tearDown() throws Exception {
+        String[] cameraIdsPostTest = mCameraManager.getCameraIdList();
+        assertNotNull("Camera ids shouldn't be null", cameraIdsPostTest);
+        Log.i(TAG, "Camera ids in setup:" + Arrays.toString(mCameraIds));
+        Log.i(TAG, "Camera ids in tearDown:" + Arrays.toString(cameraIdsPostTest));
+        assertTrue(
+                "Number of cameras changed from " + mCameraIds.length + " to " +
+                cameraIdsPostTest.length,
+                mCameraIds.length == cameraIdsPostTest.length);
         mHandlerThread.quitSafely();
         mHandler = null;
         mCameraListener = null;
diff --git a/tests/camera/src/android/hardware/camera2/cts/testcases/Camera2SurfaceViewTestCase.java b/tests/camera/src/android/hardware/camera2/cts/testcases/Camera2SurfaceViewTestCase.java
index 29253eb..6697b75 100644
--- a/tests/camera/src/android/hardware/camera2/cts/testcases/Camera2SurfaceViewTestCase.java
+++ b/tests/camera/src/android/hardware/camera2/cts/testcases/Camera2SurfaceViewTestCase.java
@@ -144,6 +144,14 @@
 
     @Override
     protected void tearDown() throws Exception {
+        String[] cameraIdsPostTest = mCameraManager.getCameraIdList();
+        assertNotNull("Camera ids shouldn't be null", cameraIdsPostTest);
+        Log.i(TAG, "Camera ids in setup:" + Arrays.toString(mCameraIds));
+        Log.i(TAG, "Camera ids in tearDown:" + Arrays.toString(cameraIdsPostTest));
+        assertTrue(
+                "Number of cameras changed from " + mCameraIds.length + " to " +
+                cameraIdsPostTest.length,
+                mCameraIds.length == cameraIdsPostTest.length);
         // Teardown the camera preview required environments.
         mHandlerThread.quitSafely();
         mHandler = null;
diff --git a/tests/filesystem/Android.mk b/tests/filesystem/Android.mk
index 9dca6af..e18754e 100644
--- a/tests/filesystem/Android.mk
+++ b/tests/filesystem/Android.mk
@@ -27,7 +27,7 @@
 # Tag this module as a cts test artifact
 LOCAL_COMPATIBILITY_SUITE := cts vts general-tests
 
-LOCAL_SDK_VERSION := 16
+LOCAL_SDK_VERSION := test_current
 
 include $(BUILD_CTS_PACKAGE)
 
diff --git a/tests/filesystem/AndroidManifest.xml b/tests/filesystem/AndroidManifest.xml
index c02ac77..f76ea53 100644
--- a/tests/filesystem/AndroidManifest.xml
+++ b/tests/filesystem/AndroidManifest.xml
@@ -15,7 +15,8 @@
 -->
 
 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
-        package="android.filesystem.cts">
+        package="android.filesystem.cts"
+        android:targetSandboxVersion="2">
 
     <uses-permission android:name="android.permission.DISABLE_KEYGUARD" />
     <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
diff --git a/tests/filesystem/src/android/filesystem/cts/AlmostFullTest.java b/tests/filesystem/src/android/filesystem/cts/AlmostFullTest.java
index e25c2be..d75ebbf 100644
--- a/tests/filesystem/src/android/filesystem/cts/AlmostFullTest.java
+++ b/tests/filesystem/src/android/filesystem/cts/AlmostFullTest.java
@@ -16,18 +16,24 @@
 
 package android.filesystem.cts;
 
-import android.util.Log;
+import static android.support.test.InstrumentationRegistry.getContext;
+import static android.support.test.InstrumentationRegistry.getInstrumentation;
 
-import com.android.compatibility.common.util.CtsAndroidTestCase;
+import android.support.test.runner.AndroidJUnit4;
+import android.util.Log;
 
 import com.android.compatibility.common.util.DeviceReportLog;
 import com.android.compatibility.common.util.SystemUtil;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
 
 import java.util.concurrent.atomic.AtomicBoolean;
 import java.util.concurrent.atomic.AtomicInteger;
 
-public class AlmostFullTest extends CtsAndroidTestCase {
-
+@RunWith(AndroidJUnit4.class)
+public class AlmostFullTest {
     private static final String DIR_INITIAL_FILL = "INITIAL_FILL";
     private static final String DIR_SEQ_UPDATE = "SEQ_UPDATE";
     private static final String DIR_RANDOM_WR = "RANDOM_WR";
@@ -48,9 +54,8 @@
         Log.i(TAG, "++currentCounter: " + currentCounter);
     }
 
-    @Override
-    protected void setUp() throws Exception {
-        super.setUp();
+    @Before
+    public void setUp() throws Exception {
         if (mDiskFilled.compareAndSet(false, true)) {
             Log.i(TAG, "Filling disk");
             // initial fill done in two stage as disk can be filled by other
@@ -81,8 +86,8 @@
         Log.i(TAG, "free disk " + SystemUtil.getFreeDiskSize(getContext()));
     }
 
-    @Override
-    protected void tearDown() throws Exception {
+    @After
+    public void tearDown() throws Exception {
         Log.i(TAG, "tearDown free disk " + SystemUtil.getFreeDiskSize(getContext()));
         int currentCounter = mRefCounter.decrementAndGet();
         Log.i(TAG, "--currentCounter: " + currentCounter);
@@ -93,9 +98,9 @@
         FileUtil.removeFileOrDir(getContext(), DIR_RANDOM_WR);
         FileUtil.removeFileOrDir(getContext(), DIR_RANDOM_RD);
         Log.i(TAG, "tearDown free disk " + SystemUtil.getFreeDiskSize(getContext()));
-        super.tearDown();
     }
 
+    @Test
     public void testSequentialUpdate() throws Exception {
         // now about freeSpaceToLeave should be left
         // and try updating exceeding the free space size
@@ -115,6 +120,7 @@
 
     // TODO: file size too small and caching will give wrong better result.
     // needs to flush cache by reading big files per each read.
+    @Test
     public void testRandomRead() throws Exception {
         final int BUFFER_SIZE = 4 * 1024;
         final long fileSize = 400L * 1024L * 1024L;
@@ -129,6 +135,7 @@
         report.submit(getInstrumentation());
     }
 
+    @Test
     public void testRandomUpdate() throws Exception {
         final int BUFFER_SIZE = 4 * 1024;
         final long fileSize = 256L * 1024L * 1024L;
diff --git a/tests/filesystem/src/android/filesystem/cts/RandomRWTest.java b/tests/filesystem/src/android/filesystem/cts/RandomRWTest.java
index f9abebb..a58b397 100644
--- a/tests/filesystem/src/android/filesystem/cts/RandomRWTest.java
+++ b/tests/filesystem/src/android/filesystem/cts/RandomRWTest.java
@@ -16,25 +16,32 @@
 
 package android.filesystem.cts;
 
+import static android.support.test.InstrumentationRegistry.getContext;
+import static android.support.test.InstrumentationRegistry.getInstrumentation;
+
 import android.os.Environment;
 
+import android.support.test.runner.AndroidJUnit4;
 import com.android.compatibility.common.util.CddTest;
-import com.android.compatibility.common.util.CtsAndroidTestCase;
 import com.android.compatibility.common.util.DeviceReportLog;
+import org.junit.After;
+import org.junit.Test;
+import org.junit.runner.RunWith;
 
-public class RandomRWTest extends CtsAndroidTestCase {
+@RunWith(AndroidJUnit4.class)
+public class RandomRWTest {
     private static final String DIR_RANDOM_WR = "RANDOM_WR";
     private static final String DIR_RANDOM_RD = "RANDOM_RD";
     private static final String REPORT_LOG_NAME = "CtsFileSystemTestCases";
 
-    @Override
-    protected void tearDown() throws Exception {
+    @After
+    public void tearDown() throws Exception {
         FileUtil.removeFileOrDir(getContext(), DIR_RANDOM_WR);
         FileUtil.removeFileOrDir(getContext(), DIR_RANDOM_RD);
-        super.tearDown();
     }
 
     @CddTest(requirement="8.2")
+    @Test
     public void testRandomRead() throws Exception {
         final int READ_BUFFER_SIZE = 4 * 1024;
         final long fileSize = FileUtil.getFileSizeExceedingMemory(getContext(), READ_BUFFER_SIZE);
@@ -50,6 +57,7 @@
 
     // It is taking too long in some device, and thus cannot run multiple times
     @CddTest(requirement="8.2")
+    @Test
     public void testRandomUpdate() throws Exception {
         final int WRITE_BUFFER_SIZE = 4 * 1024;
         final long usableSpace = Environment.getDataDirectory().getUsableSpace();
diff --git a/tests/filesystem/src/android/filesystem/cts/SequentialRWTest.java b/tests/filesystem/src/android/filesystem/cts/SequentialRWTest.java
index ed24759..4e7b3f0 100644
--- a/tests/filesystem/src/android/filesystem/cts/SequentialRWTest.java
+++ b/tests/filesystem/src/android/filesystem/cts/SequentialRWTest.java
@@ -16,7 +16,10 @@
 
 package android.filesystem.cts;
 
-import com.android.compatibility.common.util.CtsAndroidTestCase;
+import static android.support.test.InstrumentationRegistry.getContext;
+import static android.support.test.InstrumentationRegistry.getInstrumentation;
+
+import android.support.test.runner.AndroidJUnit4;
 
 import com.android.compatibility.common.util.DeviceReportLog;
 import com.android.compatibility.common.util.MeasureRun;
@@ -26,27 +29,31 @@
 import com.android.compatibility.common.util.Stat;
 
 import com.android.compatibility.common.util.CddTest;
+import org.junit.After;
+import org.junit.Test;
+import org.junit.runner.RunWith;
 
 import java.io.File;
 import java.io.FileInputStream;
 import java.io.IOException;
 
-public class SequentialRWTest extends CtsAndroidTestCase {
+@RunWith(AndroidJUnit4.class)
+public class SequentialRWTest {
     private static final String DIR_SEQ_WR = "SEQ_WR";
     private static final String DIR_SEQ_UPDATE = "SEQ_UPDATE";
     private static final String DIR_SEQ_RD = "SEQ_RD";
     private static final String REPORT_LOG_NAME = "CtsFileSystemTestCases";
     private static final int BUFFER_SIZE = 10 * 1024 * 1024;
 
-    @Override
-    protected void tearDown() throws Exception {
+    @After
+    public void tearDown() throws Exception {
         FileUtil.removeFileOrDir(getContext(), DIR_SEQ_WR);
         FileUtil.removeFileOrDir(getContext(), DIR_SEQ_UPDATE);
         FileUtil.removeFileOrDir(getContext(), DIR_SEQ_RD);
-        super.tearDown();
     }
 
     @CddTest(requirement="8.2")
+    @Test
     public void testSingleSequentialWrite() throws Exception {
         final long fileSize = FileUtil.getFileSizeExceedingMemory(getContext(), BUFFER_SIZE);
         if (fileSize == 0) { // not enough space, give up
@@ -77,6 +84,7 @@
         report.submit(getInstrumentation());
     }
 
+    @Test
     public void testSingleSequentialUpdate() throws Exception {
         final long fileSize = FileUtil.getFileSizeExceedingMemory(getContext(), BUFFER_SIZE);
         if (fileSize == 0) { // not enough space, give up
@@ -89,6 +97,7 @@
     }
 
     @CddTest(requirement="8.2")
+    @Test
     public void testSingleSequentialRead() throws Exception {
         final long fileSize = FileUtil.getFileSizeExceedingMemory(getContext(), BUFFER_SIZE);
         if (fileSize == 0) { // not enough space, give up
diff --git a/tests/fragment/AndroidManifest.xml b/tests/fragment/AndroidManifest.xml
index e1261ef..6b43606b 100644
--- a/tests/fragment/AndroidManifest.xml
+++ b/tests/fragment/AndroidManifest.xml
@@ -14,7 +14,8 @@
      limitations under the License.
 -->
 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
-    package="android.fragment.cts">
+    package="android.fragment.cts"
+    android:targetSandboxVersion="2">
 
     <uses-permission android:name="android.permission.DISABLE_KEYGUARD" />
 
diff --git a/tests/fragment/sdk26/AndroidManifest.xml b/tests/fragment/sdk26/AndroidManifest.xml
index be344b3..ade9fff 100644
--- a/tests/fragment/sdk26/AndroidManifest.xml
+++ b/tests/fragment/sdk26/AndroidManifest.xml
@@ -14,7 +14,8 @@
      limitations under the License.
 -->
 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
-    package="android.fragment.cts.sdk26">
+    package="android.fragment.cts.sdk26"
+    android:targetSandboxVersion="2">
 
     <application>
         <uses-library android:name="android.test.runner" />
diff --git a/tests/framework/base/activitymanager/AndroidManifest.xml b/tests/framework/base/activitymanager/AndroidManifest.xml
index a0d302d5..5b9672b 100644
--- a/tests/framework/base/activitymanager/AndroidManifest.xml
+++ b/tests/framework/base/activitymanager/AndroidManifest.xml
@@ -53,6 +53,10 @@
             android:label="MaxAspectRatioUnsetActivity"
             android:resizeableActivity="false" />
 
+        <activity android:name="android.server.am.ActivityManagerTestBase$SideActivity"
+                  android:resizeableActivity="true"
+                  android:taskAffinity="nobody.but.SideActivity"/>
+
         <activity android:name="android.server.am.lifecycle.ActivityLifecycleClientTestBase$FirstActivity" />
 
         <activity android:name="android.server.am.lifecycle.ActivityLifecycleClientTestBase$SecondActivity"/>
diff --git a/tests/framework/base/activitymanager/app/AndroidManifest.xml b/tests/framework/base/activitymanager/app/AndroidManifest.xml
index dfa1e94..c977b37 100755
--- a/tests/framework/base/activitymanager/app/AndroidManifest.xml
+++ b/tests/framework/base/activitymanager/app/AndroidManifest.xml
@@ -93,10 +93,14 @@
                 android:exported="true"
                 android:taskAffinity="nobody.but.LaunchingActivity"
         />
+        <!--
+         * This activity should have same affinity as LaunchingActivity, because we're using it to
+         * check activities being launched into the same task.
+         -->
         <activity android:name=".AltLaunchingActivity"
                 android:resizeableActivity="true"
                 android:exported="true"
-                android:taskAffinity="nobody.but.AltLaunchingActivity"
+                android:taskAffinity="nobody.but.LaunchingActivity"
         />
         <activity android:name=".PipActivity"
                 android:resizeableActivity="false"
diff --git a/tests/framework/base/activitymanager/src/android/server/am/ActivityManagerActivityVisibilityTests.java b/tests/framework/base/activitymanager/src/android/server/am/ActivityManagerActivityVisibilityTests.java
index 68be619..36be03a 100644
--- a/tests/framework/base/activitymanager/src/android/server/am/ActivityManagerActivityVisibilityTests.java
+++ b/tests/framework/base/activitymanager/src/android/server/am/ActivityManagerActivityVisibilityTests.java
@@ -366,7 +366,7 @@
 
     @Test
     public void testTurnScreenOnAttrWithLockScreen() throws Exception {
-        assumeTrue(isHandheld());
+        assumeTrue(supportsSecureLock());
 
         try (final LockScreenSession lockScreenSession = new LockScreenSession()) {
             lockScreenSession.setLockCredential()
diff --git a/tests/framework/base/activitymanager/src/android/server/am/ActivityManagerAssistantStackTests.java b/tests/framework/base/activitymanager/src/android/server/am/ActivityManagerAssistantStackTests.java
index ad67958..2acf3ac 100644
--- a/tests/framework/base/activitymanager/src/android/server/am/ActivityManagerAssistantStackTests.java
+++ b/tests/framework/base/activitymanager/src/android/server/am/ActivityManagerAssistantStackTests.java
@@ -57,6 +57,7 @@
 import android.server.am.settings.SettingsSession;
 import android.support.test.filters.FlakyTest;
 
+import org.junit.Ignore;
 import org.junit.Test;
 
 /**
@@ -146,6 +147,7 @@
 
     @Test
     @Presubmit
+    @Ignore("b/77272253#comment10")
     public void testAssistantStackLaunchNewTaskWithDockedStack() throws Exception {
         assumeTrue(assistantRunsOnPrimaryDisplay());
         assumeTrue(supportsSplitScreenMultiWindow());
diff --git a/tests/framework/base/activitymanager/src/android/server/am/ActivityManagerDisplayKeyguardTests.java b/tests/framework/base/activitymanager/src/android/server/am/ActivityManagerDisplayKeyguardTests.java
index 32262d5..300d9bd 100644
--- a/tests/framework/base/activitymanager/src/android/server/am/ActivityManagerDisplayKeyguardTests.java
+++ b/tests/framework/base/activitymanager/src/android/server/am/ActivityManagerDisplayKeyguardTests.java
@@ -39,7 +39,7 @@
         super.setUp();
 
         assumeTrue(supportsMultiDisplay());
-        assumeTrue(isHandheld());
+        assumeTrue(supportsInsecureLock());
     }
 
     /**
diff --git a/tests/framework/base/activitymanager/src/android/server/am/ActivityManagerDisplayLockedKeyguardTests.java b/tests/framework/base/activitymanager/src/android/server/am/ActivityManagerDisplayLockedKeyguardTests.java
index a68dafd..7cf3c68 100644
--- a/tests/framework/base/activitymanager/src/android/server/am/ActivityManagerDisplayLockedKeyguardTests.java
+++ b/tests/framework/base/activitymanager/src/android/server/am/ActivityManagerDisplayLockedKeyguardTests.java
@@ -44,7 +44,7 @@
         super.setUp();
 
         assumeTrue(supportsMultiDisplay());
-        assumeTrue(isHandheld());
+        assumeTrue(supportsSecureLock());
     }
 
     /**
diff --git a/tests/framework/base/activitymanager/src/android/server/am/ActivityManagerSplitScreenTests.java b/tests/framework/base/activitymanager/src/android/server/am/ActivityManagerSplitScreenTests.java
index 8d8614c..c1c3cf0 100644
--- a/tests/framework/base/activitymanager/src/android/server/am/ActivityManagerSplitScreenTests.java
+++ b/tests/framework/base/activitymanager/src/android/server/am/ActivityManagerSplitScreenTests.java
@@ -277,17 +277,7 @@
 
         // Move to split-screen primary
         final int taskId = mAmWmState.getAmState().getTaskByActivity(LAUNCHING_ACTIVITY).mTaskId;
-        mAm.setTaskWindowingModeSplitScreenPrimary(taskId, SPLIT_SCREEN_CREATE_MODE_TOP_OR_LEFT,
-                true /* onTop */, false /* animate */, null /* initialBounds */,
-                true /* showRecents */);
-        mAmWmState.waitForRecentsActivityVisible();
-
-        // Launch another activity. This forces the any home activity back and allows the primary
-        // stack to gain focus during launch.
-        getLaunchActivityBuilder().setTargetActivity(ALT_LAUNCHING_ACTIVITY)
-                .setUseInstrumentation()
-                .setWaitForLaunched(true)
-                .execute();
+        moveTaskToPrimarySplitScreen(taskId, true /* launchSideActivityIfNeeded */);
 
         // Launch target to side
         final LaunchActivityBuilder targetActivityLauncher = getLaunchActivityBuilder()
diff --git a/tests/framework/base/activitymanager/src/android/server/am/KeyguardLockedTests.java b/tests/framework/base/activitymanager/src/android/server/am/KeyguardLockedTests.java
index eca8940..003f89b 100644
--- a/tests/framework/base/activitymanager/src/android/server/am/KeyguardLockedTests.java
+++ b/tests/framework/base/activitymanager/src/android/server/am/KeyguardLockedTests.java
@@ -27,6 +27,7 @@
 import static android.server.am.Components.PipActivity.EXTRA_ENTER_PIP;
 import static android.server.am.Components.PipActivity.EXTRA_SHOW_OVER_KEYGUARD;
 import static android.server.am.Components.SHOW_WHEN_LOCKED_ACTIVITY;
+import static android.server.am.Components.TURN_SCREEN_ON_ATTR_DISMISS_KEYGUARD_ACTIVITY;
 import static android.server.am.UiDeviceUtils.pressBackButton;
 
 import static org.junit.Assert.assertFalse;
@@ -52,7 +53,7 @@
     @Override
     public void setUp() throws Exception {
         super.setUp();
-        assumeTrue(isHandheld());
+        assumeTrue(supportsSecureLock());
     }
 
     @Test
@@ -160,6 +161,22 @@
     }
 
     @Test
+    public void testDismissKeyguardAttrActivity_method_turnScreenOn_withSecureKeyguard()
+            throws Exception {
+        try (final LockScreenSession lockScreenSession = new LockScreenSession()) {
+            lockScreenSession.setLockCredential().sleepDevice();
+
+            mAmWmState.computeState(true);
+            assertTrue(mAmWmState.getAmState().getKeyguardControllerState().keyguardShowing);
+            launchActivity(TURN_SCREEN_ON_ATTR_DISMISS_KEYGUARD_ACTIVITY);
+            mAmWmState.waitForKeyguardShowingAndNotOccluded();
+            mAmWmState.assertVisibility(TURN_SCREEN_ON_ATTR_DISMISS_KEYGUARD_ACTIVITY, false);
+            assertTrue(mAmWmState.getAmState().getKeyguardControllerState().keyguardShowing);
+            assertTrue(isDisplayOn());
+        }
+    }
+
+    @Test
     public void testEnterPipOverKeyguard() throws Exception {
         assumeTrue(supportsPip());
 
diff --git a/tests/framework/base/activitymanager/src/android/server/am/KeyguardTests.java b/tests/framework/base/activitymanager/src/android/server/am/KeyguardTests.java
index 2a07b27..e79c13b 100644
--- a/tests/framework/base/activitymanager/src/android/server/am/KeyguardTests.java
+++ b/tests/framework/base/activitymanager/src/android/server/am/KeyguardTests.java
@@ -74,7 +74,7 @@
     public void setUp() throws Exception {
         super.setUp();
 
-        assumeTrue(isHandheld());
+        assumeTrue(supportsInsecureLock());
         assertFalse(isUiModeLockedToVrHeadset());
     }
 
@@ -362,23 +362,6 @@
     }
 
     @Test
-    public void testDismissKeyguardAttrActivity_method_turnScreenOn_withSecureKeyguard()
-            throws Exception {
-        try (final LockScreenSession lockScreenSession = new LockScreenSession()) {
-            lockScreenSession.setLockCredential()
-                    .sleepDevice();
-
-            mAmWmState.computeState(true);
-            assertTrue(mAmWmState.getAmState().getKeyguardControllerState().keyguardShowing);
-            launchActivity(TURN_SCREEN_ON_ATTR_DISMISS_KEYGUARD_ACTIVITY);
-            mAmWmState.waitForKeyguardShowingAndNotOccluded();
-            mAmWmState.assertVisibility(TURN_SCREEN_ON_ATTR_DISMISS_KEYGUARD_ACTIVITY, false);
-            assertTrue(mAmWmState.getAmState().getKeyguardControllerState().keyguardShowing);
-            assertTrue(isDisplayOn());
-        }
-    }
-
-    @Test
     public void testScreenOffWhileOccludedStopsActivity() throws Exception {
         try (final LockScreenSession lockScreenSession = new LockScreenSession()) {
             final LogSeparator logSeparator = separateLogs();
diff --git a/tests/framework/base/activitymanager/src/android/server/am/KeyguardTransitionTests.java b/tests/framework/base/activitymanager/src/android/server/am/KeyguardTransitionTests.java
index c2156fe..105121b 100644
--- a/tests/framework/base/activitymanager/src/android/server/am/KeyguardTransitionTests.java
+++ b/tests/framework/base/activitymanager/src/android/server/am/KeyguardTransitionTests.java
@@ -46,7 +46,7 @@
     public void setUp() throws Exception {
         super.setUp();
 
-        assumeTrue(isHandheld());
+        assumeTrue(supportsInsecureLock());
         assumeFalse(isUiModeLockedToVrHeadset());
     }
 
diff --git a/tests/framework/base/activitymanager/src/android/server/am/lifecycle/ActivityLifecycleKeyguardTests.java b/tests/framework/base/activitymanager/src/android/server/am/lifecycle/ActivityLifecycleKeyguardTests.java
index 9555af7..12bfc64 100644
--- a/tests/framework/base/activitymanager/src/android/server/am/lifecycle/ActivityLifecycleKeyguardTests.java
+++ b/tests/framework/base/activitymanager/src/android/server/am/lifecycle/ActivityLifecycleKeyguardTests.java
@@ -23,8 +23,7 @@
     @Test
     public void testSingleLaunch() throws Exception {
         try (final LockScreenSession lockScreenSession = new LockScreenSession()) {
-            lockScreenSession.setLockCredential()
-                    .gotoKeyguard();
+            lockScreenSession.setLockCredential().gotoKeyguard();
 
             final Activity activity = mFirstActivityTestRule.launchActivity(new Intent());
             waitAndAssertActivityStates(state(activity, ON_STOP));
diff --git a/tests/framework/base/activitymanager/src/android/server/am/lifecycle/ActivityLifecycleTests.java b/tests/framework/base/activitymanager/src/android/server/am/lifecycle/ActivityLifecycleTests.java
index fa9894f..7c04612 100644
--- a/tests/framework/base/activitymanager/src/android/server/am/lifecycle/ActivityLifecycleTests.java
+++ b/tests/framework/base/activitymanager/src/android/server/am/lifecycle/ActivityLifecycleTests.java
@@ -23,6 +23,7 @@
 import static android.view.Surface.ROTATION_90;
 
 import static org.junit.Assert.fail;
+import static org.junit.Assume.assumeTrue;
 
 import android.app.Activity;
 import android.content.ComponentName;
@@ -171,8 +172,8 @@
             LifecycleVerifier.assertSequence(FirstActivity.class, getLifecycleLog(),
                     Arrays.asList(ON_DESTROY, PRE_ON_CREATE, ON_CREATE, ON_START, ON_RESUME,
                             ON_PAUSE), "becomingVisiblePaused");
-            // TODO(b/78021523): Local relaunch sequence should always be the same.
-            // It is possible to get another pause-resume now.
+            // TODO(b/77974794): New intent handling sequence should always be the same.
+            // It is possible to get an extra pause and resume now.
             final List<LifecycleLog.ActivityCallback> expectedSequence =
                     Arrays.asList(ON_DESTROY, PRE_ON_CREATE, ON_CREATE, ON_START, ON_RESUME);
             final List<LifecycleLog.ActivityCallback> extraCycleSequence =
@@ -241,6 +242,9 @@
 
     @Test
     public void testPausedWhenRecreatedFromInNonFocusedStack() throws Exception {
+        assumeTrue("Skipping test: no split multi-window support",
+                supportsSplitScreenMultiWindow());
+
         // Launch first activity
         final Activity firstActivity =
                 mFirstActivityTestRule.launchActivity(new Intent());
@@ -275,6 +279,9 @@
 
     @Test
     public void testPausedWhenRestartedFromInNonFocusedStack() throws Exception {
+        assumeTrue("Skipping test: no split multi-window support",
+                supportsSplitScreenMultiWindow());
+
         // Launch first activity
         final Activity firstActivity =
                 mFirstActivityTestRule.launchActivity(new Intent());
@@ -283,7 +290,8 @@
         waitAndAssertActivityStates(state(firstActivity, ON_RESUME));
 
         // Enter split screen
-        moveTaskToPrimarySplitScreen(firstActivity.getTaskId());
+        moveTaskToPrimarySplitScreen(firstActivity.getTaskId(),
+                true /* launchSideActivityIfNeeded */);
 
         // Launch second activity to pause first
         final Activity secondActivity =
@@ -320,8 +328,13 @@
                         ON_PAUSE, ON_ACTIVITY_RESULT, ON_RESUME);
         waitForActivityTransitions(LaunchForResultActivity.class, expectedSequence);
 
-        LifecycleVerifier.assertSequence(LaunchForResultActivity.class,
-                getLifecycleLog(), expectedSequence, "activityResult");
+        // TODO(b/79218023): First activity might also be stopped before getting result.
+        final List<LifecycleLog.ActivityCallback> sequenceWithStop =
+                Arrays.asList(PRE_ON_CREATE, ON_CREATE, ON_START, ON_POST_CREATE, ON_RESUME,
+                        ON_PAUSE, ON_STOP, ON_ACTIVITY_RESULT, ON_RESTART, ON_START, ON_RESUME);
+        LifecycleVerifier.assertSequenceMatchesOneOf(LaunchForResultActivity.class,
+                getLifecycleLog(), Arrays.asList(expectedSequence, sequenceWithStop),
+                "activityResult");
     }
 
     @Test
@@ -382,11 +395,8 @@
         // Wait for activity to resume
         waitAndAssertActivityStates(state(trackingActivity, ON_RESUME));
 
-        // Enter split screen
-        moveTaskToPrimarySplitScreen(trackingActivity.getTaskId());
-
-        // Start an activity in separate task (will be placed in secondary stack)
-        getLaunchActivityBuilder().execute();
+        // Launch translucent activity, which will make the first one paused.
+        mTranslucentActivityTestRule.launchActivity(new Intent());
 
         // Wait for first activity to become paused
         waitAndAssertActivityStates(state(trackingActivity, ON_PAUSE));
@@ -486,18 +496,11 @@
 
         // Wait for activity to relaunch and resume
         final List<LifecycleLog.ActivityCallback> expectedRelaunchSequence =
-                Arrays.asList(ON_NEW_INTENT, ON_DESTROY, PRE_ON_CREATE, ON_CREATE, ON_START,
-                        ON_POST_CREATE, ON_RESUME);
+                Arrays.asList(ON_NEW_INTENT, ON_RESTART, ON_START, ON_RESUME, ON_PAUSE, ON_STOP,
+                        ON_DESTROY, PRE_ON_CREATE, ON_CREATE, ON_START, ON_POST_CREATE, ON_RESUME);
         waitForActivityTransitions(SingleTopActivity.class, expectedRelaunchSequence);
-
-        // TODO(b/78021523): Local relaunch sequence should always be the same.
-        // It is possible to get another restart now.
-        final List<LifecycleLog.ActivityCallback> extraCycleRelaunchSequence =
-                Arrays.asList(ON_NEW_INTENT, ON_DESTROY, PRE_ON_CREATE, ON_CREATE, ON_START,
-                        ON_POST_CREATE, ON_RESUME, ON_PAUSE, ON_STOP, ON_RESTART, ON_START,
-                        ON_RESUME);
-        LifecycleVerifier.assertSequenceMatchesOneOf(SingleTopActivity.class, getLifecycleLog(),
-                Arrays.asList(expectedRelaunchSequence, extraCycleRelaunchSequence), "recreate");
+        LifecycleVerifier.assertSequence(SingleTopActivity.class, getLifecycleLog(),
+                expectedRelaunchSequence, "recreate");
     }
 
     @Test
@@ -557,9 +560,13 @@
         waitAndAssertActivityStates(state(singleTopActivity, ON_RESUME));
 
         // Verify that the first activity was restarted, new intent was delivered and resumed again
-        LifecycleVerifier.assertSequence(SingleTopActivity.class, getLifecycleLog(),
-                Arrays.asList(ON_NEW_INTENT, ON_RESTART, ON_START, ON_RESUME), "newIntent");
-        // TODO(b/65236456): This should actually be ON_RESTART, ON_START, ON_NEW_INTENT, ON_RESUME
+        final List<LifecycleLog.ActivityCallback> expectedSequence =
+                Arrays.asList(ON_NEW_INTENT, ON_RESTART, ON_START, ON_RESUME);
+        final List<LifecycleLog.ActivityCallback> otherSequence =
+                Arrays.asList(ON_RESTART, ON_START, ON_NEW_INTENT, ON_RESUME);
+        // TODO(b/65236456): This should always be ON_RESTART, ON_START, ON_NEW_INTENT, ON_RESUME
+        LifecycleVerifier.assertSequenceMatchesOneOf(SingleTopActivity.class, getLifecycleLog(),
+                Arrays.asList(expectedSequence, otherSequence), "newIntent");
     }
 
     @Test
@@ -573,11 +580,8 @@
         LifecycleVerifier.assertLaunchSequence(SingleTopActivity.class, getLifecycleLog(),
                 true /* includeCallbacks */);
 
-        // Enter split screen
-        moveTaskToPrimarySplitScreen(singleTopActivity.getTaskId());
-
-        // Start an activity in separate task (will be placed in secondary stack)
-        getLaunchActivityBuilder().execute();
+        // Launch translucent activity, which will make the first one paused.
+        mTranslucentActivityTestRule.launchActivity(new Intent());
 
         // Wait for the activity to pause
         waitAndAssertActivityStates(state(singleTopActivity, ON_PAUSE));
@@ -586,7 +590,7 @@
         getLifecycleLog().clear();
         final Intent intent = new Intent(InstrumentationRegistry.getContext(),
                 SingleTopActivity.class);
-        intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+        intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TOP);
         InstrumentationRegistry.getTargetContext().startActivity(intent);
 
         // Wait for the activity to resume again
@@ -605,6 +609,9 @@
 
     @Test
     public void testLifecycleOnMoveToFromSplitScreenRelaunch() throws Exception {
+        assumeTrue("Skipping test: no split multi-window support",
+                supportsSplitScreenMultiWindow());
+
         // Launch a singleTop activity
         final Activity testActivity =
                 mCallbackTrackingActivityTestRule.launchActivity(new Intent());
@@ -647,6 +654,9 @@
 
     @Test
     public void testLifecycleOnMoveToFromSplitScreenNoRelaunch() throws Exception {
+        assumeTrue("Skipping test: no split multi-window support",
+                supportsSplitScreenMultiWindow());
+
         // Launch a singleTop activity
         final Activity testActivity =
                 mConfigChangeHandlingActivityTestRule.launchActivity(new Intent());
diff --git a/tests/framework/base/activitymanager/util/src/android/server/am/ActivityManagerTestBase.java b/tests/framework/base/activitymanager/util/src/android/server/am/ActivityManagerTestBase.java
index 5a6b0be..e187eee 100644
--- a/tests/framework/base/activitymanager/util/src/android/server/am/ActivityManagerTestBase.java
+++ b/tests/framework/base/activitymanager/util/src/android/server/am/ActivityManagerTestBase.java
@@ -45,9 +45,9 @@
 import static android.server.am.ActivityLauncher.KEY_USE_APPLICATION_CONTEXT;
 import static android.server.am.ActivityLauncher.KEY_USE_INSTRUMENTATION;
 import static android.server.am.ActivityLauncher.launchActivityFromExtras;
+import static android.server.am.ActivityManagerState.STATE_RESUMED;
 import static android.server.am.ComponentNameUtils.getActivityName;
 import static android.server.am.ComponentNameUtils.getLogTag;
-import static android.server.am.ComponentNameUtils.getWindowName;
 import static android.server.am.Components.LAUNCHING_ACTIVITY;
 import static android.server.am.Components.TEST_ACTIVITY;
 import static android.server.am.StateLogger.log;
@@ -69,22 +69,26 @@
 
 import static java.lang.Integer.toHexString;
 
+import android.accessibilityservice.AccessibilityService;
+import android.app.Activity;
 import android.app.ActivityManager;
 import android.content.ComponentName;
 import android.content.Context;
 import android.graphics.Bitmap;
+import android.content.Intent;
 import android.os.Bundle;
 import android.os.SystemClock;
 import android.provider.Settings;
 import android.server.am.settings.SettingsSession;
-import androidx.annotation.NonNull;
-import androidx.annotation.Nullable;
 import android.support.test.InstrumentationRegistry;
 
+import android.support.test.rule.ActivityTestRule;
+
 import com.android.compatibility.common.util.SystemUtil;
 
 import org.junit.After;
 import org.junit.Before;
+import org.junit.Rule;
 import org.junit.rules.TestRule;
 import org.junit.runner.Description;
 import org.junit.runners.model.Statement;
@@ -102,6 +106,9 @@
 import java.util.stream.Collectors;
 import java.util.stream.IntStream;
 
+import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
+
 public abstract class ActivityManagerTestBase {
     private static final boolean PRETEND_DEVICE_SUPPORTS_PIP = false;
     private static final boolean PRETEND_DEVICE_SUPPORTS_FREEFORM = false;
@@ -147,6 +154,11 @@
     protected Context mContext;
     protected ActivityManager mAm;
 
+    @Rule
+    public final ActivityTestRule<SideActivity> mSideActivityRule =
+            new ActivityTestRule<>(SideActivity.class, true /* initialTouchMode */,
+                    false /* launchActivity */);
+
     /**
      * @return the am command to start the given activity with the following extra key/value pairs.
      *         {@param keyValuePairs} must be a list of arguments defining each key/value extra.
@@ -366,10 +378,26 @@
     }
 
     public void moveTaskToPrimarySplitScreen(int taskId) {
+        moveTaskToPrimarySplitScreen(taskId, false /* launchSideActivityIfNeeded */);
+    }
+
+    /**
+     * Moves the device into split-screen with the specified task into the primary stack.
+     * @param taskId                        The id of the task to move into the primary stack.
+     * @param launchSideActivityIfNeeded    Whether a placeholder activity should be launched if no
+     *                                      recents activity is available.
+     */
+    public void moveTaskToPrimarySplitScreen(int taskId, boolean launchSideActivityIfNeeded) {
         mAm.setTaskWindowingModeSplitScreenPrimary(taskId, SPLIT_SCREEN_CREATE_MODE_TOP_OR_LEFT,
                 true /* onTop */, false /* animate */, null /* initialBounds */,
                 true /* showRecents */);
         mAmWmState.waitForRecentsActivityVisible();
+
+        if (mAmWmState.getAmState().isHomeRecentsComponent() && launchSideActivityIfNeeded) {
+            // Launch Placeholder Recents
+            final Activity recentsActivity = mSideActivityRule.launchActivity(new Intent());
+            mAmWmState.waitForActivityState(recentsActivity.getComponentName(), STATE_RESUMED);
+        }
     }
 
     /**
@@ -469,7 +497,14 @@
                 || PRETEND_DEVICE_SUPPORTS_FREEFORM;
     }
 
-    protected boolean isHandheld() {
+    /** Whether or not the device pin/pattern/password lock. */
+    protected boolean supportsSecureLock() {
+        return !hasDeviceFeature(FEATURE_LEANBACK)
+                && !hasDeviceFeature(FEATURE_EMBEDDED);
+    }
+
+    /** Whether or not the device supports "swipe" lock. */
+    protected boolean supportsInsecureLock() {
         return !hasDeviceFeature(FEATURE_LEANBACK)
                 && !hasDeviceFeature(FEATURE_WATCH)
                 && !hasDeviceFeature(FEATURE_EMBEDDED);
@@ -628,6 +663,11 @@
 
         LockScreenSession sleepDevice() {
             pressSleepButton();
+            // Not all device variants lock when we go to sleep, so we need to explicitly lock the
+            // device. Note that pressSleepButton() above is redundant because the action also
+            // puts the device to sleep, but kept around for clarity.
+            InstrumentationRegistry.getInstrumentation().getUiAutomation().performGlobalAction(
+                    AccessibilityService.GLOBAL_ACTION_LOCK_SCREEN);
             for (int retry = 1; isDisplayOn() && retry <= 5; retry++) {
                 logAlways("***Waiting for display to turn off... retry=" + retry);
                 SystemClock.sleep(TimeUnit.SECONDS.toMillis(1));
@@ -647,7 +687,7 @@
 
         public LockScreenSession gotoKeyguard() {
             if (DEBUG && isLockDisabled()) {
-                logE("LockScreenSession.gotoKeygurad() is called without lock enabled.");
+                logE("LockScreenSession.gotoKeyguard() is called without lock enabled.");
             }
             sleepDevice();
             wakeUpDevice();
@@ -1420,4 +1460,8 @@
             executeShellCommand(commandBuilder.toString());
         }
     }
+
+    // Activity used in place of recents when home is the recents component.
+    public static class SideActivity extends Activity {
+    }
 }
diff --git a/tests/framework/base/windowmanager/src/android/server/wm/CrossAppDragAndDropTests.java b/tests/framework/base/windowmanager/src/android/server/wm/CrossAppDragAndDropTests.java
index 2ab39e7..0cc2ac8 100644
--- a/tests/framework/base/windowmanager/src/android/server/wm/CrossAppDragAndDropTests.java
+++ b/tests/framework/base/windowmanager/src/android/server/wm/CrossAppDragAndDropTests.java
@@ -148,7 +148,9 @@
 
     @After
     public void tearDown() throws Exception {
-        assumeTrue(supportsDragAndDrop());
+        if (!supportsDragAndDrop()) {
+          return;
+        }
 
         executeShellCommand(AM_FORCE_STOP + mSourcePackageName);
         executeShellCommand(AM_FORCE_STOP + mTargetPackageName);
diff --git a/tests/pdf/AndroidManifest.xml b/tests/pdf/AndroidManifest.xml
index 495b5da..deb2c88 100644
--- a/tests/pdf/AndroidManifest.xml
+++ b/tests/pdf/AndroidManifest.xml
@@ -16,7 +16,8 @@
  -->
 
 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
-    package="android.graphics.pdf.cts">
+    package="android.graphics.pdf.cts"
+    android:targetSandboxVersion="2">
 
     <uses-permission android:name="android.permission.DISABLE_KEYGUARD" />
     <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
diff --git a/tests/sample/AndroidManifest.xml b/tests/sample/AndroidManifest.xml
index 108321f..fbc7a05 100755
--- a/tests/sample/AndroidManifest.xml
+++ b/tests/sample/AndroidManifest.xml
@@ -16,7 +16,8 @@
  -->
 
 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
-    package="android.sample.cts">
+    package="android.sample.cts"
+    android:targetSandboxVersion="2">
 
     <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
     <application>
diff --git a/tests/signature/api-check/Android.mk b/tests/signature/api-check/Android.mk
index 94b59ba..272bf1b 100644
--- a/tests/signature/api-check/Android.mk
+++ b/tests/signature/api-check/Android.mk
@@ -44,4 +44,26 @@
 LOCAL_NDK_STL_VARIANT := c++_static
 include $(BUILD_SHARED_LIBRARY)
 
+# hidden API lists
+# ===================================
+
+include $(CLEAR_VARS)
+LOCAL_MODULE := cts-hidden-api-blacklist
+LOCAL_MODULE_STEM := blacklist.api
+LOCAL_MODULE_CLASS := ETC
+LOCAL_MODULE_PATH = $(TARGET_OUT_DATA_ETC)
+LOCAL_COMPATIBILITY_SUITE := cts vts general-tests
+include $(BUILD_SYSTEM)/base_rules.mk
+$(eval $(call copy-one-file,$(INTERNAL_PLATFORM_HIDDENAPI_BLACKLIST),$(LOCAL_BUILT_MODULE)))
+
+include $(CLEAR_VARS)
+LOCAL_MODULE := cts-hidden-api-dark-greylist
+LOCAL_MODULE_STEM := dark_greylist.api
+LOCAL_MODULE_CLASS := ETC
+LOCAL_MODULE_PATH = $(TARGET_OUT_DATA_ETC)
+LOCAL_COMPATIBILITY_SUITE := cts vts general-tests
+include $(BUILD_SYSTEM)/base_rules.mk
+$(eval $(call copy-one-file,$(INTERNAL_PLATFORM_HIDDENAPI_DARK_GREYLIST),$(LOCAL_BUILT_MODULE)))
+
+
 include $(call all-makefiles-under,$(LOCAL_PATH))
diff --git a/tests/signature/api-check/hidden-api/Android.mk b/tests/signature/api-check/hidden-api-blacklist-27-api/Android.mk
similarity index 67%
rename from tests/signature/api-check/hidden-api/Android.mk
rename to tests/signature/api-check/hidden-api-blacklist-27-api/Android.mk
index f039032..58bf17d 100644
--- a/tests/signature/api-check/hidden-api/Android.mk
+++ b/tests/signature/api-check/hidden-api-blacklist-27-api/Android.mk
@@ -15,16 +15,7 @@
 LOCAL_PATH := $(call my-dir)
 
 include $(CLEAR_VARS)
-LOCAL_MODULE := cts-hidden-api-blacklist
-LOCAL_MODULE_STEM := blacklist.api
-LOCAL_MODULE_CLASS := ETC
-LOCAL_MODULE_PATH = $(TARGET_OUT_DATA_ETC)
-LOCAL_COMPATIBILITY_SUITE := cts vts general-tests
-include $(BUILD_SYSTEM)/base_rules.mk
-$(eval $(call copy-one-file,$(INTERNAL_PLATFORM_HIDDENAPI_BLACKLIST),$(LOCAL_BUILT_MODULE)))
-
-include $(CLEAR_VARS)
-LOCAL_PACKAGE_NAME := CtsHiddenApiDiscoveryTestCases
+LOCAL_PACKAGE_NAME := CtsHiddenApiBlacklistApi27TestCases
 LOCAL_MODULE_PATH := $(TARGET_OUT_DATA_APPS)
 LOCAL_SIGNATURE_API_FILES := blacklist.api
 LOCAL_JNI_SHARED_LIBRARIES := libcts_dexchecker
diff --git a/tests/signature/api-check/hidden-api/AndroidManifest.xml b/tests/signature/api-check/hidden-api-blacklist-27-api/AndroidManifest.xml
similarity index 71%
copy from tests/signature/api-check/hidden-api/AndroidManifest.xml
copy to tests/signature/api-check/hidden-api-blacklist-27-api/AndroidManifest.xml
index a68e11a..838112f 100644
--- a/tests/signature/api-check/hidden-api/AndroidManifest.xml
+++ b/tests/signature/api-check/hidden-api-blacklist-27-api/AndroidManifest.xml
@@ -16,13 +16,15 @@
  -->
 
 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
-          package="android.signature.cts.api.hidden">
+          package="android.signature.cts.api.hiddenapi_blacklist_api_27">
     <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
     <uses-permission android:name="android.permission.READ_PHONE_STATE"/>
+    <uses-sdk android:targetSdkVersion="27" />
 
     <application/>
 
-    <instrumentation android:name="repackaged.android.test.InstrumentationTestRunner"
-                     android:targetPackage="android.signature.cts.api.hidden"
-                     android:label="Hidden API Signature Test"/>
+    <instrumentation
+        android:name="repackaged.android.test.InstrumentationTestRunner"
+        android:targetPackage="android.signature.cts.api.hiddenapi_blacklist_api_27"
+        android:label="Hidden API Blacklist Test for SDK level 27"/>
 </manifest>
diff --git a/tests/signature/api-check/hidden-api/AndroidTest.xml b/tests/signature/api-check/hidden-api-blacklist-27-api/AndroidTest.xml
similarity index 94%
rename from tests/signature/api-check/hidden-api/AndroidTest.xml
rename to tests/signature/api-check/hidden-api-blacklist-27-api/AndroidTest.xml
index df6d7ce..bfa5fc6 100644
--- a/tests/signature/api-check/hidden-api/AndroidTest.xml
+++ b/tests/signature/api-check/hidden-api-blacklist-27-api/AndroidTest.xml
@@ -25,10 +25,10 @@
     </target_preparer>
     <target_preparer class="com.android.tradefed.targetprep.suite.SuiteApkInstaller">
         <option name="cleanup-apks" value="true" />
-        <option name="test-file-name" value="CtsHiddenApiDiscoveryTestCases.apk" />
+        <option name="test-file-name" value="CtsHiddenApiBlacklistApi27TestCases.apk" />
     </target_preparer>
     <test class="com.android.tradefed.testtype.AndroidJUnitTest" >
-        <option name="package" value="android.signature.cts.api.hidden" />
+        <option name="package" value="android.signature.cts.api.hiddenapi_blacklist_api_27" />
         <option name="runner" value="repackaged.android.test.InstrumentationTestRunner" />
         <option name="class" value="android.signature.cts.api.HiddenApiTest" />
         <option name="instrumentation-arg" key="hidden-api-files" value="blacklist.api" />
diff --git a/tests/signature/api-check/hidden-api/Android.mk b/tests/signature/api-check/hidden-api-blacklist-current-api/Android.mk
similarity index 64%
copy from tests/signature/api-check/hidden-api/Android.mk
copy to tests/signature/api-check/hidden-api-blacklist-current-api/Android.mk
index f039032..e518f14 100644
--- a/tests/signature/api-check/hidden-api/Android.mk
+++ b/tests/signature/api-check/hidden-api-blacklist-current-api/Android.mk
@@ -15,17 +15,8 @@
 LOCAL_PATH := $(call my-dir)
 
 include $(CLEAR_VARS)
-LOCAL_MODULE := cts-hidden-api-blacklist
-LOCAL_MODULE_STEM := blacklist.api
-LOCAL_MODULE_CLASS := ETC
-LOCAL_MODULE_PATH = $(TARGET_OUT_DATA_ETC)
-LOCAL_COMPATIBILITY_SUITE := cts vts general-tests
-include $(BUILD_SYSTEM)/base_rules.mk
-$(eval $(call copy-one-file,$(INTERNAL_PLATFORM_HIDDENAPI_BLACKLIST),$(LOCAL_BUILT_MODULE)))
-
-include $(CLEAR_VARS)
-LOCAL_PACKAGE_NAME := CtsHiddenApiDiscoveryTestCases
+LOCAL_PACKAGE_NAME := CtsHiddenApiBlacklistCurrentApiTestCases
 LOCAL_MODULE_PATH := $(TARGET_OUT_DATA_APPS)
-LOCAL_SIGNATURE_API_FILES := blacklist.api
+LOCAL_SIGNATURE_API_FILES := blacklist.api dark_greylist.api
 LOCAL_JNI_SHARED_LIBRARIES := libcts_dexchecker
 include $(LOCAL_PATH)/../build_signature_apk.mk
diff --git a/tests/signature/api-check/hidden-api/AndroidManifest.xml b/tests/signature/api-check/hidden-api-blacklist-current-api/AndroidManifest.xml
similarity index 73%
rename from tests/signature/api-check/hidden-api/AndroidManifest.xml
rename to tests/signature/api-check/hidden-api-blacklist-current-api/AndroidManifest.xml
index a68e11a..12d0393 100644
--- a/tests/signature/api-check/hidden-api/AndroidManifest.xml
+++ b/tests/signature/api-check/hidden-api-blacklist-current-api/AndroidManifest.xml
@@ -16,13 +16,14 @@
  -->
 
 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
-          package="android.signature.cts.api.hidden">
+          package="android.signature.cts.api.hiddenapi_blacklist_current">
     <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
     <uses-permission android:name="android.permission.READ_PHONE_STATE"/>
 
     <application/>
 
-    <instrumentation android:name="repackaged.android.test.InstrumentationTestRunner"
-                     android:targetPackage="android.signature.cts.api.hidden"
-                     android:label="Hidden API Signature Test"/>
+    <instrumentation
+        android:name="repackaged.android.test.InstrumentationTestRunner"
+        android:targetPackage="android.signature.cts.api.hiddenapi_blacklist_current"
+        android:label="Hidden API Blacklist Test for current SDK"/>
 </manifest>
diff --git a/tests/signature/api-check/hidden-api/AndroidTest.xml b/tests/signature/api-check/hidden-api-blacklist-current-api/AndroidTest.xml
similarity index 87%
copy from tests/signature/api-check/hidden-api/AndroidTest.xml
copy to tests/signature/api-check/hidden-api-blacklist-current-api/AndroidTest.xml
index df6d7ce..dfcd0d9 100644
--- a/tests/signature/api-check/hidden-api/AndroidTest.xml
+++ b/tests/signature/api-check/hidden-api-blacklist-current-api/AndroidTest.xml
@@ -22,16 +22,17 @@
     </target_preparer>
     <target_preparer class="com.android.compatibility.common.tradefed.targetprep.FilePusher">
         <option name="push" value="blacklist.api->/data/local/tmp/signature-test/blacklist.api" />
+        <option name="push" value="dark_greylist.api->/data/local/tmp/signature-test/dark_greylist.api" />
     </target_preparer>
     <target_preparer class="com.android.tradefed.targetprep.suite.SuiteApkInstaller">
         <option name="cleanup-apks" value="true" />
-        <option name="test-file-name" value="CtsHiddenApiDiscoveryTestCases.apk" />
+        <option name="test-file-name" value="CtsHiddenApiBlacklistCurrentApiTestCases.apk" />
     </target_preparer>
     <test class="com.android.tradefed.testtype.AndroidJUnitTest" >
-        <option name="package" value="android.signature.cts.api.hidden" />
+        <option name="package" value="android.signature.cts.api.hiddenapi_blacklist_current" />
         <option name="runner" value="repackaged.android.test.InstrumentationTestRunner" />
         <option name="class" value="android.signature.cts.api.HiddenApiTest" />
-        <option name="instrumentation-arg" key="hidden-api-files" value="blacklist.api" />
+        <option name="instrumentation-arg" key="hidden-api-files" value="blacklist.api,dark_greylist.api" />
         <option name="runtime-hint" value="30s" />
     </test>
 </configuration>
diff --git a/tests/signature/api-check/hidden-api-whitelist/AndroidTest.xml b/tests/signature/api-check/hidden-api-whitelist/AndroidTest.xml
index 5bfe03a..478c7c2 100644
--- a/tests/signature/api-check/hidden-api-whitelist/AndroidTest.xml
+++ b/tests/signature/api-check/hidden-api-whitelist/AndroidTest.xml
@@ -15,7 +15,7 @@
 -->
 <configuration description="Config for CTS Hidden API Signature test cases">
     <option name="test-suite-tag" value="cts" />
-    <option name="config-descriptor:metadata" key="component" value="systems" />W
+    <option name="config-descriptor:metadata" key="component" value="systems" />
     <target_preparer class="com.android.tradefed.targetprep.RunCommandTargetPreparer">
         <!-- Whitelist all APIs before running the test, then reset this afterwards. The test
              is intended to verify the behaviour when all APIs are whitelisted. -->
diff --git a/tests/signature/intent-check/DynamicConfig.xml b/tests/signature/intent-check/DynamicConfig.xml
index 75d292b..6c7aace 100644
--- a/tests/signature/intent-check/DynamicConfig.xml
+++ b/tests/signature/intent-check/DynamicConfig.xml
@@ -20,6 +20,9 @@
     Bug: 38182465 android.intent.action.ACTION_DEFAULT_SMS_SUBSCRIPTION_CHANGED
     Bug: 70315695 android.intent.action.HDMI_PLUGGED
     Bug: 78574873 android.intent.action.QUICKSTEP_SERVICE
+    Bug: 78574873 android.intent.action.INSTALL_EPHEMERAL_PACKAGE
+    Bug: 78574873 android.intent.action.RESOLVE_EPHEMERAL_PACKAGE
+    Bug: 78574873 android.intent.action.EPHEMERAL_RESOLVER_SETTINGS
 -->
 <dynamicConfig>
     <entry key ="intent_whitelist">
@@ -28,5 +31,8 @@
       <value>android.intent.action.ACTION_DEFAULT_SMS_SUBSCRIPTION_CHANGED</value>
       <value>android.intent.action.HDMI_PLUGGED</value>
       <value>android.intent.action.QUICKSTEP_SERVICE</value>
+      <value>android.intent.action.INSTALL_EPHEMERAL_PACKAGE</value>
+      <value>android.intent.action.RESOLVE_EPHEMERAL_PACKAGE</value>
+      <value>android.intent.action.EPHEMERAL_RESOLVER_SETTINGS</value>
     </entry>
 </dynamicConfig>
diff --git a/tests/signature/runSignatureTests.sh b/tests/signature/runSignatureTests.sh
index 087d356..e5664fb 100755
--- a/tests/signature/runSignatureTests.sh
+++ b/tests/signature/runSignatureTests.sh
@@ -25,7 +25,8 @@
 
 CtsSystemApiAnnotationTestCases
 
-CtsHiddenApiDiscoveryTestCases
+CtsHiddenApiBlacklistCurrentApiTestCases
+CtsHiddenApiBlacklistApi27TestCases
 CtsHiddenApiKillswitchTestCases
 CtsHiddenApiWhitelistTestCases
 "
diff --git a/tests/signature/src/android/signature/cts/DexMemberChecker.java b/tests/signature/src/android/signature/cts/DexMemberChecker.java
index acb59f8..b72cc35 100644
--- a/tests/signature/src/android/signature/cts/DexMemberChecker.java
+++ b/tests/signature/src/android/signature/cts/DexMemberChecker.java
@@ -17,6 +17,7 @@
 package android.signature.cts;
 
 import java.lang.reflect.Constructor;
+import java.lang.reflect.Executable;
 import java.lang.reflect.Field;
 import java.lang.reflect.Method;
 import java.util.List;
@@ -97,8 +98,8 @@
     private static boolean hasMatchingField_JNI(Class<?> klass, DexField dexField) {
         Field ifield = getField_JNI(klass, dexField.getName(), dexField.getDexType());
         Field sfield = getStaticField_JNI(klass, dexField.getName(), dexField.getDexType());
-        return (ifield != null && ifield.getClass() == klass) ||
-               (sfield != null && sfield.getClass() == klass);
+        return (ifield != null && ifield.getDeclaringClass() == klass) ||
+               (sfield != null && sfield.getDeclaringClass() == klass);
     }
 
     private static boolean hasMatchingMethod_Reflection(Class<?> klass, DexMethod dexMethod) {
@@ -124,17 +125,17 @@
     }
 
     private static boolean hasMatchingMethod_JNI(Class<?> klass, DexMethod dexMethod) {
-        Method imethod = getMethod_JNI(klass, dexMethod.getName(), dexMethod.getDexSignature());
-        Method smethod = dexMethod.isConstructor() ? null :
+        Executable imethod = getMethod_JNI(klass, dexMethod.getName(), dexMethod.getDexSignature());
+        Executable smethod = dexMethod.isConstructor() ? null :
              getStaticMethod_JNI(klass, dexMethod.getName(), dexMethod.getDexSignature());
-        return (imethod != null && imethod.getClass() == klass) ||
-               (smethod != null && smethod.getClass() == klass);
+        return (imethod != null && imethod.getDeclaringClass() == klass) ||
+               (smethod != null && smethod.getDeclaringClass() == klass);
     }
 
     private static native Field getField_JNI(Class<?> klass, String name, String type);
     private static native Field getStaticField_JNI(Class<?> klass, String name, String type);
-    private static native Method getMethod_JNI(Class<?> klass, String name, String signature);
-    private static native Method getStaticMethod_JNI(Class<?> klass, String name,
+    private static native Executable getMethod_JNI(Class<?> klass, String name, String signature);
+    private static native Executable getStaticMethod_JNI(Class<?> klass, String name,
             String signature);
 
 }
diff --git a/tests/tests/animation/AndroidManifest.xml b/tests/tests/animation/AndroidManifest.xml
index 8c599b7..776ce13 100644
--- a/tests/tests/animation/AndroidManifest.xml
+++ b/tests/tests/animation/AndroidManifest.xml
@@ -15,7 +15,8 @@
 -->
 
 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
-    package="android.animation.cts">
+    package="android.animation.cts"
+    android:targetSandboxVersion="2">
     <uses-permission android:name="android.permission.DISABLE_KEYGUARD" />
     <application>
         <activity android:name="android.animation.cts.AnimationActivity"
diff --git a/tests/tests/app.usage/src/android/app/usage/cts/UsageStatsTest.java b/tests/tests/app.usage/src/android/app/usage/cts/UsageStatsTest.java
index ce8f553..7d72317 100644
--- a/tests/tests/app.usage/src/android/app/usage/cts/UsageStatsTest.java
+++ b/tests/tests/app.usage/src/android/app/usage/cts/UsageStatsTest.java
@@ -36,6 +36,7 @@
 import android.app.usage.UsageStatsManager;
 import android.content.Context;
 import android.content.Intent;
+import android.content.pm.PackageManager;
 import android.os.Parcel;
 import android.os.SystemClock;
 import android.provider.Settings;
@@ -447,6 +448,10 @@
     public void testNotificationSeen() throws Exception {
         final long startTime = System.currentTimeMillis();
         Context context = InstrumentationRegistry.getContext();
+        if (context.getPackageManager().hasSystemFeature(PackageManager.FEATURE_WATCH)) {
+            // Skip the test for wearable device.
+            return;
+        }
         NotificationManager mNotificationManager =
             (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
         int importance = NotificationManager.IMPORTANCE_DEFAULT;
diff --git a/tests/tests/background/src/android/app/cts/backgroundrestrictions/BroadcastsTest.java b/tests/tests/background/src/android/app/cts/backgroundrestrictions/BroadcastsTest.java
index 9d41ad8..3a8b43f 100644
--- a/tests/tests/background/src/android/app/cts/backgroundrestrictions/BroadcastsTest.java
+++ b/tests/tests/background/src/android/app/cts/backgroundrestrictions/BroadcastsTest.java
@@ -28,6 +28,7 @@
 import android.util.Log;
 
 import com.android.compatibility.common.util.SystemUtil;
+import com.android.compatibility.common.util.CddTest;
 
 import org.junit.Test;
 import org.junit.runner.RunWith;
@@ -54,6 +55,7 @@
      * receiver.
      */
     @Test
+    @CddTest(requirement="3.5/C-0-6")
     public void testNonSupportedBroadcastsNotDelivered_runtimeReceiver() throws Exception {
 
         // Need a reference here to initialize it in a lambda.
@@ -80,6 +82,7 @@
      * receiver, even if an intent is targeted to the component.
      */
     @Test
+    @CddTest(requirement="3.5/C-0-6")
     public void testNonSupportedBroadcastsNotDelivered_manifestReceiver() throws Exception {
         // Need a reference here to initialize it in a lambda.
         final AtomicReference<BroadcastReceiver> receiverRef = new AtomicReference<>();
diff --git a/tests/tests/bluetooth/src/android/bluetooth/cts/BluetoothLeScanTest.java b/tests/tests/bluetooth/src/android/bluetooth/cts/BluetoothLeScanTest.java
index b8a4ce8..cb59a0a3 100644
--- a/tests/tests/bluetooth/src/android/bluetooth/cts/BluetoothLeScanTest.java
+++ b/tests/tests/bluetooth/src/android/bluetooth/cts/BluetoothLeScanTest.java
@@ -96,6 +96,11 @@
 
     @Override
     public void tearDown() {
+        if (!isBleSupported()) {
+          // mBluetoothAdapter == null.
+          return;
+        }
+
         if (!mLocationOn) {
             TestUtils.disableLocation(getContext());
         }
diff --git a/tests/tests/colormode/AndroidManifest.xml b/tests/tests/colormode/AndroidManifest.xml
index be2c457..4c65c59 100644
--- a/tests/tests/colormode/AndroidManifest.xml
+++ b/tests/tests/colormode/AndroidManifest.xml
@@ -15,7 +15,8 @@
  -->
 
 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
-        package="android.colormode.cts">
+        package="android.colormode.cts"
+        android:targetSandboxVersion="2">
 
     <uses-permission android:name="android.permission.DISABLE_KEYGUARD" />
 
diff --git a/tests/tests/content/src/android/content/cts/AvailableIntentsTest.java b/tests/tests/content/src/android/content/cts/AvailableIntentsTest.java
index 14156cf..4723524 100644
--- a/tests/tests/content/src/android/content/cts/AvailableIntentsTest.java
+++ b/tests/tests/content/src/android/content/cts/AvailableIntentsTest.java
@@ -333,32 +333,6 @@
         assertCanBeHandled(new Intent(StorageManager.ACTION_MANAGE_STORAGE));
     }
 
-    public void testVoiceCommand() {
-        if (FeatureUtil.isLowRam()) {
-            // Low ram devices do not support voice command, skip this test
-            return;
-        }
-        PackageManager packageManager = mContext.getPackageManager();
-        if (packageManager.hasSystemFeature(PackageManager.FEATURE_MICROPHONE)) {
-            Intent intent = new Intent(Intent.ACTION_VOICE_COMMAND);
-            assertCanBeHandled(intent);
-            assertDefaultHandlerValidPriority(intent);
-        }
-    }
-
-    public void testVoiceSearchHandsFree() {
-        if (FeatureUtil.isLowRam()) {
-            // Low ram devices do not support hands-free hot word, skip this test
-            return;
-        }
-        PackageManager packageManager = mContext.getPackageManager();
-        if (packageManager.hasSystemFeature(PackageManager.FEATURE_MICROPHONE)) {
-            Intent intent = new Intent(RecognizerIntent.ACTION_VOICE_SEARCH_HANDS_FREE);
-            assertCanBeHandled(intent);
-            assertDefaultHandlerValidPriority(intent);
-        }
-    }
-
     public void testFingerprintEnrollStart() {
         PackageManager packageManager = mContext.getPackageManager();
         if (packageManager.hasSystemFeature(PackageManager.FEATURE_FINGERPRINT)) {
@@ -382,6 +356,10 @@
 
     public void testLocationScanningSettings() {
         PackageManager packageManager = mContext.getPackageManager();
+        if (packageManager.hasSystemFeature(PackageManager.FEATURE_WATCH)) {
+            // Skip the test for wearable device.
+            return;
+        }
         if (packageManager.hasSystemFeature(PackageManager.FEATURE_WIFI)
                 || packageManager.hasSystemFeature(PackageManager.FEATURE_BLUETOOTH_LE)) {
             assertCanBeHandled(new Intent("android.settings.LOCATION_SCANNING_SETTINGS"));
diff --git a/tests/tests/content/src/android/content/pm/cts/PackageManagerTest.java b/tests/tests/content/src/android/content/pm/cts/PackageManagerTest.java
index edc7924..60a7abd 100644
--- a/tests/tests/content/src/android/content/pm/cts/PackageManagerTest.java
+++ b/tests/tests/content/src/android/content/pm/cts/PackageManagerTest.java
@@ -436,12 +436,6 @@
                 mPackageManager.checkPermission(NOT_GRANTED_PERMISSION_NAME, PACKAGE_NAME));
     }
 
-    public void testCheckPermissionSystem() {
-        // Everything will be granted to the system.
-        assertEquals(PackageManager.PERMISSION_GRANTED,
-                mPackageManager.checkPermission(NOT_GRANTED_PERMISSION_NAME, "android"));
-    }
-
     public void testResolveMethods() {
         // Test resolveActivity
         Intent intent = new Intent(ACTIVITY_ACTION_NAME);
diff --git a/tests/tests/content/src/android/content/res/cts/PrivateAttributeTest.java b/tests/tests/content/src/android/content/res/cts/PrivateAttributeTest.java
index 0c18b4f..33a8777 100644
--- a/tests/tests/content/src/android/content/res/cts/PrivateAttributeTest.java
+++ b/tests/tests/content/src/android/content/res/cts/PrivateAttributeTest.java
@@ -27,7 +27,7 @@
  */
 public class PrivateAttributeTest extends AndroidTestCase {
 
-    private static final int sLastPublicAttr = 0x0101056d;
+    private static final int sLastPublicAttr = 0x010c001a;
 
     public void testNoAttributesAfterLastPublicAttribute() throws Exception {
         if (!Build.VERSION.CODENAME.equals("REL")) {
diff --git a/tests/tests/database/AndroidManifest.xml b/tests/tests/database/AndroidManifest.xml
index f9043db..145ed7b 100644
--- a/tests/tests/database/AndroidManifest.xml
+++ b/tests/tests/database/AndroidManifest.xml
@@ -16,7 +16,8 @@
  -->
 
 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
-    package="android.database.cts">
+    package="android.database.cts"
+    android:targetSandboxVersion="2">
 
     <uses-permission android:name="android.permission.DISABLE_KEYGUARD" />
     <application>
diff --git a/tests/tests/database/src/android/database/sqlite/cts/SQLiteDatabaseTest.java b/tests/tests/database/src/android/database/sqlite/cts/SQLiteDatabaseTest.java
index 6e3aa2c..2759a54 100644
--- a/tests/tests/database/src/android/database/sqlite/cts/SQLiteDatabaseTest.java
+++ b/tests/tests/database/src/android/database/sqlite/cts/SQLiteDatabaseTest.java
@@ -1657,7 +1657,7 @@
         String syncMode = DatabaseUtils
                 .stringForQuery(mDatabase, "PRAGMA synchronous", null);
 
-        assertEquals("2" /* FULL */, syncMode);
+        assertEquals("1" /* NORMAL */, syncMode);
     }
 
     /**
diff --git a/tests/tests/display/AndroidManifest.xml b/tests/tests/display/AndroidManifest.xml
index 5651f47..cc2d154 100644
--- a/tests/tests/display/AndroidManifest.xml
+++ b/tests/tests/display/AndroidManifest.xml
@@ -16,7 +16,8 @@
  -->
 
 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
-    package="android.display.cts">
+    package="android.display.cts"
+    android:targetSandboxVersion="2">
 
     <!-- For special presentation windows when testing mode switches. -->
     <uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW" />
diff --git a/tests/tests/dpi/AndroidManifest.xml b/tests/tests/dpi/AndroidManifest.xml
index 118050e..32576f2 100644
--- a/tests/tests/dpi/AndroidManifest.xml
+++ b/tests/tests/dpi/AndroidManifest.xml
@@ -16,7 +16,8 @@
  -->
 
 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
-    package="android.dpi.cts">
+    package="android.dpi.cts"
+    android:targetSandboxVersion="2">
 
     <uses-permission android:name="android.permission.DISABLE_KEYGUARD" />
     <application>
diff --git a/tests/tests/dreams/AndroidManifest.xml b/tests/tests/dreams/AndroidManifest.xml
index 8f1d75e..e683700 100644
--- a/tests/tests/dreams/AndroidManifest.xml
+++ b/tests/tests/dreams/AndroidManifest.xml
@@ -14,7 +14,8 @@
      limitations under the License.
 -->
 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
-    package="android.dreams.cts">
+    package="android.dreams.cts"
+    android:targetSandboxVersion="2">
 
     <uses-permission android:name="android.permission.DISABLE_KEYGUARD" />
     <application>
diff --git a/tests/tests/gesture/AndroidManifest.xml b/tests/tests/gesture/AndroidManifest.xml
index fb3ee51..eed0ffd 100755
--- a/tests/tests/gesture/AndroidManifest.xml
+++ b/tests/tests/gesture/AndroidManifest.xml
@@ -16,7 +16,8 @@
  -->
 
 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
-    package="android.gesture.cts">
+    package="android.gesture.cts"
+    android:targetSandboxVersion="2">
 
     <application>
         <uses-library android:name="android.test.runner" />
diff --git a/tests/tests/graphics/jni/android_graphics_cts_CameraGpuCtsActivity.cpp b/tests/tests/graphics/jni/android_graphics_cts_CameraGpuCtsActivity.cpp
index 05cc03b..a6b6c5f 100644
--- a/tests/tests/graphics/jni/android_graphics_cts_CameraGpuCtsActivity.cpp
+++ b/tests/tests/graphics/jni/android_graphics_cts_CameraGpuCtsActivity.cpp
@@ -311,8 +311,8 @@
 
 bool isCameraReady(JNIEnv*, jclass, jlong renderer) {
     if (renderer == 0) {
-        ALOGE("Invalid renderer.");
-        return -EINVAL;
+        ALOGE("isCameraReady: Invalid renderer: nullptr.");
+        return false;
     }
 
     return native(renderer)->isCameraReady();
diff --git a/tests/tests/graphics/src/android/graphics/cts/CameraGpuCtsActivity.java b/tests/tests/graphics/src/android/graphics/cts/CameraGpuCtsActivity.java
index 7df9892..6508bf3 100644
--- a/tests/tests/graphics/src/android/graphics/cts/CameraGpuCtsActivity.java
+++ b/tests/tests/graphics/src/android/graphics/cts/CameraGpuCtsActivity.java
@@ -20,10 +20,11 @@
 import android.opengl.GLSurfaceView;
 import android.os.Bundle;
 import android.view.Window;
-import android.util.Log;
 
 import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.Semaphore;
 import java.util.concurrent.TimeUnit;
+
 import javax.microedition.khronos.egl.EGLConfig;
 import javax.microedition.khronos.opengles.GL10;
 
@@ -39,6 +40,7 @@
     private static final String TAG = "CameraGpuCtsActivity";
 
     protected GLSurfaceView mView;
+    protected Semaphore mNativeRendererInitialized;
     protected long mNativeRenderer;
     private CountDownLatch mFinishedRendering;
 
@@ -55,12 +57,14 @@
 
         public void onSurfaceCreated(GL10 gl, EGLConfig config) {
             mNativeRenderer = nCreateRenderer();
+            mNativeRendererInitialized.release();
         }
     }
 
     @Override
     public void onCreate(Bundle savedInstanceState) {
         super.onCreate(savedInstanceState);
+        mNativeRendererInitialized = new Semaphore(0);
         mView = new GLSurfaceView(this);
         mView.setEGLContextClientVersion(2);
         mView.setRenderer(new Renderer());
@@ -92,6 +96,8 @@
     }
 
     public void waitToFinishRendering() throws InterruptedException {
+        // Wait for renderer initialization
+        mNativeRendererInitialized.acquire();
         // Skip the test if there is no camera on board.
         if (!nIsCameraReady(mNativeRenderer)) {
             return;
diff --git a/tests/tests/graphics/src/android/graphics/cts/ImageDecoderTest.java b/tests/tests/graphics/src/android/graphics/cts/ImageDecoderTest.java
index a9865fe..1ce3706 100644
--- a/tests/tests/graphics/src/android/graphics/cts/ImageDecoderTest.java
+++ b/tests/tests/graphics/src/android/graphics/cts/ImageDecoderTest.java
@@ -1678,16 +1678,11 @@
             }
         };
         Listener l = new Listener();
-        int resIds[] = new int[] { R.drawable.png_test, R.raw.basi6a16 };
-        // Though png_test is opaque, using HARDWARE will require 8888, so we
-        // do not decode to 565. basi6a16 will still downconvert from F16 to
-        // 8888.
-        boolean hardwareOverrides[] = new boolean[] { true, false };
         SourceCreator f = mCreators[0];
-        for (int i = 0; i < resIds.length; ++i) {
+        for (int resId : new int[] { R.drawable.png_test, R.raw.basi6a16 }) {
             Bitmap normal = null;
             try {
-                normal = ImageDecoder.decodeBitmap(f.apply(resIds[i]));
+                normal = ImageDecoder.decodeBitmap(f.apply(resId));
             } catch (IOException e) {
                 fail("Failed with exception " + e);
             }
@@ -1697,17 +1692,38 @@
                 l.allocator = allocator;
                 Bitmap test = null;
                 try {
-                   test = ImageDecoder.decodeBitmap(f.apply(resIds[i]), l);
+                    test = ImageDecoder.decodeBitmap(f.apply(resId), l);
                 } catch (IOException e) {
                     fail("Failed with exception " + e);
                 }
                 assertNotNull(test);
                 int byteCount = test.getAllocationByteCount();
-                if ((allocator == ImageDecoder.ALLOCATOR_HARDWARE ||
-                     allocator == ImageDecoder.ALLOCATOR_DEFAULT)
-                    && hardwareOverrides[i]) {
-                    assertEquals(normalByteCount, byteCount);
+
+                if (allocator == ImageDecoder.ALLOCATOR_HARDWARE
+                        || allocator == ImageDecoder.ALLOCATOR_DEFAULT) {
+                    if (resId == R.drawable.png_test) {
+                        // We do not support 565 in HARDWARE, so no RAM savings
+                        // are possible.
+                        assertEquals(normalByteCount, byteCount);
+                    } else { // R.raw.basi6a16
+                        // This image defaults to F16. MEMORY_POLICY_LOW_RAM
+                        // forces "test" to decode to 8888. But if the device
+                        // does not support F16 in HARDWARE, "normal" is also
+                        // 8888. Its Config is HARDWARE either way, but we can
+                        // detect its underlying pixel format by checking the
+                        // ColorSpace, which is always LINEAR_EXTENDED_SRGB for
+                        // F16.
+                        if (normal.getColorSpace().equals(
+                                    ColorSpace.get(ColorSpace.Named.LINEAR_EXTENDED_SRGB))) {
+                            // F16. "test" should be smaller.
+                            assertTrue(byteCount < normalByteCount);
+                        } else {
+                            // 8888. No RAM savings possible.
+                            assertEquals(normalByteCount, byteCount);
+                        }
+                    }
                 } else {
+                    // Not decoding to HARDWARE, so we can save RAM in either case.
                     assertTrue(byteCount < normalByteCount);
                 }
             }
diff --git a/tests/tests/graphics/src/android/graphics/drawable/cts/AnimatedImageDrawableTest.java b/tests/tests/graphics/src/android/graphics/drawable/cts/AnimatedImageDrawableTest.java
index e8d0cd5..a3f116e 100644
--- a/tests/tests/graphics/src/android/graphics/drawable/cts/AnimatedImageDrawableTest.java
+++ b/tests/tests/graphics/src/android/graphics/drawable/cts/AnimatedImageDrawableTest.java
@@ -249,6 +249,9 @@
     public void testLifeCycle() throws Throwable {
         AnimatedImageDrawable drawable = createFromImageDecoder(RES_ID);
 
+        // Only run the animation one time.
+        drawable.setRepeatCount(0);
+
         Callback cb = new Callback(drawable);
         mActivityRule.runOnUiThread(() -> {
             setContentView(drawable);
@@ -267,11 +270,8 @@
         cb.waitForStart();
         cb.assertStarted(true);
 
-        // Only run the animation one time.
-        drawable.setRepeatCount(0);
-
         // Extra time, to wait for the message to post.
-        cb.waitForEnd(DURATION * 2);
+        cb.waitForEnd(DURATION * 3);
         cb.assertEnded(true);
         assertFalse(drawable.isRunning());
     }
@@ -333,7 +333,9 @@
             drawable.registerAnimationCallback(cb);
         });
 
-        cb.waitForEnd(DURATION * 2);
+        // Add extra duration to wait for the message posted by the end of the
+        // animation. This should help fix flakiness.
+        cb.waitForEnd(DURATION * 3);
         cb.assertEnded(true);
     }
 
@@ -353,9 +355,9 @@
             assertFalse(drawable.isRunning());
         });
 
-        // Duration may be overkill, but we need to wait for the message
-        // to post.
-        cb.waitForEnd(DURATION);
+        // This duration may be overkill, but we need to wait for the message
+        // to post. Increasing it should help with flakiness on bots.
+        cb.waitForEnd(DURATION * 3);
         cb.assertStarted(true);
         cb.assertEnded(true);
     }
diff --git a/tests/tests/hardware/src/android/hardware/biometrics/cts/BiometricPromptTest.java b/tests/tests/hardware/src/android/hardware/biometrics/cts/BiometricPromptTest.java
new file mode 100644
index 0000000..2279f41
--- /dev/null
+++ b/tests/tests/hardware/src/android/hardware/biometrics/cts/BiometricPromptTest.java
@@ -0,0 +1,108 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+
+package android.hardware.biometrics.cts;
+
+import android.content.DialogInterface;
+import android.content.pm.PackageManager;
+import android.hardware.biometrics.BiometricPrompt;
+import android.os.CancellationSignal;
+import android.os.Handler;
+import android.os.Looper;
+import android.platform.test.annotations.Presubmit;
+import android.test.AndroidTestCase;
+
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.Executor;
+import java.util.concurrent.TimeUnit;
+
+/**
+ * Basic test cases for BiometricPrompt
+ */
+public class BiometricPromptTest extends AndroidTestCase {
+
+    private static final int AWAIT_TIMEOUT_MS = 3000;
+
+    private final Handler mHandler = new Handler(Looper.getMainLooper());
+    private final CountDownLatch mLatch = new CountDownLatch(1);
+
+    private int mErrorReceived;
+
+    private final Executor mExecutor = new Executor() {
+        @Override
+        public void execute(Runnable runnable) {
+            mHandler.post(runnable);
+        }
+    };
+
+    private final BiometricPrompt.AuthenticationCallback mAuthenticationCallback
+            = new BiometricPrompt.AuthenticationCallback() {
+        @Override
+        public void onAuthenticationError(int errorCode, CharSequence errString) {
+            mErrorReceived = errorCode;
+            mLatch.countDown();
+        }
+
+        @Override
+        public void onAuthenticationHelp(int helpCode, CharSequence helpString) {}
+
+        @Override
+        public void onAuthenticationFailed() {}
+
+        @Override
+        public void onAuthenticationSucceeded(BiometricPrompt.AuthenticationResult result) {}
+    };
+
+    /**
+     * Test that we can try to start fingerprint authentication. It won't actually start since
+     * there are no fingers enrolled. Cts-verifier will check the implementation.
+     */
+    @Presubmit
+    public void test_authenticate_fingerprint() {
+        final PackageManager pm = getContext().getPackageManager();
+        if (!pm.hasSystemFeature(PackageManager.FEATURE_FINGERPRINT)) {
+            return;
+        }
+
+        boolean exceptionTaken = false;
+        boolean callbackReceived = false;
+        CancellationSignal cancellationSignal = new CancellationSignal();
+        try {
+            BiometricPrompt.Builder builder = new BiometricPrompt.Builder(getContext());
+            builder.setTitle("Title");
+            builder.setSubtitle("Subtitle");
+            builder.setDescription("Description");
+            builder.setNegativeButton("Negative", mExecutor, new DialogInterface.OnClickListener() {
+                @Override
+                public void onClick(DialogInterface dialog, int which) {
+
+                }
+            });
+
+            BiometricPrompt prompt = builder.build();
+
+            prompt.authenticate(cancellationSignal, mExecutor, mAuthenticationCallback);
+            mLatch.await(AWAIT_TIMEOUT_MS, TimeUnit.MILLISECONDS);
+            assert(mErrorReceived == BiometricPrompt.BIOMETRIC_ERROR_NO_BIOMETRICS);
+        } catch (Exception e) {
+            exceptionTaken = true;
+        } finally {
+            assertFalse(exceptionTaken);
+            cancellationSignal.cancel();
+        }
+    }
+
+}
diff --git a/tests/tests/hardware/src/android/hardware/input/cts/tests/InputTestCase.java b/tests/tests/hardware/src/android/hardware/input/cts/tests/InputTestCase.java
index 27ba081..9089529 100644
--- a/tests/tests/hardware/src/android/hardware/input/cts/tests/InputTestCase.java
+++ b/tests/tests/hardware/src/android/hardware/input/cts/tests/InputTestCase.java
@@ -24,6 +24,7 @@
 import android.hardware.input.cts.InputCallback;
 import android.hardware.input.cts.InputCtsActivity;
 import android.os.ParcelFileDescriptor;
+import android.os.SystemClock;
 import android.support.test.InstrumentationRegistry;
 import android.support.test.rule.ActivityTestRule;
 import android.view.KeyEvent;
@@ -103,6 +104,7 @@
         } catch (InterruptedException ex) {
             fail("Unexpectedly interrupted while waiting for device added notification.");
         }
+        SystemClock.sleep(100);
     }
 
     /**
diff --git a/tests/tests/keystore/src/android/keystore/cts/CipherTest.java b/tests/tests/keystore/src/android/keystore/cts/CipherTest.java
index add33ae..88a59fe 100644
--- a/tests/tests/keystore/src/android/keystore/cts/CipherTest.java
+++ b/tests/tests/keystore/src/android/keystore/cts/CipherTest.java
@@ -465,6 +465,10 @@
             assertNotNull(provider);
             final byte[] originalPlaintext = EmptyArray.BYTE;
             for (String algorithm : EXPECTED_ALGORITHMS) {
+                // Normally we would test all combinations of algorithms and key sizes, but the
+                // semi-manual locking and unlocking this requires takes way too long if we try to
+                // go through all of those. Other tests check all the key sizes, so we don't need to
+                // duplicate all that work.
                 for (ImportedKey key : importKatKeys(
                         algorithm,
                         KeyProperties.PURPOSE_ENCRYPT | KeyProperties.PURPOSE_DECRYPT,
@@ -508,6 +512,9 @@
                               "Failed for " + algorithm + " with key " + key.getAlias(),
                                e);
                     }
+                    // We don't know the underlying type of this collection, so just break out of
+                    // the iterator loop.
+                    break;
                 }
             }
         }
diff --git a/tests/tests/location/src/android/location/cts/GnssMeasurementValuesTest.java b/tests/tests/location/src/android/location/cts/GnssMeasurementValuesTest.java
index 023b616..1cb02d4 100644
--- a/tests/tests/location/src/android/location/cts/GnssMeasurementValuesTest.java
+++ b/tests/tests/location/src/android/location/cts/GnssMeasurementValuesTest.java
@@ -94,7 +94,7 @@
         Log.i(TAG, "Location status received = " + mLocationListener.isLocationReceived());
 
         if (!mMeasurementListener.verifyStatus(isMeasurementTestStrict())) {
-            // If test is strict and veriifyState reutrns false, an assert exception happens and
+            // If test is strict and verifyStatus returns false, an assert exception happens and
             // test fails.   If test is not strict, we arrive here, and:
             return; // exit (with pass)
         }
@@ -102,12 +102,12 @@
         List<GnssMeasurementsEvent> events = mMeasurementListener.getEvents();
         int eventCount = events.size();
         Log.i(TAG, "Number of Gps Event received = " + eventCount);
-        SoftAssert.failOrWarning(isMeasurementTestStrict(),
-                "GnssMeasurementEvent count: expected >= 0, received = " + eventCount,
-                eventCount > 0);
 
         SoftAssert softAssert = new SoftAssert(TAG);
 
+        softAssert.assertTrue("GnssMeasurementEvent count", "X > 0",
+                String.valueOf(eventCount), eventCount > 0);
+
         boolean carrierPhaseQualityPrrFound = false;
         // we received events, so perform a quick sanity check on mandatory fields
         for (GnssMeasurementsEvent event : events) {
@@ -119,8 +119,8 @@
             TestMeasurementUtil.assertGnssClockFields(event.getClock(), softAssert, timeInNs);
 
             for (GnssMeasurement measurement : event.getMeasurements()) {
-                TestMeasurementUtil.assertAllGnssMeasurementMandatoryFields(measurement,
-                        softAssert, timeInNs);
+                TestMeasurementUtil.assertAllGnssMeasurementMandatoryFields(mTestLocationManager,
+                        measurement, softAssert, timeInNs);
                 carrierPhaseQualityPrrFound |=
                         TestMeasurementUtil.gnssMeasurementHasCarrierPhasePrr(measurement);
             }
diff --git a/tests/tests/location/src/android/location/cts/GnssMeasurementWhenNoLocationTest.java b/tests/tests/location/src/android/location/cts/GnssMeasurementWhenNoLocationTest.java
index 32c54c9..7a6c152 100644
--- a/tests/tests/location/src/android/location/cts/GnssMeasurementWhenNoLocationTest.java
+++ b/tests/tests/location/src/android/location/cts/GnssMeasurementWhenNoLocationTest.java
@@ -180,8 +180,8 @@
 
         // Verify mandatory fields of GnssMeasurement
         for (GnssMeasurement measurement : gpsMeasurements) {
-            TestMeasurementUtil.assertAllGnssMeasurementMandatoryFields(measurement,
-                    softAssert, timeInNs);
+            TestMeasurementUtil.assertAllGnssMeasurementMandatoryFields(mTestLocationManager,
+                    measurement, softAssert, timeInNs);
         }
         softAssert.assertAll();
     }
diff --git a/tests/tests/location/src/android/location/cts/TestMeasurementUtil.java b/tests/tests/location/src/android/location/cts/TestMeasurementUtil.java
index 4df2b15..fa9f9c5 100644
--- a/tests/tests/location/src/android/location/cts/TestMeasurementUtil.java
+++ b/tests/tests/location/src/android/location/cts/TestMeasurementUtil.java
@@ -54,6 +54,8 @@
             " a full bugreport.";
 
     private static final int YEAR_2016 = 2016;
+    private static final int YEAR_2017 = 2017;
+    private static final int YEAR_2018 = 2018;
 
     // The valid Gnss navigation message type as listed in
     // android/hardware/libhardware/include/hardware/gps.h
@@ -163,17 +165,20 @@
      * Assert all mandatory fields in Gnss Measurement are in expected range.
      * See mandatory fields in {@code gps.h}.
      *
+     * @param testLocationManager TestLocationManager
      * @param measurement GnssMeasurement
      * @param softAssert  custom SoftAssert
      * @param timeInNs    event time in ns
      */
-    public static void assertAllGnssMeasurementMandatoryFields(GnssMeasurement measurement,
+    public static void assertAllGnssMeasurementMandatoryFields(
+        TestLocationManager testLocationManager, GnssMeasurement measurement,
         SoftAssert softAssert, long timeInNs) {
 
         verifySvid(measurement, softAssert, timeInNs);
         verifyReceivedSatelliteVehicleTimeInNs(measurement, softAssert, timeInNs);
         verifyAccumulatedDeltaRanges(measurement, softAssert, timeInNs);
 
+        int gnssYearOfHardware = testLocationManager.getLocationManager().getGnssYearOfHardware();
         int state = measurement.getState();
         softAssert.assertTrue("state: Satellite code sync state",
                 timeInNs,
@@ -213,6 +218,16 @@
                 measurement.getPseudorangeRateUncertaintyMetersPerSecond() > 0.0);
 
         // Check carrier_frequency_hz.
+        // As per CDD 7.3.3 / C-3-3 Year 2107+ should have Carrier Frequency present
+        // Enforcing it only for year 2018+
+        if (gnssYearOfHardware >= YEAR_2018) {
+            softAssert.assertTrue("Carrier Frequency in measurement",
+                    timeInNs,
+                    "X == true",
+                    String.valueOf(measurement.hasCarrierFrequencyHz()),
+                    measurement.hasCarrierFrequencyHz());
+        }
+
         if (measurement.hasCarrierFrequencyHz()) {
             softAssert.assertTrue("carrier_frequency_hz: Carrier frequency in hz",
                     timeInNs,
@@ -259,6 +274,14 @@
         }
 
         // Check Automatic Gain Control level in dB.
+        // As per CDD 7.3.3 / C-3-3 Year 2107+ should have AGC level present
+        if (gnssYearOfHardware >= YEAR_2017) {
+            softAssert.assertTrue("AGC level in measurement",
+                    timeInNs,
+                    "X == true",
+                    String.valueOf(measurement.hasAutomaticGainControlLevelDb()),
+                    measurement.hasAutomaticGainControlLevelDb());
+        }
         if (measurement.hasAutomaticGainControlLevelDb()) {
             softAssert.assertTrue("Automatic Gain Control level in dB",
                 timeInNs,
diff --git a/tests/tests/media/libmediandkjni/native-mediadrm-jni.cpp b/tests/tests/media/libmediandkjni/native-mediadrm-jni.cpp
index cc4387b..ea95574 100644
--- a/tests/tests/media/libmediandkjni/native-mediadrm-jni.cpp
+++ b/tests/tests/media/libmediandkjni/native-mediadrm-jni.cpp
@@ -19,6 +19,7 @@
 #include <utils/Log.h>
 #include <sys/types.h>
 
+#include <list>
 #include <string>
 #include <vector>
 
@@ -741,6 +742,62 @@
     return JNI_TRUE;
 }
 
+extern "C" jboolean Java_android_media_cts_NativeMediaDrmClearkeyTest_testFindSessionIdNative(
+    JNIEnv* env, jclass /*clazz*/, jbyteArray uuid) {
+
+    if (NULL == uuid) {
+        jniThrowException(env, "java/lang/NullPointerException", "null uuid");
+        return JNI_FALSE;
+    }
+
+    Uuid juuid = jbyteArrayToUuid(env, uuid);
+    if (!isUuidSizeValid(juuid)) {
+        jniThrowExceptionFmt(env, "java/lang/IllegalArgumentException",
+                "invalid UUID size, expected %u bytes", kUuidSize);
+        return JNI_FALSE;
+    }
+
+    AMediaObjects aMediaObjects;
+    media_status_t status = AMEDIA_OK;
+    aMediaObjects.setDrm(AMediaDrm_createByUUID(&juuid[0]));
+    if (NULL == aMediaObjects.getDrm()) {
+        jniThrowException(env, "java/lang/RuntimeException", "failed to create drm");
+        return JNI_FALSE;
+    }
+
+    // Stores duplicates of session id.
+    std::vector<std::vector<uint8_t> > sids;
+
+    std::list<AMediaDrmSessionId> sessionIds;
+    AMediaDrmSessionId sessionId;
+    for (int i = 0; i < 5; ++i) {
+        status = AMediaDrm_openSession(aMediaObjects.getDrm(), &sessionId);
+        if (status != AMEDIA_OK) {
+            jniThrowException(env, "java/lang/RuntimeException", "openSession failed");
+            return JNI_FALSE;
+        }
+
+        // Allocates a new pointer to duplicate the session id returned by
+        // AMediaDrm_openSession. These new pointers will be passed to
+        // AMediaDrm_closeSession, which verifies that the ndk
+        // can find the session id even if the pointer has changed.
+        sids.push_back(std::vector<uint8_t>(sessionId.length));
+        memcpy(sids.at(i).data(), sessionId.ptr, sessionId.length);
+        sessionId.ptr = static_cast<uint8_t *>(sids.at(i).data());
+        sessionIds.push_back(sessionId);
+    }
+
+    for (auto sessionId : sessionIds) {
+        status = AMediaDrm_closeSession(aMediaObjects.getDrm(), &sessionId);
+        if (status != AMEDIA_OK) {
+            jniThrowException(env, "java/lang/RuntimeException", "closeSession failed");
+            return JNI_FALSE;
+        }
+    }
+
+    return JNI_TRUE;
+}
+
 static JNINativeMethod gMethods[] = {
     { "isCryptoSchemeSupportedNative", "([B)Z",
             (void *)Java_android_media_cts_NativeMediaDrmClearkeyTest_isCryptoSchemeSupportedNative },
@@ -758,6 +815,9 @@
 
     { "testQueryKeyStatusNative", "([B)Z",
             (void *)Java_android_media_cts_NativeMediaDrmClearkeyTest_testQueryKeyStatusNative },
+
+    { "testFindSessionIdNative", "([B)Z",
+            (void *)Java_android_media_cts_NativeMediaDrmClearkeyTest_testFindSessionIdNative },
 };
 
 int register_android_media_cts_NativeMediaDrmClearkeyTest(JNIEnv* env) {
diff --git a/tests/tests/media/res/raw/noise_1ch_29_4khz_aot42_19_lufs_drc_config_change_mp4.m4a b/tests/tests/media/res/raw/noise_1ch_29_4khz_aot42_19_lufs_drc_config_change_mp4.m4a
new file mode 100755
index 0000000..0bb8dad
--- /dev/null
+++ b/tests/tests/media/res/raw/noise_1ch_29_4khz_aot42_19_lufs_drc_config_change_mp4.m4a
Binary files differ
diff --git a/tests/tests/media/res/raw/noise_1ch_38_4khz_aot42_19_lufs_config_change_mp4.m4a b/tests/tests/media/res/raw/noise_1ch_38_4khz_aot42_19_lufs_config_change_mp4.m4a
new file mode 100755
index 0000000..497ff98
--- /dev/null
+++ b/tests/tests/media/res/raw/noise_1ch_38_4khz_aot42_19_lufs_config_change_mp4.m4a
Binary files differ
diff --git a/tests/tests/media/res/raw/noise_2ch_08khz_aot42_19_lufs_mp4.m4a b/tests/tests/media/res/raw/noise_2ch_08khz_aot42_19_lufs_mp4.m4a
new file mode 100755
index 0000000..36de1b0
--- /dev/null
+++ b/tests/tests/media/res/raw/noise_2ch_08khz_aot42_19_lufs_mp4.m4a
Binary files differ
diff --git a/tests/tests/media/res/raw/noise_2ch_12khz_aot42_19_lufs_mp4.m4a b/tests/tests/media/res/raw/noise_2ch_12khz_aot42_19_lufs_mp4.m4a
new file mode 100755
index 0000000..7cd7923
--- /dev/null
+++ b/tests/tests/media/res/raw/noise_2ch_12khz_aot42_19_lufs_mp4.m4a
Binary files differ
diff --git a/tests/tests/media/res/raw/noise_2ch_19_2khz_aot42_no_ludt_mp4.m4a b/tests/tests/media/res/raw/noise_2ch_19_2khz_aot42_no_ludt_mp4.m4a
new file mode 100755
index 0000000..6efdb14
--- /dev/null
+++ b/tests/tests/media/res/raw/noise_2ch_19_2khz_aot42_no_ludt_mp4.m4a
Binary files differ
diff --git a/tests/tests/media/res/raw/noise_2ch_22_05khz_aot42_19_lufs_mp4.m4a b/tests/tests/media/res/raw/noise_2ch_22_05khz_aot42_19_lufs_mp4.m4a
new file mode 100755
index 0000000..a164036
--- /dev/null
+++ b/tests/tests/media/res/raw/noise_2ch_22_05khz_aot42_19_lufs_mp4.m4a
Binary files differ
diff --git a/tests/tests/media/res/raw/noise_2ch_32khz_aot42_19_lufs_drc_mp4.m4a b/tests/tests/media/res/raw/noise_2ch_32khz_aot42_19_lufs_drc_mp4.m4a
new file mode 100755
index 0000000..e806d3f
--- /dev/null
+++ b/tests/tests/media/res/raw/noise_2ch_32khz_aot42_19_lufs_drc_mp4.m4a
Binary files differ
diff --git a/tests/tests/media/res/raw/noise_2ch_35_28khz_aot42_19_lufs_drc_config_change_mp4.m4a b/tests/tests/media/res/raw/noise_2ch_35_28khz_aot42_19_lufs_drc_config_change_mp4.m4a
new file mode 100755
index 0000000..5336d1b
--- /dev/null
+++ b/tests/tests/media/res/raw/noise_2ch_35_28khz_aot42_19_lufs_drc_config_change_mp4.m4a
Binary files differ
diff --git a/tests/tests/media/res/raw/noise_2ch_44_1khz_aot42_19_lufs_config_change_mp4.m4a b/tests/tests/media/res/raw/noise_2ch_44_1khz_aot42_19_lufs_config_change_mp4.m4a
new file mode 100755
index 0000000..0daf7fb
--- /dev/null
+++ b/tests/tests/media/res/raw/noise_2ch_44_1khz_aot42_19_lufs_config_change_mp4.m4a
Binary files differ
diff --git a/tests/tests/media/res/raw/noise_2ch_48khz_aot42_19_lufs_mp4.m4a b/tests/tests/media/res/raw/noise_2ch_48khz_aot42_19_lufs_mp4.m4a
new file mode 100755
index 0000000..dbfd613
--- /dev/null
+++ b/tests/tests/media/res/raw/noise_2ch_48khz_aot42_19_lufs_mp4.m4a
Binary files differ
diff --git a/tests/tests/media/res/raw/noise_2ch_64khz_aot42_19_lufs_mp4.m4a b/tests/tests/media/res/raw/noise_2ch_64khz_aot42_19_lufs_mp4.m4a
new file mode 100755
index 0000000..d7739df
--- /dev/null
+++ b/tests/tests/media/res/raw/noise_2ch_64khz_aot42_19_lufs_mp4.m4a
Binary files differ
diff --git a/tests/tests/media/res/raw/noise_2ch_88_2khz_aot42_19_lufs_mp4.m4a b/tests/tests/media/res/raw/noise_2ch_88_2khz_aot42_19_lufs_mp4.m4a
new file mode 100755
index 0000000..c93ea5f
--- /dev/null
+++ b/tests/tests/media/res/raw/noise_2ch_88_2khz_aot42_19_lufs_mp4.m4a
Binary files differ
diff --git a/tests/tests/media/src/android/media/cts/AdaptivePlaybackTest.java b/tests/tests/media/src/android/media/cts/AdaptivePlaybackTest.java
index 2e7a848..4f5ec97 100644
--- a/tests/tests/media/src/android/media/cts/AdaptivePlaybackTest.java
+++ b/tests/tests/media/src/android/media/cts/AdaptivePlaybackTest.java
@@ -31,6 +31,8 @@
 import android.util.Log;
 import android.view.Surface;
 
+import com.android.compatibility.common.util.MediaUtils;
+
 import android.opengl.GLES20;
 import javax.microedition.khronos.opengles.GL10;
 
@@ -53,7 +55,6 @@
         return factory.createCodecList(
                 mContext,
                 MediaFormat.MIMETYPE_VIDEO_AVC,
-                "OMX.google.h264.decoder",
                 R.raw.video_480x360_mp4_h264_1000kbps_25fps_aac_stereo_128kbps_44100hz,
                 R.raw.video_1280x720_mp4_h264_1000kbps_25fps_aac_stereo_128kbps_44100hz,
                 R.raw.bbb_s1_720x480_mp4_h264_mp3_2mbps_30fps_aac_lc_5ch_320kbps_48000hz);
@@ -63,7 +64,6 @@
         return factory.createCodecList(
                 mContext,
                 MediaFormat.MIMETYPE_VIDEO_HEVC,
-                "OMX.google.hevc.decoder",
                 R.raw.bbb_s1_720x480_mp4_hevc_mp3_1600kbps_30fps_aac_he_6ch_240kbps_48000hz,
                 R.raw.bbb_s4_1280x720_mp4_hevc_mp31_4mbps_30fps_aac_he_stereo_80kbps_32000hz,
                 R.raw.bbb_s1_352x288_mp4_hevc_mp2_600kbps_30fps_aac_he_stereo_96kbps_48000hz);
@@ -73,7 +73,6 @@
         return factory.createCodecList(
                 mContext,
                 MediaFormat.MIMETYPE_VIDEO_H263,
-                "OMX.google.h263.decoder",
                 R.raw.video_176x144_3gp_h263_300kbps_12fps_aac_stereo_128kbps_22050hz,
                 R.raw.video_352x288_3gp_h263_300kbps_12fps_aac_stereo_128kbps_22050hz);
     }
@@ -82,8 +81,6 @@
         return factory.createCodecList(
                 mContext,
                 MediaFormat.MIMETYPE_VIDEO_MPEG4,
-                "OMX.google.mpeg4.decoder",
-
                 R.raw.video_1280x720_mp4_mpeg4_1000kbps_25fps_aac_stereo_128kbps_44100hz,
                 R.raw.video_480x360_mp4_mpeg4_860kbps_25fps_aac_stereo_128kbps_44100hz,
                 R.raw.video_176x144_mp4_mpeg4_300kbps_25fps_aac_stereo_128kbps_44100hz);
@@ -93,7 +90,6 @@
         return factory.createCodecList(
                 mContext,
                 MediaFormat.MIMETYPE_VIDEO_VP8,
-                "OMX.google.vp8.decoder",
                 R.raw.video_480x360_webm_vp8_333kbps_25fps_vorbis_stereo_128kbps_48000hz,
                 R.raw.bbb_s3_1280x720_webm_vp8_8mbps_60fps_opus_6ch_384kbps_48000hz,
                 R.raw.bbb_s1_320x180_webm_vp8_800kbps_30fps_opus_5ch_320kbps_48000hz);
@@ -103,7 +99,6 @@
         return factory.createCodecList(
                 mContext,
                 MediaFormat.MIMETYPE_VIDEO_VP9,
-                "OMX.google.vp9.decoder",
                 R.raw.video_480x360_webm_vp9_333kbps_25fps_vorbis_stereo_128kbps_48000hz,
                 R.raw.bbb_s4_1280x720_webm_vp9_0p31_4mbps_30fps_opus_stereo_128kbps_48000hz,
                 R.raw.bbb_s1_320x180_webm_vp9_0p11_600kbps_30fps_vorbis_mono_64kbps_48000hz);
@@ -1388,7 +1383,7 @@
     private final static String TAG = "AdaptiveCodecFamily";
     private static final int NUM_FRAMES = AdaptivePlaybackTest.NUM_FRAMES;
 
-    public CodecFamily(Context context, String mime, String explicitCodecName, int ... resources) {
+    public CodecFamily(Context context, String mime, int ... resources) {
         try {
             /* read all media */
             Media[] mediaList = new Media[resources.length];
@@ -1418,10 +1413,6 @@
                 }
                 for (String type : codecInfo.getSupportedTypes()) {
                     if (type.equals(mime)) {
-                        /* mark the explicitly named codec as included */
-                        if (codecInfo.getName().equals(explicitCodecName)) {
-                            explicitCodecName = null;
-                        }
                         add(new Codec(
                                 codecInfo.getName(),
                                 codecInfo.getCapabilitiesForType(mime),
@@ -1430,15 +1421,6 @@
                     }
                 }
             }
-
-            /* test if the explicitly named codec is present on the system */
-            if (explicitCodecName != null) {
-                MediaCodec codec = MediaCodec.createByCodecName(explicitCodecName);
-                if (codec != null) {
-                    codec.release();
-                    add(new Codec(explicitCodecName, null, mediaList));
-                }
-            }
         } catch (Throwable t) {
             Log.wtf("Constructor failed", t);
             throw new RuntimeException("constructor failed", t);
@@ -1446,23 +1428,12 @@
     }
 }
 
-/* named codec if exists */
-class CodecByName extends CodecList {
-    public CodecByName(Context context, String mime, String codecName, int ... resources) {
-        for (Codec c: new CodecFamily(context, mime, codecName, resources)) {
-            if (c.name.equals(codecName)) {
-                add(c);
-            }
-        }
-    }
-}
-
 /* all codecs of mime, except named codec if exists */
-class CodecFamilyExcept extends CodecList {
-    public CodecFamilyExcept(
-            Context context, String mime, String exceptCodecName, int ... resources) {
-        for (Codec c: new CodecFamily(context, mime, null, resources)) {
-            if (!c.name.equals(exceptCodecName)) {
+class CodecFamilySpecific extends CodecList {
+    public CodecFamilySpecific(
+            Context context, String mime, boolean isGoogle, int ... resources) {
+        for (Codec c: new CodecFamily(context, mime, resources)) {
+            if (MediaUtils.isGoogle(c.name) == isGoogle) {
                 add(c);
             }
         }
@@ -1470,42 +1441,23 @@
 }
 
 class CodecFactory {
-    protected boolean hasCodec(String codecName) {
-        MediaCodecList list = new MediaCodecList(MediaCodecList.ALL_CODECS);
-        for (MediaCodecInfo info : list.getCodecInfos()) {
-            if (codecName.equals(info.getName())) {
-                return true;
-            }
-        }
-        return false;
-    }
-
     public CodecList createCodecList(
-            Context context, String mime, String googleCodecName, int ...resources) {
-        if (!hasCodec(googleCodecName)) {
-            return null;
-        }
-        return new CodecFamily(context, mime, googleCodecName, resources);
+            Context context, String mime, int ...resources) {
+        return new CodecFamily(context, mime, resources);
     }
 }
 
 class SWCodecFactory extends CodecFactory {
     public CodecList createCodecList(
-            Context context, String mime, String googleCodecName, int ...resources) {
-        if (!hasCodec(googleCodecName)) {
-            return null;
-        }
-        return new CodecByName(context, mime, googleCodecName, resources);
+            Context context, String mime, int ...resources) {
+        return new CodecFamilySpecific(context, mime, true, resources);
     }
 }
 
 class HWCodecFactory extends CodecFactory {
     public CodecList createCodecList(
-            Context context, String mime, String googleCodecName, int ...resources) {
-        if (!hasCodec(googleCodecName)) {
-            return null;
-        }
-        return new CodecFamilyExcept(context, mime, googleCodecName, resources);
+            Context context, String mime, int ...resources) {
+        return new CodecFamilySpecific(context, mime, false, resources);
     }
 }
 
@@ -1784,4 +1736,3 @@
         return false;
     }
 }
-
diff --git a/tests/tests/media/src/android/media/cts/AudioFocusTest.java b/tests/tests/media/src/android/media/cts/AudioFocusTest.java
index e360ecb..bacc1cf 100644
--- a/tests/tests/media/src/android/media/cts/AudioFocusTest.java
+++ b/tests/tests/media/src/android/media/cts/AudioFocusTest.java
@@ -38,6 +38,10 @@
             .setUsage(AudioAttributes.USAGE_MEDIA)
             .setContentType(AudioAttributes.CONTENT_TYPE_MUSIC)
             .build();
+    private static final AudioAttributes ATTR_A11Y = new AudioAttributes.Builder()
+            .setUsage(AudioAttributes.USAGE_ASSISTANCE_ACCESSIBILITY)
+            .setContentType(AudioAttributes.CONTENT_TYPE_SPEECH)
+            .build();
 
 
     public void testInvalidAudioFocusRequestDelayNoListener() throws Exception {
@@ -175,12 +179,39 @@
                 true /*with handler*/);
     }
 
+    public void testAudioFocusRequestForceDuckNotA11y() throws Exception {
+        // verify a request that is "force duck"'d still causes loss of focus because it doesn't
+        // come from an A11y service, and requests are from same uid
+        final AudioAttributes[] attributes = { ATTR_MEDIA, ATTR_A11Y };
+        doTestTwoPlayersGainLoss(AudioManager.AUDIOFOCUS_GAIN_TRANSIENT_MAY_DUCK, attributes,
+                false /*no handler*/, true /* forceDucking */);
+    }
+
+    //-----------------------------------
+    // Test utilities
+
     /**
      * Test focus request and abandon between two focus owners
      * @param gainType focus gain of the focus owner on top (== 2nd focus requester)
      */
     private void doTestTwoPlayersGainLoss(int gainType, AudioAttributes[] attributes,
             boolean useHandlerInListener) throws Exception {
+        doTestTwoPlayersGainLoss(gainType, attributes, useHandlerInListener,
+                false /*forceDucking*/);
+    }
+
+    /**
+     * Same as {@link #doTestTwoPlayersGainLoss(int, AudioAttributes[], boolean)} with forceDucking
+     *   set to false.
+     * @param gainType
+     * @param attributes
+     * @param useHandlerInListener
+     * @param forceDucking value used for setForceDucking in request for focus requester at top of
+     *   stack (second requester in test).
+     * @throws Exception
+     */
+    private void doTestTwoPlayersGainLoss(int gainType, AudioAttributes[] attributes,
+            boolean useHandlerInListener, boolean forceDucking) throws Exception {
         final int NB_FOCUS_OWNERS = 2;
         if (NB_FOCUS_OWNERS != attributes.length) {
             throw new IllegalArgumentException("Invalid test: invalid number of attributes");
@@ -216,15 +247,18 @@
         try {
             for (int i = 0 ; i < NB_FOCUS_OWNERS ; i++) {
                 focusListeners[i] = new FocusChangeListener();
+                final boolean forceDuck = i == NB_FOCUS_OWNERS - 1 ? forceDucking : false;
                 if (h != null) {
                     focusRequests[i] = new AudioFocusRequest.Builder(focusGains[i])
                             .setAudioAttributes(attributes[i])
                             .setOnAudioFocusChangeListener(focusListeners[i], h /*handler*/)
+                            .setForceDucking(forceDuck)
                             .build();
                 } else {
                     focusRequests[i] = new AudioFocusRequest.Builder(focusGains[i])
                             .setAudioAttributes(attributes[i])
                             .setOnAudioFocusChangeListener(focusListeners[i])
+                            .setForceDucking(forceDuck)
                             .build();
                 }
             }
diff --git a/tests/tests/media/src/android/media/cts/AudioManagerTest.java b/tests/tests/media/src/android/media/cts/AudioManagerTest.java
index 3ca6c45..954c331 100644
--- a/tests/tests/media/src/android/media/cts/AudioManagerTest.java
+++ b/tests/tests/media/src/android/media/cts/AudioManagerTest.java
@@ -1499,6 +1499,7 @@
             Log.i(TAG, "deviceId:" + microphone.getDescription());
             Log.i(TAG, "portId:" + microphone.getId());
             Log.i(TAG, "type:" + microphone.getType());
+            Log.i(TAG, "address:" + microphone.getAddress());
             Log.i(TAG, "deviceLocation:" + microphone.getLocation());
             Log.i(TAG, "deviceGroup:" + microphone.getGroup()
                     + " index:" + microphone.getIndexInTheGroup());
diff --git a/tests/tests/media/src/android/media/cts/AudioRecordTest.java b/tests/tests/media/src/android/media/cts/AudioRecordTest.java
index 6474c26..45b166b 100644
--- a/tests/tests/media/src/android/media/cts/AudioRecordTest.java
+++ b/tests/tests/media/src/android/media/cts/AudioRecordTest.java
@@ -844,6 +844,7 @@
         Log.i(TAG, "deviceId:" + microphone.getDescription());
         Log.i(TAG, "portId:" + microphone.getId());
         Log.i(TAG, "type:" + microphone.getType());
+        Log.i(TAG, "address:" + microphone.getAddress());
         Log.i(TAG, "deviceLocation:" + microphone.getLocation());
         Log.i(TAG, "deviceGroup:" + microphone.getGroup()
             + " index:" + microphone.getIndexInTheGroup());
diff --git a/tests/tests/media/src/android/media/cts/DecoderTest.java b/tests/tests/media/src/android/media/cts/DecoderTest.java
index eae9d51..aae53fc 100755
--- a/tests/tests/media/src/android/media/cts/DecoderTest.java
+++ b/tests/tests/media/src/android/media/cts/DecoderTest.java
@@ -2066,18 +2066,14 @@
         try {
             if (false) {
                 // change to force testing software codecs
-                if (mime.contains("avc")) {
-                    return MediaCodec.createByCodecName("OMX.google.h264.decoder");
-                } else if (mime.contains("hevc")) {
-                    return MediaCodec.createByCodecName("OMX.google.hevc.decoder");
-                } else if (mime.contains("3gpp")) {
-                    return MediaCodec.createByCodecName("OMX.google.h263.decoder");
-                } else if (mime.contains("mp4v")) {
-                    return MediaCodec.createByCodecName("OMX.google.mpeg4.decoder");
-                } else if (mime.contains("vp8")) {
-                    return MediaCodec.createByCodecName("OMX.google.vp8.decoder");
-                } else if (mime.contains("vp9")) {
-                    return MediaCodec.createByCodecName("OMX.google.vp9.decoder");
+                MediaFormat format = new MediaFormat();
+                format.setString(MediaFormat.KEY_MIME, mime);
+                String[] codecs =
+                    MediaUtils.getDecoderNames(Boolean.TRUE /* isGoog */, format);
+                if (codecs.length > 0) {
+                    return MediaCodec.createByCodecName(codecs[0]);
+                } else {
+                    return null;
                 }
             }
             return MediaCodec.createDecoderByType(mime);
@@ -2950,4 +2946,3 @@
         return pm.hasSystemFeature(PackageManager.FEATURE_VR_MODE_HIGH_PERFORMANCE);
     }
 }
-
diff --git a/tests/tests/media/src/android/media/cts/DecoderTestAacDrc.java b/tests/tests/media/src/android/media/cts/DecoderTestAacDrc.java
index 997967c..86615f5 100755
--- a/tests/tests/media/src/android/media/cts/DecoderTestAacDrc.java
+++ b/tests/tests/media/src/android/media/cts/DecoderTestAacDrc.java
@@ -138,6 +138,51 @@
         checkClipping(decSamples, decParams, 248.0f /* Hz */);
     }
 
+    /**
+     * Default decoder target level.
+     * The actual default value used by the decoder can differ between platforms, or even devices,
+     * but tests will measure energy relative to this value.
+     */
+    public static final int DEFAULT_DECODER_TARGET_LEVEL = 64; // -16.0 dBFs
+
+    /**
+     * Test USAC decoder with different target loudness levels
+     */
+    @Test
+    public void testDecodeUsacLoudnessM4a() throws Exception {
+        Log.v(TAG, "START testDecodeUsacLoudnessM4a");
+
+        // test default loudness
+        // decoderTargetLevel = 64 --> target output level = -16.0 dBFs
+        try {
+            checkUsacLoudness(DEFAULT_DECODER_TARGET_LEVEL, 1, 1.0f);
+        } catch (Exception e) {
+            Log.v(TAG, "testDecodeUsacLoudnessM4a for default loudness failed");
+            throw new RuntimeException(e);
+        }
+
+        // test loudness boost
+        // decoderTargetLevel = 40 --> target output level = -10.0 dBFs
+        // normFactor = 1/(10^(-6/10)) = 3.98f
+        //    where "-6" is the difference between the default level (-16), and -10 for this test
+        try {
+            checkUsacLoudness(40, 1, (float)(1.0f/Math.pow(10.0f, -6.0f/10.0f)));
+        } catch (Exception e) {
+            Log.v(TAG, "testDecodeUsacLoudnessM4a for loudness boost failed");
+            throw new RuntimeException(e);
+        }
+
+        // test loudness attenuation
+        // decoderTargetLevel = 96 --> target output level = -24.0 dBFs
+        // normFactor = 1/(10^(8/10)) = 0.15f
+        //     where -8 is the difference between the default level (-16), and -24 for this test
+        try {
+            checkUsacLoudness(96, 0, (float)(1.0f/Math.pow(10.0f, 8.0f/10.0f)));
+        } catch (Exception e) {
+            Log.v(TAG, "testDecodeUsacLoudnessM4a for loudness attenuation failed");
+            throw new RuntimeException(e);
+        }
+    }
 
     /**
      *  Internal utilities
@@ -259,28 +304,81 @@
         }
     }
 
+    /**
+     * USAC test DRC loudness
+     */
+    private void checkUsacLoudness(int decoderTargetLevel, int heavy, float normFactor)
+            throws Exception {
+        AudioParameter decParams = new AudioParameter();
+        DrcParams drcParams_def  = new DrcParams(127, 127, DEFAULT_DECODER_TARGET_LEVEL, 1);
+        DrcParams drcParams_test = new DrcParams(127, 127, decoderTargetLevel, heavy);
+
+        short[] decSamples_def = decodeToMemory(decParams, R.raw.noise_2ch_48khz_aot42_19_lufs_mp4,
+                -1, null, drcParams_def);
+        short[] decSamples_test = decodeToMemory(decParams, R.raw.noise_2ch_48khz_aot42_19_lufs_mp4,
+                -1, null, drcParams_test);
+
+        DecoderTestXheAac decTesterXheAac = new DecoderTestXheAac();
+        float[] nrg_def  = decTesterXheAac.checkEnergyUSAC(decSamples_def, decParams, 2, 1);
+        float[] nrg_test = decTesterXheAac.checkEnergyUSAC(decSamples_test, decParams, 2, 1);
+
+        float[] nrgThreshold = {2602510595620.0f, 2354652443657.0f};
+
+        // Check default loudness behavior
+        if (nrg_def[0] > nrgThreshold[0] || nrg_def[0] < nrgThreshold[1]) {
+            throw new Exception("Default loudness behavior not as expected");
+        }
+
+        float nrgRatio = nrg_def[0]/nrg_test[0];
+
+        // Check for loudness boost/attenuation if decoderTargetLevel deviates from default value
+        // used in these tests (note that the default target level can change from platform
+        // to platform, or device to device)
+        if ((decoderTargetLevel < DEFAULT_DECODER_TARGET_LEVEL) // boosted loudness
+                && (nrg_def[0] > nrg_test[0])) {
+            throw new Exception("Signal not attenuated");
+        } else if ((decoderTargetLevel > DEFAULT_DECODER_TARGET_LEVEL) // attenuated loudness
+                && (nrg_def[0] < nrg_test[0])) {
+            throw new Exception("Signal not boosted");
+        }
+        nrgRatio = nrgRatio * normFactor;
+
+        // Check whether loudness behavior is as expected
+        if (nrgRatio > 1.05f || nrgRatio < 0.95f ){
+            throw new Exception("Loudness behavior not as expected");
+        }
+    }
+
 
     /**
-     *  Class handling all MPEG-4 Dynamic Range Control (DRC) parameter relevant for testing
+     *  Class handling all MPEG-4 and MPEG-D Dynamic Range Control (DRC) parameter relevant for testing
      */
-    private class DrcParams {
-        int boost;                          // scaling of boosting gains
-        int cut;                            // scaling of compressing gains
-        int decoderTargetLevel;             // desired target output level (for normalization)
-        int heavy;                          // en-/disable heavy compression
+    protected static class DrcParams {
+        int mBoost;                          // scaling of boosting gains
+        int mCut;                            // scaling of compressing gains
+        int mDecoderTargetLevel;             // desired target output level (for normalization)
+        int mHeavy;                          // en-/disable heavy compression
+        int mEffectType;                     // MPEG-D DRC Effect Type
 
         public DrcParams() {
-            this.boost = 127;               // no scaling
-            this.cut = 127;                 // no scaling
-            this.decoderTargetLevel = 64;   // -16.0 dBFs
-            this.heavy = 1;                 // enabled
+            mBoost = 127;               // no scaling
+            mCut   = 127;               // no scaling
+            mHeavy = 1;                 // enabled
         }
 
         public DrcParams(int boost, int cut, int decoderTargetLevel, int heavy) {
-            this.boost = boost;
-            this.cut = cut;
-            this.decoderTargetLevel = decoderTargetLevel;
-            this.heavy = heavy;
+            mBoost = boost;
+            mCut = cut;
+            mDecoderTargetLevel = decoderTargetLevel;
+            mHeavy = heavy;
+        }
+
+        public DrcParams(int boost, int cut, int decoderTargetLevel, int heavy, int effectType) {
+            mBoost = boost;
+            mCut = cut;
+            mDecoderTargetLevel = decoderTargetLevel;
+            mHeavy = heavy;
+            mEffectType = effectType;
         }
     }
 
@@ -319,11 +417,13 @@
 
         // set DRC parameters
         if (drcParams != null) {
-            configFormat.setInteger(MediaFormat.KEY_AAC_DRC_BOOST_FACTOR, drcParams.boost);
-            configFormat.setInteger(MediaFormat.KEY_AAC_DRC_ATTENUATION_FACTOR, drcParams.cut);
-            configFormat.setInteger(MediaFormat.KEY_AAC_DRC_TARGET_REFERENCE_LEVEL,
-                    drcParams.decoderTargetLevel);
-            configFormat.setInteger(MediaFormat.KEY_AAC_DRC_HEAVY_COMPRESSION, drcParams.heavy);
+            configFormat.setInteger(MediaFormat.KEY_AAC_DRC_BOOST_FACTOR, drcParams.mBoost);
+            configFormat.setInteger(MediaFormat.KEY_AAC_DRC_ATTENUATION_FACTOR, drcParams.mCut);
+            if (drcParams.mDecoderTargetLevel != 0) {
+                configFormat.setInteger(MediaFormat.KEY_AAC_DRC_TARGET_REFERENCE_LEVEL,
+                        drcParams.mDecoderTargetLevel);
+            }
+            configFormat.setInteger(MediaFormat.KEY_AAC_DRC_HEAVY_COMPRESSION, drcParams.mHeavy);
         }
         Log.v(localTag, "configuring with " + configFormat);
         codec.configure(configFormat, null /* surface */, null /* crypto */, 0 /* flags */);
diff --git a/tests/tests/media/src/android/media/cts/DecoderTestXheAac.java b/tests/tests/media/src/android/media/cts/DecoderTestXheAac.java
new file mode 100755
index 0000000..cc294a9
--- /dev/null
+++ b/tests/tests/media/src/android/media/cts/DecoderTestXheAac.java
@@ -0,0 +1,895 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.media.cts;
+
+import android.media.cts.R;
+
+import android.app.Instrumentation;
+import android.content.res.AssetFileDescriptor;
+import android.content.res.Resources;
+import android.media.cts.DecoderTest.AudioParameter;
+import android.media.cts.DecoderTestAacDrc.DrcParams;
+import android.media.MediaCodec;
+import android.media.MediaCodecInfo;
+import android.media.MediaCodecInfo.CodecCapabilities;
+import android.media.MediaExtractor;
+import android.media.MediaFormat;
+import android.support.test.InstrumentationRegistry;
+import android.util.Log;
+
+import com.android.compatibility.common.util.CtsAndroidTestCase;
+
+import static org.junit.Assert.*;
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+
+import java.io.IOException;
+import java.nio.ByteBuffer;
+import java.util.Arrays;
+import java.util.List;
+
+public class DecoderTestXheAac {
+    private static final String TAG = "DecoderTestXheAac";
+
+    private Resources mResources;
+
+    @Before
+    public void setUp() throws Exception {
+        final Instrumentation inst = InstrumentationRegistry.getInstrumentation();
+        assertNotNull(inst);
+        mResources = inst.getContext().getResources();
+    }
+
+    /**
+     * Verify the correct decoding of USAC bitstreams with different MPEG-D DRC effect types.
+     */
+    @Test
+    public void testDecodeUsacDrcEffectTypeM4a() throws Exception {
+        Log.v(TAG, "START testDecodeUsacDrcEffectTypeM4a");
+
+        // test DRC effectTypeID 1 "NIGHT"
+        // L -3dB -> normalization factor = 1/(10^(-3/10)) = 0.5011f
+        // R +3dB -> normalization factor = 1/(10^( 3/10)) = 1.9952f
+        try {
+            checkUsacDrcEffectType(1, 0.5011f, 1.9952f, "Night", 2, 0);
+        } catch (Exception e) {
+            Log.v(TAG, "testDecodeUsacDrcEffectTypeM4a effect type Night failed");
+            throw new RuntimeException(e);
+        }
+
+        // test DRC effectTypeID 2 "NOISY"
+        // L +3dB -> normalization factor = 1/(10^( 3/10)) = 1.9952f
+        // R -6dB -> normalization factor = 1/(10^(-6/10)) = 0.2511f
+        try {
+            checkUsacDrcEffectType(2, 1.9952f, 0.2511f, "Noisy", 2, 0);
+        } catch (Exception e) {
+            Log.v(TAG, "testDecodeUsacDrcEffectTypeM4a effect type Noisy failed");
+            throw new RuntimeException(e);
+        }
+
+        // test DRC effectTypeID 3 "LIMITED"
+        // L -6dB -> normalization factor = 1/(10^(-6/10)) = 0.2511f
+        // R +6dB -> normalization factor = 1/(10^( 6/10)) = 3.9810f
+        try {
+            checkUsacDrcEffectType(3, 0.2511f, 3.9810f, "Limited", 2, 0);
+        } catch (Exception e) {
+            Log.v(TAG, "testDecodeUsacDrcEffectTypeM4a effect type Limited failed");
+            throw new RuntimeException(e);
+        }
+
+        // test DRC effectTypeID 6 "GENERAL"
+        // L +6dB -> normalization factor = 1/(10^( 6/10)) = 3.9810f
+        // R -3dB -> normalization factor = 1/(10^(-3/10)) = 0.5011f
+        try {
+            checkUsacDrcEffectType(6, 3.9810f, 0.5011f, "General", 2, 0);
+        } catch (Exception e) {
+            Log.v(TAG, "testDecodeUsacDrcEffectTypeM4a effect type General failed");
+            throw new RuntimeException(e);
+        }
+
+        // test DRC effectTypeID 1 "NIGHT"
+        // L    -6dB -> normalization factor = 1/(10^(-6/10)) = 0.2511f
+        // R    +6dB -> normalization factor = 1/(10^( 6/10)) = 3.9810f
+        // mono -6dB -> normalization factor = 1/(10^(-6/10)) = 0.2511f
+        try {
+            checkUsacDrcEffectType(1, 0.2511f, 3.9810f, "Night", 2, 1);
+        } catch (Exception e) {
+            Log.v(TAG, "testDecodeUsacDrcEffectTypeM4a FAILED!");
+            throw new RuntimeException(e);
+        }
+        try {
+            checkUsacDrcEffectType(1, 0.2511f, 0.0f, "Night", 1, 1);
+        } catch (Exception e) {
+            Log.v(TAG, "testDecodeUsacDrcEffectTypeM4a FAILED!");
+            throw new RuntimeException(e);
+        }
+
+        // test DRC effectTypeID 2 "NOISY"
+        // L    +6dB -> normalization factor = 1/(10^( 6/10))   = 3.9810f
+        // R    -9dB -> normalization factor = 1/(10^(-9/10))  = 0.1258f
+        // mono +6dB -> normalization factor = 1/(10^( 6/10))   = 3.9810f
+        try {
+            checkUsacDrcEffectType(2, 3.9810f, 0.1258f, "Noisy", 2, 1);
+        } catch (Exception e) {
+            Log.v(TAG, "testDecodeUsacDrcEffectTypeM4a FAILED!");
+            throw new RuntimeException(e);
+        }
+        try {
+            checkUsacDrcEffectType(2, 3.9810f, 0.0f, "Noisy", 1, 1);
+        } catch (Exception e) {
+            Log.v(TAG, "testDecodeUsacDrcEffectTypeM4a FAILED!");
+            throw new RuntimeException(e);
+        }
+
+        // test DRC effectTypeID 3 "LIMITED"
+        // L    -9dB -> normalization factor = 1/(10^(-9/10)) = 0.1258f
+        // R    +9dB -> normalization factor = 1/(10^( 9/10)) = 7.9432f
+        // mono -9dB -> normalization factor = 1/(10^(-9/10)) = 0.1258f
+        try {
+            checkUsacDrcEffectType(3, 0.1258f, 7.9432f, "Limited", 2, 1);
+        } catch (Exception e) {
+            Log.v(TAG, "testDecodeUsacDrcEffectTypeM4a FAILED!");
+            throw new RuntimeException(e);
+        }
+        try {
+            checkUsacDrcEffectType(3, 0.1258f, 0.0f, "Limited", 1, 1);
+        } catch (Exception e) {
+            Log.v(TAG, "testDecodeUsacDrcEffectTypeM4a FAILED!");
+            throw new RuntimeException(e);
+        }
+
+        // test DRC effectTypeID 6 "GENERAL"
+        // L    +9dB -> normalization factor = 1/(10^( 9/10)) = 7.9432f
+        // R    -6dB -> normalization factor = 1/(10^(-6/10))  = 0.2511f
+        // mono +9dB -> normalization factor = 1/(10^( 9/10)) = 7.9432f
+        try {
+            checkUsacDrcEffectType(6, 7.9432f, 0.2511f, "General", 2, 1);
+        } catch (Exception e) {
+            Log.v(TAG, "testDecodeUsacDrcEffectTypeM4a FAILED!");
+            throw new RuntimeException(e);
+        }
+        try {
+            checkUsacDrcEffectType(6, 7.9432f, 0.0f, "General", 1, 1);
+        } catch (Exception e) {
+            Log.v(TAG, "testDecodeUsacDrcEffectTypeM4a FAILED!");
+            throw new RuntimeException(e);
+        }
+    }
+
+    /**
+     * Verify the correct decoding of USAC bitstreams with config changes.
+     */
+    @Test
+    public void testDecodeUsacStreamSwitchingM4a() throws Exception {
+        Log.v(TAG, "START testDecodeUsacStreamSwitchingM4a");
+
+        // Stereo
+        // switch between SBR ratios and stereo modes
+        try {
+            checkUsacStreamSwitching(2.5459829E12f, 2,
+            R.raw.noise_2ch_44_1khz_aot42_19_lufs_config_change_mp4);
+        } catch (Exception e) {
+            Log.v(TAG, "testDecodeUsacStreamSwitchingM4a FAILED!");
+            throw new RuntimeException(e);
+        }
+
+        // Mono
+        // switch between SBR ratios and stereo modes
+        try {
+            checkUsacStreamSwitching(2.24669126E12f, 1,
+            R.raw.noise_1ch_38_4khz_aot42_19_lufs_config_change_mp4);
+        } catch (Exception e) {
+            Log.v(TAG, "testDecodeUsacStreamSwitchingM4a FAILED!");
+            throw new RuntimeException(e);
+        }
+
+        // Stereo
+        // switch between USAC modes
+        try {
+            checkUsacStreamSwitching(2.1E12f, 2,
+            R.raw.noise_2ch_35_28khz_aot42_19_lufs_drc_config_change_mp4);
+        } catch (Exception e) {
+            Log.v(TAG, "testDecodeUsacStreamSwitchingM4a FAILED!");
+            throw new RuntimeException(e);
+        }
+
+        // Mono
+        // switch between USAC modes
+        try {
+            checkUsacStreamSwitching(1.7E12f, 1,
+            R.raw.noise_1ch_29_4khz_aot42_19_lufs_drc_config_change_mp4);
+        } catch (Exception e) {
+            Log.v(TAG, "testDecodeUsacStreamSwitchingM4a FAILED!");
+            throw new RuntimeException(e);
+        }
+    }
+
+    /**
+     * Verify the correct decoding of USAC bitstreams with various sampling rates.
+     */
+    @Test
+    public void testDecodeUsacSamplingRatesM4a() throws Exception {
+        Log.v(TAG, "START testDecodeUsacSamplingRatesM4a");
+
+        try {
+            checkUsacSamplingRate(R.raw.noise_2ch_08khz_aot42_19_lufs_mp4);
+            checkUsacSamplingRate(R.raw.noise_2ch_12khz_aot42_19_lufs_mp4);
+            checkUsacSamplingRate(R.raw.noise_2ch_22_05khz_aot42_19_lufs_mp4);
+            checkUsacSamplingRate(R.raw.noise_2ch_64khz_aot42_19_lufs_mp4);
+            checkUsacSamplingRate(R.raw.noise_2ch_88_2khz_aot42_19_lufs_mp4);
+            checkUsacSamplingRateWoLoudness(R.raw.noise_2ch_19_2khz_aot42_no_ludt_mp4);
+        } catch (Exception e) {
+            Log.v(TAG, "testDecodeUsacSamplingRatesM4a FAILED!");
+            throw new RuntimeException(e);
+        }
+    }
+
+
+    /**
+     *  Internal utilities
+     */
+
+    /**
+     * USAC test DRC Effect Type
+     */
+    private void checkUsacDrcEffectType(int effectTypeID, float normFactor_L, float normFactor_R,
+                 String effectTypeName, int nCh, int aggressiveDrc) throws Exception {
+        int testinput = -1;
+        AudioParameter decParams = new AudioParameter();
+        DrcParams drcParams_def  = new DrcParams(127, 127, 96, 0, -1);
+        DrcParams drcParams_test = new DrcParams(127, 127, 96, 0, effectTypeID);
+
+        if (aggressiveDrc == 0) {
+            testinput = R.raw.noise_2ch_32khz_aot42_19_lufs_drc_mp4;
+        } else {
+            if (nCh == 2) {
+                testinput = R.raw.noise_2ch_35_28khz_aot42_19_lufs_drc_config_change_mp4;
+            } else if (nCh == 1){
+                testinput = R.raw.noise_1ch_29_4khz_aot42_19_lufs_drc_config_change_mp4;
+            }
+        }
+
+        short[] decSamples_def  = decodeToMemory(decParams, testinput,
+                -1, null, drcParams_def);
+        short[] decSamples_test = decodeToMemory(decParams, testinput,
+                -1, null, drcParams_test);
+
+        float[] nrg_def  = checkEnergyUSAC(decSamples_def, decParams, nCh, 1, 0);
+        float[] nrg_test = checkEnergyUSAC(decSamples_test, decParams, nCh, 1, 1);
+
+        if (nCh == 2) {
+            float nrgRatio_L = (nrg_test[1]/nrg_def[1])/normFactor_L;
+            float nrgRatio_R = (nrg_test[2]/nrg_def[2])/normFactor_R;
+            if ((nrgRatio_R > 1.05f || nrgRatio_R < 0.95f) 
+                    || (nrgRatio_L > 1.05f || nrgRatio_L < 0.95f) ){
+                throw new Exception("DRC Effect Type '" + effectTypeName + "' not as expected");
+            }
+        } else if (nCh == 1){
+            float nrgRatio_L = (nrg_test[0]/nrg_def[0])/normFactor_L;
+            if (nrgRatio_L > 1.05f || nrgRatio_L < 0.95f){
+                throw new Exception("DRC Effect Type '" + effectTypeName + "' not as expected");
+            }
+        }
+    }
+
+    /**
+     * USAC test stream switching
+     */
+    private void checkUsacStreamSwitching(float nrg_ref, int encNch, int testinput) throws Exception
+    {
+        AudioParameter decParams = new AudioParameter();
+        DrcParams drcParams      = new DrcParams(127, 127, 64, 0, -1);
+
+        // Check stereo stream switching
+        short[] decSamples = decodeToMemory(decParams, testinput,
+                -1, null, drcParams);
+        float[] nrg = checkEnergyUSAC(decSamples, decParams, encNch, 1);
+
+        float nrgRatio = nrg[0] / nrg_ref;
+
+        // Check if energy levels are within 15% of the reference
+        // Energy drops within the decoded stream are checked by checkEnergyUSAC() within every
+        // 250ms interval
+        if (nrgRatio > 1.15f || nrgRatio < 0.85f ) {
+            throw new Exception("Config switching not as expected");
+        }
+    }
+
+    /**
+     * USAC test sampling rate
+     */
+    private void checkUsacSamplingRate(int testinput) throws Exception {
+        AudioParameter decParams  = new AudioParameter();
+        DrcParams drcParams_def   = new DrcParams(127, 127, 64, 0, -1);
+        DrcParams drcParams_test  = new DrcParams(127, 127, 96, 0, -1);
+
+        short[] decSamples_def  = decodeToMemory(decParams, testinput,
+                -1, null, drcParams_def);
+        short[] decSamples_test = decodeToMemory(decParams, testinput,
+                -1, null, drcParams_test);
+
+        float[] nrg_def  = checkEnergyUSAC(decSamples_def, decParams, 2, 1);
+        float[] nrg_test = checkEnergyUSAC(decSamples_test, decParams, 2, 1);
+
+        float nrgRatio = nrg_def[0]/nrg_test[0];
+
+        // normFactor = 1/(10^(-8/10)) = 6.3f
+        nrgRatio = nrgRatio / 6.3f;
+
+        // Check whether behavior is as expected
+        if (nrgRatio > 1.05f || nrgRatio < 0.95f ){
+            throw new Exception("Sampling rate not supported");
+        }
+    }
+
+    /**
+     * USAC test sampling rate for streams without loudness application
+     */
+    private void checkUsacSamplingRateWoLoudness(int testinput) throws Exception {
+        AudioParameter decParams  = new AudioParameter();
+        DrcParams drcParams       = new DrcParams();
+
+        short[] decSamples = decodeToMemory(decParams, testinput,
+                -1, null, drcParams);
+
+        float[] nrg = checkEnergyUSAC(decSamples, decParams, 2, 1);
+
+        float nrg_ref  = 3.15766394E12f;
+        float nrgRatio = nrg_ref/nrg[0];
+
+        // Check whether behavior is as expected
+        if (nrgRatio > 1.05f || nrgRatio < 0.95f ){
+            throw new Exception("Sampling rate not supported");
+        }
+    }
+
+    /**
+     * Perform a segmented energy analysis on given audio signal samples and run several tests on
+     * the energy values.
+     *
+     * The main purpose is to verify whether a USAC decoder implementation applies Spectral Band
+     * Replication (SBR), Parametric Stereo (PS) and Dynamic Range Control (DRC) correctly. All
+     * tools are inherent parts to either the MPEG-D USAC audio codec or the MPEG-D DRC tool.
+     *
+     * In addition, this test can verify the correct decoding of multi-channel (e.g. 5.1 channel)
+     * streams or the creation of a downmixed signal.
+     *
+     * Note: This test procedure is not an MPEG Conformance Test and can not serve as a replacement.
+     *
+     * @param decSamples the decoded audio samples to be tested
+     * @param decParams the audio parameters of the given audio samples (decSamples)
+     * @param encNch the encoded number of audio channels (number of channels of the original
+     *               input)
+     * @param drcContext indicate to use test criteria applicable for DRC testing
+     * @return array of energies, at index 0: accumulated energy of all channels, and
+     *     index 1 and over contain the individual channel energies
+     * @throws RuntimeException
+     */
+    protected float[] checkEnergyUSAC(short[] decSamples, AudioParameter decParams,
+                                      int encNch, int drcContext)
+    {
+        final float[] nrg = checkEnergyUSAC(decSamples, decParams, encNch, drcContext,  0);
+        return nrg;
+    }
+
+    /**
+     * Same as {@link #checkEnergyUSAC(short[], AudioParameter, int, int)} but with DRC effec type
+     * @param decSamples
+     * @param decParams
+     * @param encNch
+     * @param drcContext
+     * @param drcApplied indicate if MPEG-D DRC Effect Type has been applied
+     * @return
+     * @throws RuntimeException
+     */
+    private float[] checkEnergyUSAC(short[] decSamples, AudioParameter decParams,
+                                    int encNch, int drcContext,  int drcApplied)
+            throws RuntimeException
+    {
+        String localTag = TAG + "#checkEnergyUSAC";
+
+        // the number of segments per block
+        final int nSegPerBlk = 4;
+        // the number of input channels
+        final int nCh = encNch;
+        // length of one (LB/HB) block [samples]
+        final int nBlkSmp = decParams.getSamplingRate();
+        // length of one segment [samples]
+        final int nSegSmp = nBlkSmp / nSegPerBlk;
+        // actual # samples per channel (total)
+        final int smplPerChan = decSamples.length / nCh;
+        // actual # samples per segment (all ch)
+        final int nSegSmpTot = nSegSmp * nCh;
+        // signal offset between chans [segments]
+        final int nSegChOffst = 2 * nSegPerBlk;
+        // // the number of channels to be analyzed
+        final int procNch = Math.min(nCh, encNch);
+        // all original configs with more than five channel have an LFE
+        final int encEffNch = (encNch > 5) ? encNch-1 : encNch;
+        // expected number of decoded audio samples
+        final int expSmplPerChan = Math.max(encEffNch, 2) * nSegChOffst * nSegSmp;
+        // flag telling that input is dmx signal
+        final boolean isDmx = nCh < encNch;
+        final float nrgRatioThresh = 0.0f;
+        // the num analyzed channels with signal
+        int effProcNch = procNch;
+
+        // get the signal offset by counting zero samples at the very beginning (over all channels)
+        // sample value threshold 4 signal search
+        final int zeroSigThresh = 1;
+        // receives the number of samples that are in front of the actual signal
+        int signalStart = smplPerChan;
+        // receives the number of null samples (per chan) at the very beginning
+        int noiseStart = signalStart;
+
+        for (int smpl = 0; smpl < decSamples.length; smpl++) {
+            int value = Math.abs(decSamples[smpl]);
+
+            if (value > 0 && noiseStart == signalStart) {
+                // store start of prepended noise (can be same as signalStart)
+                noiseStart = smpl / nCh;
+            }
+
+            if (value > zeroSigThresh) {
+                // store signal start offset [samples]
+                signalStart = smpl / nCh;
+                break;
+            }
+        }
+
+        signalStart = (signalStart > noiseStart+1) ? signalStart : noiseStart;
+
+        // check if the decoder reproduced a waveform or kept silent
+        assertTrue ("no signal found in any channel!", signalStart < smplPerChan);
+
+        // max num seg that fit into signal
+        final int totSeg = (smplPerChan - signalStart) / nSegSmp;
+        // max num relevant samples (per channel)
+        final int totSmp = nSegSmp * totSeg;
+
+        // check if the number of reproduced segments in the audio file is valid
+        assertTrue("no segments left to test after signal search", totSeg > 0);
+
+        // get the energies and the channel offsets by searching for the first segment above the
+        // energy threshold:
+        // ratio of zeroNrgThresh to the max nrg
+        final double zeroMaxNrgRatio = 0.001f;
+        // threshold to classify segment energies
+        double zeroNrgThresh = nSegSmp * nSegSmp;
+        // will store the max seg nrg over all ch
+        double totMaxNrg = 0.0f;
+        // array receiving the segment energies
+        double[][] nrg = new double[procNch][totSeg];
+        // array for channel offsets
+        int[] offset = new int[procNch];
+        // array receiving the segment energy status over all channels
+        boolean[] sigSeg = new boolean[totSeg];
+        // energy per channel
+        double[] nrgPerChannel = new double[procNch];
+        // return value: [0]: total energy of all channels
+        //               [1 ... procNch + 1]: energy of the individual channels
+        float[] nrgTotal = new float[procNch + 1];
+        // mapping array to sort channels
+        int[] chMap = new int[nCh];
+
+        // calculate the segmental energy for each channel
+        for (int ch = 0; ch < procNch; ch++) {
+            offset[ch] = -1;
+
+            for (int seg = 0; seg < totSeg; seg++) {
+                final int smpStart = (signalStart * nCh) + (seg * nSegSmpTot) + ch;
+                final int smpStop = smpStart + nSegSmpTot;
+
+                for (int smpl = smpStart; smpl < smpStop; smpl += nCh) {
+                    // accumulate total energy per channel
+                    nrgPerChannel[ch] += decSamples[smpl] * decSamples[smpl];
+                    // accumulate segment energy
+                    nrg[ch][seg] += nrgPerChannel[ch];
+                }
+
+                // store 1st segment (index) per channel which has energy above the threshold to get
+                // the ch offsets
+                if (nrg[ch][seg] > zeroNrgThresh && offset[ch] < 0) {
+                    offset[ch] = seg / nSegChOffst;
+                }
+
+                // store the max segment nrg over all ch
+                if (nrg[ch][seg] > totMaxNrg) {
+                    totMaxNrg = nrg[ch][seg];
+                }
+
+                // store whether the channel has energy in this segment
+                sigSeg[seg] |= nrg[ch][seg] > zeroNrgThresh;
+            }
+
+            // if one channel has no signal it is most probably the LFE the LFE is no
+            // effective channel
+            if (offset[ch] < 0) {
+                effProcNch -= 1;
+                offset[ch] = effProcNch;
+            }
+
+            // recalculate the zero signal threshold based on the 1st channels max energy for
+            // all subsequent checks
+            if (ch == 0) {
+                zeroNrgThresh = zeroMaxNrgRatio * totMaxNrg;
+            }
+        }
+
+        // check if the LFE is decoded properly
+        assertTrue("more than one LFE detected", effProcNch >= procNch - 1);
+
+        // check if the amount of samples is valid
+        assertTrue(String.format("less samples decoded than expected: %d < %d",
+                                 decSamples.length - (signalStart * nCh),
+                                 totSmp * effProcNch),
+                                 decSamples.length - (signalStart * nCh) >= totSmp * effProcNch);
+
+        // for multi-channel signals the only valid front channel orders
+        // are L, R, C or C, L, R (L=left, R=right, C=center)
+        if (procNch >= 5) {
+            final int[] frontChMap1 = {2, 0, 1};
+            final int[] frontChMap2 = {0, 1, 2};
+
+            // check if the channel mapping is valid
+            if (!(Arrays.equals(Arrays.copyOfRange(offset, 0, 3), frontChMap1)
+                    || Arrays.equals(Arrays.copyOfRange(offset, 0, 3), frontChMap2))) {
+                fail("wrong front channel mapping");
+            }
+        }
+
+        // create mapping table to address channels from front to back the LFE must be last
+        if (drcContext == 0) {
+            // check whether every channel occurs exactly once
+            for (int ch = 0; ch < effProcNch; ch++) {
+                int occurred = 0;
+
+                for (int idx = 0; idx < procNch; idx++) {
+                    if (offset[idx] == ch) {
+                        occurred += 1;
+                        chMap[ch] = idx;
+                    }
+                }
+
+                // check if one channel is mapped more than one time
+                assertTrue(String.format("channel %d occurs %d times in the mapping", ch, occurred),
+                        occurred == 1);
+            }
+        } else {
+            for (int ch = 0; ch < procNch; ch++) {
+                chMap[ch] = ch;
+            }
+        }
+
+        // reference min energy for the 1st ch; others will be compared against 1st
+        double refMinNrg = zeroNrgThresh;
+
+        // calculate total energy, min and max energy
+        for (int ch = 0; ch < procNch; ch++) {
+            // resolve channel mapping
+            int idx = chMap[ch];
+            // signal offset [segments]
+            final int ofst = offset[idx] * nSegChOffst;
+
+            if (ch <= effProcNch && ofst < totSeg) {
+                // the last segment that has energy
+                int nrgSegEnd;
+                // the number of segments with energy
+                int nrgSeg;
+
+                if (drcContext == 0) {
+
+                    // the first channel of a mono or stereo signal has full signal all others have
+                    // one LB + one HB block
+                    if ((encNch <= 2) && (ch == 0)) {
+                        nrgSeg = totSeg;
+                    } else {
+                        nrgSeg = Math.min(totSeg, (2 * nSegPerBlk) + ofst) - ofst;
+                    }
+                } else {
+                    nrgSeg = totSeg;
+                }
+
+                nrgSegEnd = ofst + nrgSeg;
+
+                // find min and max energy of all segments that should have signal
+                double minNrg = nrg[idx][ofst]; // channels minimum segment energy
+                double maxNrg = nrg[idx][ofst]; // channels maximum segment energy
+
+                // values of 1st segment already assigned
+                for (int seg = ofst + 1; seg < nrgSegEnd; seg++) {
+                    if (nrg[idx][seg] < minNrg) {
+                        minNrg = nrg[idx][seg];
+                    }
+
+                    if (nrg[idx][seg] > maxNrg) {
+                        maxNrg = nrg[idx][seg];
+                    }
+                }
+
+                // check if the energy of this channel is > 0
+                assertTrue(String.format("max energy of channel %d is zero", ch),maxNrg > 0.0f);
+
+                if (drcContext == 0) {
+                    // check the channels minimum energy >= refMinNrg
+                    assertTrue(String.format("channel %d has not enough energy", ch),
+                            minNrg >= refMinNrg);
+
+                    if (ch == 0) {
+                        // use 85% of 1st channels min energy as reference the other chs must meet
+                        refMinNrg = minNrg * 0.85f;
+                    } else if (isDmx && (ch == 1)) {
+                        // in case of downmixed signal the energy can be lower depending on the
+                        refMinNrg *= 0.50f;
+                    }
+
+                    // calculate and check the energy ratio
+                    final double nrgRatio = minNrg / maxNrg;
+
+                    // check if the threshold is exceeded
+                    assertTrue(String.format("energy ratio of channel %d below threshold", ch),
+                            nrgRatio >= nrgRatioThresh);
+
+                    if (!isDmx) {
+                        if (nrgSegEnd < totSeg) {
+                            // consider that some noise can extend into the subsequent segment
+                            // allow this to be at max 20% of the channels minimum energy
+                            assertTrue(
+                                    String.format("min energy after noise above threshold (%.2f)",
+                                    nrg[idx][nrgSegEnd]),
+                                    nrg[idx][nrgSegEnd] < minNrg * 0.20f);
+                            nrgSegEnd += 1;
+                        }
+                    } else {
+                        // ignore all subsequent segments in case of a downmixed signal
+                        nrgSegEnd = totSeg;
+                    }
+
+                    // zero-out the verified energies to simplify the subsequent check
+                    for (int seg = ofst; seg < nrgSegEnd; seg++) {
+                        nrg[idx][seg] = 0.0f;
+                    }
+
+                    // check zero signal parts
+                    for (int seg = 0; seg < totSeg; seg++) {
+                        assertTrue(String.format("segment %d in channel %d has signal where should "
+                                + "be none (%.2f)", seg, ch, nrg[idx][seg]),
+                                nrg[idx][seg] < zeroNrgThresh);
+                    }
+                }
+            }
+
+            // test whether each segment has energy in at least one channel
+            for (int seg = 0; seg < totSeg; seg++) {
+                assertTrue(String.format("no channel has energy in segment %d", seg), sigSeg[seg]);
+            }
+
+            nrgTotal[0]     += (float)nrgPerChannel[ch];
+            nrgTotal[ch + 1] = (float)nrgPerChannel[ch];
+        }
+
+        float errorMargin = 0.0f;
+        if (drcApplied == 0) {
+            errorMargin = 0.25f;
+        } else if (drcApplied == 1) {
+            errorMargin = 0.40f;
+        }
+
+        float totSegEnergy = 0.0f;
+        float[] segEnergy = new float[totSeg];
+        for (int seg = totSeg - 1; seg >= 0; seg--) {
+            if (seg != 0) {
+                for (int ch = 0; ch < nCh; ch++) {
+                    segEnergy[seg] += nrg[ch][seg] - nrg[ch][seg - 1];
+                }
+                totSegEnergy += segEnergy[seg];
+            } else {
+                for (int ch = 0; ch < nCh; ch++) {
+                    segEnergy[seg] += nrg[ch][seg];
+                }
+            }
+        }
+        float avgSegEnergy = totSegEnergy / (totSeg - 1);
+        for (int seg = 1; seg < totSeg; seg++) {
+            float energyRatio = segEnergy[seg] / avgSegEnergy;
+            if ((energyRatio > (1.0f + errorMargin) ) || (energyRatio < (1.0f - errorMargin) )) {
+                fail("Energy drop out");
+            }
+        }
+
+        // return nrgTotal: [0]: accumulated energy of all channels, [1 ... ] channel energies
+        return nrgTotal;
+    }
+
+    /**
+     * Decodes an compressed bitstream in the ISOBMFF into the RAM of the device.
+     *
+     * The decoder decodes compressed audio data as stored in the ISO Base Media File Format
+     * (ISOBMFF) aka .mp4/.m4a. The decoder is not reproducing the waveform but stores the decoded
+     * samples in the RAM of the device under test.
+     *
+     * @param audioParams the decoder parameter configuration
+     * @param testinput the compressed audio stream
+     * @param eossample the End-Of-Stream indicator
+     * @param timestamps the time stamps to decode
+     * @param drcParams the MPEG-D DRC decoder parameter configuration
+     * @throws RuntimeException
+     */
+    public short[] decodeToMemory(AudioParameter audioParams, int testinput,
+            int eossample, List<Long> timestamps, DrcParams drcParams)
+            throws IOException
+    {
+        // TODO: code is the same as in DecoderTest, differences are:
+        //          - addition of application of DRC parameters
+        //          - no need/use of resetMode, configMode
+        //       Split method so code can be shared
+
+        String localTag = TAG + "#decodeToMemory";
+        short [] decoded = new short[0];
+        int decodedIdx = 0;
+
+        AssetFileDescriptor testFd = mResources.openRawResourceFd(testinput);
+
+        MediaExtractor extractor;
+        MediaCodec codec;
+        ByteBuffer[] codecInputBuffers;
+        ByteBuffer[] codecOutputBuffers;
+
+        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/"));
+
+        MediaFormat configFormat = format;
+        codec = MediaCodec.createDecoderByType(mime);
+
+        // set DRC parameters
+        if (drcParams != null) {
+            configFormat.setInteger(MediaFormat.KEY_AAC_DRC_BOOST_FACTOR, drcParams.mBoost);
+            configFormat.setInteger(MediaFormat.KEY_AAC_DRC_ATTENUATION_FACTOR, drcParams.mCut);
+            if (drcParams.mDecoderTargetLevel != 0) {
+                configFormat.setInteger(MediaFormat.KEY_AAC_DRC_TARGET_REFERENCE_LEVEL,
+                        drcParams.mDecoderTargetLevel);
+            }
+            configFormat.setInteger(MediaFormat.KEY_AAC_DRC_HEAVY_COMPRESSION, drcParams.mHeavy);
+            if (drcParams.mEffectType != 0){
+                configFormat.setInteger(MediaFormat.KEY_AAC_DRC_EFFECT_TYPE,
+                        drcParams.mEffectType);
+            }
+        }
+
+        Log.v(localTag, "configuring with " + configFormat);
+        codec.configure(configFormat, null /* surface */, null /* crypto */, 0 /* flags */);
+
+        codec.start();
+        codecInputBuffers = codec.getInputBuffers();
+        codecOutputBuffers = codec.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;
+
+        // main decoding loop
+        while (!sawOutputEOS && noOutputCounter < 50) {
+            noOutputCounter++;
+            if (!sawInputEOS) {
+                int inputBufIndex = codec.dequeueInputBuffer(kTimeOutUs);
+
+                if (inputBufIndex >= 0) {
+                    ByteBuffer dstBuf = codecInputBuffers[inputBufIndex];
+
+                    int sampleSize =
+                        extractor.readSampleData(dstBuf, 0 /* offset */);
+
+                    long presentationTimeUs = 0;
+
+                    if (sampleSize < 0 && eossample > 0) {
+                        fail("test is broken: never reached eos sample");
+                    }
+
+                    if (sampleSize < 0) {
+                        Log.d(TAG, "saw input EOS.");
+                        sawInputEOS = true;
+                        sampleSize = 0;
+                    } else {
+                        if (samplecounter == eossample) {
+                            sawInputEOS = true;
+                        }
+                        samplecounter++;
+                        presentationTimeUs = extractor.getSampleTime();
+                    }
+
+                    codec.queueInputBuffer(
+                            inputBufIndex,
+                            0 /* offset */,
+                            sampleSize,
+                            presentationTimeUs,
+                            sawInputEOS ? MediaCodec.BUFFER_FLAG_END_OF_STREAM : 0);
+
+                    if (!sawInputEOS) {
+                        extractor.advance();
+                    }
+                }
+            }
+
+            int res = codec.dequeueOutputBuffer(info, kTimeOutUs);
+
+            if (res >= 0) {
+                //Log.d(TAG, "got frame, size " + info.size + "/" + info.presentationTimeUs);
+
+                if (info.size > 0) {
+                    noOutputCounter = 0;
+                    if (timestamps != null) {
+                        timestamps.add(info.presentationTimeUs);
+                    }
+                }
+
+                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();
+                }
+
+                codec.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 = codec.getOutputBuffers();
+
+                Log.d(TAG, "output buffers have changed.");
+            } else if (res == MediaCodec.INFO_OUTPUT_FORMAT_CHANGED) {
+                MediaFormat oformat = codec.getOutputFormat();
+                audioParams.setNumChannels(oformat.getInteger(MediaFormat.KEY_CHANNEL_COUNT));
+                audioParams.setSamplingRate(oformat.getInteger(MediaFormat.KEY_SAMPLE_RATE));
+                Log.d(TAG, "output format has changed to " + oformat);
+            } else {
+                Log.d(TAG, "dequeueOutputBuffer returned " + res);
+            }
+        }
+
+        if (noOutputCounter >= 50) {
+            fail("decoder stopped outputting data");
+        }
+
+        codec.stop();
+        codec.release();
+        return decoded;
+    }
+
+}
+
diff --git a/tests/tests/media/src/android/media/cts/EncodeVirtualDisplayWithCompositionTest.java b/tests/tests/media/src/android/media/cts/EncodeVirtualDisplayWithCompositionTest.java
index 813742a..6301258 100644
--- a/tests/tests/media/src/android/media/cts/EncodeVirtualDisplayWithCompositionTest.java
+++ b/tests/tests/media/src/android/media/cts/EncodeVirtualDisplayWithCompositionTest.java
@@ -58,6 +58,8 @@
 import android.view.WindowManager;
 import android.widget.FrameLayout;
 import android.widget.ImageView;
+import android.widget.TableLayout;
+import android.widget.TableRow;
 import android.widget.TextView;
 
 import android.media.cts.R;
@@ -67,7 +69,9 @@
 import java.nio.FloatBuffer;
 import java.nio.IntBuffer;
 import java.util.ArrayList;
+import java.util.Arrays;
 import java.util.HashMap;
+import java.util.List;
 import java.util.concurrent.Semaphore;
 import java.util.concurrent.TimeUnit;
 import java.util.concurrent.atomic.AtomicInteger;
@@ -89,8 +93,8 @@
     private static final long DEFAULT_WAIT_TIMEOUT_US = 3000000;
 
     private static final int COLOR_RED =  makeColor(100, 0, 0);
-    private static final int COLOR_BLUE =  makeColor(0, 100, 0);
-    private static final int COLOR_GREEN =  makeColor(0, 0, 100);
+    private static final int COLOR_GREEN =  makeColor(0, 100, 0);
+    private static final int COLOR_BLUE =  makeColor(0, 0, 100);
     private static final int COLOR_GREY =  makeColor(100, 100, 100);
 
     private static final int BITRATE_1080p = 20000000;
@@ -151,6 +155,31 @@
         }
     }
 
+    public void testRendering800x480Rotated90() throws Throwable {
+        testRendering800x480Rotated(90);
+    }
+
+    public void testRendering800x480Rotated180() throws Throwable {
+        testRendering800x480Rotated(180);
+    }
+
+    public void testRendering800x480Rotated270() throws Throwable {
+        testRendering800x480Rotated(270);
+    }
+
+    public void testRendering800x480Rotated360() throws Throwable {
+        testRendering800x480Rotated(360);
+    }
+
+    private void testRendering800x480Rotated(int degrees) throws Throwable {
+        Log.i(TAG, "testRendering800x480Rotated " + degrees);
+        if (isConcurrentEncodingDecodingSupported(800, 480, BITRATE_800x480)) {
+            runTestRenderingInSeparateThread(800, 480, false, false, degrees);
+        } else {
+            Log.i(TAG, "SKIPPING testRendering800x480Rotated" + degrees + ":codec not supported");
+        }
+    }
+
     public void testRenderingMaxResolutionLocally() throws Throwable {
         Log.i(TAG, "testRenderingMaxResolutionLocally");
         Size maxRes = checkMaxConcurrentEncodingDecodingResolution();
@@ -209,11 +238,17 @@
      */
     private void runTestRenderingInSeparateThread(final int w, final int h,
             final boolean runRemotely, final boolean multipleWindows) throws Throwable {
+        runTestRenderingInSeparateThread(w, h, runRemotely, multipleWindows, /* degrees */ 0);
+    }
+
+    private void runTestRenderingInSeparateThread(final int w, final int h,
+            final boolean runRemotely, final boolean multipleWindows, final int degrees)
+            throws Throwable {
         mTestException = null;
         Thread renderingThread = new Thread(new Runnable() {
             public void run() {
                 try {
-                    doTestRenderingOutput(w, h, runRemotely, multipleWindows);
+                    doTestRenderingOutput(w, h, runRemotely, multipleWindows, degrees);
                 } catch (Throwable t) {
                     t.printStackTrace();
                     mTestException = t;
@@ -228,8 +263,8 @@
         }
     }
 
-    private void doTestRenderingOutput(int w, int h, boolean runRemotely, boolean multipleWindows)
-            throws Throwable {
+    private void doTestRenderingOutput(int w, int h, boolean runRemotely, boolean multipleWindows,
+            int degrees) throws Throwable {
         if (DBG) {
             Log.i(TAG, "doTestRenderingOutput for w:" + w + " h:" + h);
         }
@@ -237,6 +272,9 @@
             mIsQuitting = false;
             mDecoder = MediaCodec.createDecoderByType(MIME_TYPE);
             MediaFormat decoderFormat = MediaFormat.createVideoFormat(MIME_TYPE, w, h);
+            if (degrees != 0) {
+                decoderFormat.setInteger(MediaFormat.KEY_ROTATION, degrees);
+            }
             mDecodingSurface = new OutputSurface(w, h);
             mDecoder.configure(decoderFormat, mDecodingSurface.getSurface(), null, 0);
             mDecoder.start();
@@ -299,15 +337,18 @@
             }
 
             Renderer renderer = null;
+            Context context = getContext();
+            Surface windowSurface = compositor.getWindowSurface(multipleWindows? 1 : 0);
             if (runRemotely) {
-                mRemotePresentation = new RemoteVirtualDisplayPresentation(getContext(),
-                        compositor.getWindowSurface(multipleWindows? 1 : 0), w, h);
+                mRemotePresentation =
+                        new RemoteVirtualDisplayPresentation(context, windowSurface, w, h);
                 mRemotePresentation.connect();
                 mRemotePresentation.start();
                 renderer = mRemotePresentation;
             } else {
-                mLocalPresentation = new VirtualDisplayPresentation(getContext(),
-                        compositor.getWindowSurface(multipleWindows? 1 : 0), w, h);
+                mLocalPresentation = (degrees == 0)
+                        ? new VirtualDisplayPresentation(context, windowSurface, w, h)
+                        : new RotateVirtualDisplayPresentation(context, windowSurface, w, h);
                 mLocalPresentation.createVirtualDisplay();
                 mLocalPresentation.createPresentation();
                 renderer = mLocalPresentation;
@@ -316,10 +357,14 @@
             if (DBG) {
                 Log.i(TAG, "start rendering and check");
             }
-            renderColorAndCheckResult(renderer, w, h, COLOR_RED);
-            renderColorAndCheckResult(renderer, w, h, COLOR_BLUE);
-            renderColorAndCheckResult(renderer, w, h, COLOR_GREEN);
-            renderColorAndCheckResult(renderer, w, h, COLOR_GREY);
+            if (degrees == 0) {
+                renderColorAndCheckResult(renderer, w, h, COLOR_RED);
+                renderColorAndCheckResult(renderer, w, h, COLOR_BLUE);
+                renderColorAndCheckResult(renderer, w, h, COLOR_GREEN);
+                renderColorAndCheckResult(renderer, w, h, COLOR_GREY);
+            } else {
+                renderRotationAndCheckResult(renderer, w, h, degrees);
+            }
 
             mIsQuitting = true;
             if (runRemotely) {
@@ -376,6 +421,67 @@
         fail("Color did not match");
     }
 
+    private void renderRotationAndCheckResult(Renderer renderer, int w, int h,
+            int degrees) throws Exception {
+        BufferInfo info = new BufferInfo();
+        for (int i = 0; i < NUM_MAX_RETRY; i++) {
+            renderer.doRendering(-1);
+            int bufferIndex = mDecoder.dequeueOutputBuffer(info,  DEFAULT_WAIT_TIMEOUT_US);
+            if (DBG) {
+                Log.i(TAG, "decoder dequeueOutputBuffer returned " + bufferIndex);
+            }
+            if (bufferIndex < 0) {
+                continue;
+            }
+            mDecoder.releaseOutputBuffer(bufferIndex, true);
+            if (mDecodingSurface.checkForNewImage(IMAGE_WAIT_TIMEOUT_MS)) {
+                mDecodingSurface.drawImage();
+                if (checkRotatedFrameQuadrants(w, h, degrees)) {
+                    Log.i(TAG, "output rotated " + degrees + " degrees");
+                    return;
+                }
+            } else if(DBG) {
+                Log.i(TAG, "no rendering yet");
+            }
+        }
+        fail("Frame not properly rotated");
+    }
+
+    private boolean checkRotatedFrameQuadrants(int w, int h, int degrees) {
+        // Read a pixel from each quadrant of the surface.
+        int ww = w / 4;
+        int hh = h / 4;
+        // coords is ordered counter clockwise (note, gl 0,0 is bottom left)
+        int[][] coords = new int[][] {{ww, hh}, {ww * 3, hh}, {ww * 3, hh * 3}, {ww, hh * 3}};
+        List<Integer> expected = new ArrayList<>();
+        List<Integer> colors = Arrays.asList(
+                new Integer[] {COLOR_GREEN, COLOR_BLUE, COLOR_RED, COLOR_GREY});
+        expected.addAll(colors);
+        expected.addAll(colors);
+        int offset = (degrees / 90) % 4;
+        for (int i = 0; i < coords.length; i++) {
+            int[] c = coords[i];
+            int x = c[0];
+            int y = c[1];
+            GLES20.glReadPixels(x, y, 1, 1, GLES20.GL_RGBA, GLES20.GL_UNSIGNED_BYTE, mPixelBuf);
+            int r = mPixelBuf.get(0) & 0xff;
+            int g = mPixelBuf.get(1) & 0xff;
+            int b = mPixelBuf.get(2) & 0xff;
+            // adding the offset to rotate expected colors clockwise
+            int color = expected.get(offset + i);
+            int redExpected = (color >> 16) & 0xff;
+            int greenExpected = (color >> 8) & 0xff;
+            int blueExpected = color & 0xff;
+            Log.i(TAG, String.format("(%d,%d) expecting %d,%d,%d saw %d,%d,%d",
+                    x, y, redExpected, greenExpected, blueExpected, r, g, b));
+            if (!approxEquals(redExpected, r) || !approxEquals(greenExpected, g)
+                    || !approxEquals(blueExpected, b)) {
+                return false;
+            }
+        }
+        return true;
+    }
+
     private boolean checkSurfaceFrameColor(int w, int h, int color) {
         // Read a pixel from the center of the surface.  Might want to read from multiple points
         // and average them together.
@@ -1079,6 +1185,19 @@
         void doRendering(final int color) throws Exception;
     }
 
+    private static class RotateVirtualDisplayPresentation extends VirtualDisplayPresentation {
+
+        RotateVirtualDisplayPresentation(Context context, Surface surface, int w, int h) {
+            super(context, surface, w, h);
+        }
+
+        @Override
+        protected TestPresentationBase doCreatePresentation() {
+            return new TestRotatePresentation(mContext, mVirtualDisplay.getDisplay());
+        }
+
+    }
+
     private static class VirtualDisplayPresentation implements Renderer {
         protected final Context mContext;
         protected final Surface mSurface;
@@ -1196,6 +1315,50 @@
         }
     }
 
+    private static class TestRotatePresentation extends TestPresentationBase {
+        static final int[] kColors = new int[] {COLOR_GREY, COLOR_RED, COLOR_GREEN, COLOR_BLUE};
+        private final ImageView[] mQuadrants = new ImageView[4];
+
+        public TestRotatePresentation(Context outerContext, Display display) {
+            super(outerContext, display);
+        }
+
+        @Override
+        protected void onCreate(Bundle savedInstanceState) {
+            super.onCreate(savedInstanceState);
+            Context ctx = getContext();
+            TableLayout table = new TableLayout(ctx);
+            ViewGroup.LayoutParams fill = new ViewGroup.LayoutParams(
+                    ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT);
+            TableLayout.LayoutParams fillTable = new TableLayout.LayoutParams(
+                    ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT, 1f);
+            TableRow.LayoutParams fillRow = new TableRow.LayoutParams(
+                    ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT, 1f);
+            table.setLayoutParams(fill);
+            table.setStretchAllColumns(true);
+            TableRow rows[] = new TableRow[] {new TableRow(ctx), new TableRow(ctx)};
+            for (int i = 0; i < mQuadrants.length; i++) {
+                mQuadrants[i] = new ImageView(ctx);
+                mQuadrants[i].setImageDrawable(new ColorDrawable(kColors[i]));
+                rows[i / 2].addView(mQuadrants[i], fillRow);
+            }
+            for (TableRow row: rows) {
+                table.addView(row, fillTable);
+            }
+            setContentView(table);
+            Log.v(TAG, "setContentView(table)");
+        }
+
+        @Override
+        public void doRendering(int color) {
+            Log.v(TAG, "doRendering: ignoring color: " + Integer.toHexString(color));
+            for (int i = 0; i < mQuadrants.length; i++) {
+                mQuadrants[i].setImageDrawable(new ColorDrawable(kColors[i]));
+            }
+        }
+
+    }
+
     private static class TopWindowPresentation extends TestPresentationBase {
         private FrameLayout[] mWindowsLayout = new FrameLayout[MAX_NUM_WINDOWS];
         private CompositionTextureView[] mWindows = new CompositionTextureView[MAX_NUM_WINDOWS];
diff --git a/tests/tests/media/src/android/media/cts/HeifWriterTest.java b/tests/tests/media/src/android/media/cts/HeifWriterTest.java
index 08a6527..247a249 100644
--- a/tests/tests/media/src/android/media/cts/HeifWriterTest.java
+++ b/tests/tests/media/src/android/media/cts/HeifWriterTest.java
@@ -17,7 +17,10 @@
 package android.media.cts;
 
 import android.graphics.Bitmap;
+import android.graphics.BitmapFactory;
+import android.graphics.Color;
 import android.graphics.ImageFormat;
+import android.graphics.Rect;
 import android.media.MediaExtractor;
 import android.media.MediaFormat;
 import android.media.MediaMetadataRetriever;
@@ -63,12 +66,24 @@
     private static final boolean DEBUG = false;
     private static final boolean DUMP_YUV_INPUT = false;
 
-    private static byte[][] TEST_COLORS = {
+    private static byte[][] TEST_YUV_COLORS = {
             {(byte) 255, (byte) 0, (byte) 0},
             {(byte) 255, (byte) 0, (byte) 255},
             {(byte) 255, (byte) 255, (byte) 255},
             {(byte) 255, (byte) 255, (byte) 0},
     };
+    private static Color COLOR_BLOCK =
+            Color.valueOf(1.0f, 1.0f, 1.0f);
+    private static Color[] COLOR_BARS = {
+            Color.valueOf(0.0f, 0.0f, 0.0f),
+            Color.valueOf(0.0f, 0.0f, 0.64f),
+            Color.valueOf(0.0f, 0.64f, 0.0f),
+            Color.valueOf(0.0f, 0.64f, 0.64f),
+            Color.valueOf(0.64f, 0.0f, 0.0f),
+            Color.valueOf(0.64f, 0.0f, 0.64f),
+            Color.valueOf(0.64f, 0.64f, 0.0f),
+    };
+    private static int BORDER_WIDTH = 16;
 
     private static final String HEIFWRITER_INPUT = "heifwriter_input.heic";
     private static final int[] IMAGE_RESOURCES = new int[] {
@@ -243,7 +258,7 @@
         final boolean mUseGrid;
         final boolean mUseHandler;
         final int mMaxNumImages;
-        final int mNumImages;
+        final int mActualNumImages;
         final int mWidth;
         final int mHeight;
         final int mRotation;
@@ -253,14 +268,14 @@
         final Bitmap[] mBitmaps;
 
         TestConfig(int inputMode, boolean useGrid, boolean useHandler,
-                   int maxNumImages, int numImages, int width, int height,
+                   int maxNumImages, int actualNumImages, int width, int height,
                    int rotation, int quality,
                    String inputPath, String outputPath, Bitmap[] bitmaps) {
             mInputMode = inputMode;
             mUseGrid = useGrid;
             mUseHandler = useHandler;
             mMaxNumImages = maxNumImages;
-            mNumImages = numImages;
+            mActualNumImages = actualNumImages;
             mWidth = width;
             mHeight = height;
             mRotation = rotation;
@@ -363,7 +378,7 @@
                     + ", mUseGrid " + mUseGrid
                     + ", mUseHandler " + mUseHandler
                     + ", mMaxNumImages " + mMaxNumImages
-                    + ", mNumImages " + mNumImages
+                    + ", mNumImages " + mActualNumImages
                     + ", mWidth " + mWidth
                     + ", mHeight " + mHeight
                     + ", mRotation " + mRotation
@@ -373,10 +388,10 @@
         }
     }
 
-    private void doTest(TestConfig config) throws Exception {
-        int width = config.mWidth;
-        int height = config.mHeight;
-        int numImages = config.mNumImages;
+    private void doTest(final TestConfig config) throws Exception {
+        final int width = config.mWidth;
+        final int height = config.mHeight;
+        final int actualNumImages = config.mActualNumImages;
 
         mInputIndex = 0;
         HeifWriter heifWriter = null;
@@ -414,7 +429,7 @@
                     outputStream = new FileOutputStream(outputFile);
                 }
 
-                for (int i = 0; i < numImages; i++) {
+                for (int i = 0; i < actualNumImages; i++) {
                     if (DEBUG) Log.d(TAG, "fillYuvBuffer: " + i);
                     fillYuvBuffer(i, data, width, height, inputStream);
                     if (DUMP_YUV_INPUT) {
@@ -429,15 +444,15 @@
                 // how fast MediaCodec processes them, which is further dependent on how fast the
                 // MediaCodec callbacks are handled. We can't put draws on the same looper that
                 // handles MediaCodec callback, it will cause deadlock.
-                for (int i = 0; i < numImages; i++) {
+                for (int i = 0; i < actualNumImages; i++) {
                     if (DEBUG) Log.d(TAG, "drawFrame: " + i);
                     drawFrame(width, height);
                 }
                 heifWriter.setInputEndOfStreamTimestamp(
-                        1000 * computePresentationTime(numImages - 1));
+                        1000 * computePresentationTime(actualNumImages - 1));
             } else if (config.mInputMode == INPUT_MODE_BITMAP) {
                 Bitmap[] bitmaps = config.mBitmaps;
-                for (int i = 0; i < Math.min(bitmaps.length, numImages); i++) {
+                for (int i = 0; i < Math.min(bitmaps.length, actualNumImages); i++) {
                     if (DEBUG) Log.d(TAG, "addBitmap: " + i);
                     heifWriter.addBitmap(bitmaps[i]);
                     bitmaps[i].recycle();
@@ -445,8 +460,18 @@
             }
 
             heifWriter.stop(3000);
-            verifyResult(config.mOutputPath, width, height, config.mRotation, config.mUseGrid,
-                    Math.min(numImages, config.mMaxNumImages));
+            // The test sets the primary index to the last image.
+            // However, if we're testing early abort, the last image will not be
+            // present and the muxer is supposed to set it to 0 by default.
+            int expectedPrimary = config.mMaxNumImages - 1;
+            int expectedImageCount = config.mMaxNumImages;
+            if (actualNumImages < config.mMaxNumImages) {
+                expectedPrimary = 0;
+                expectedImageCount = actualNumImages;
+            }
+            verifyResult(config.mOutputPath, width, height, config.mRotation,
+                    expectedImageCount, expectedPrimary, config.mUseGrid,
+                    config.mInputMode == INPUT_MODE_SURFACE);
             if (DEBUG) Log.d(TAG, "finished: PASS");
         } finally {
             try {
@@ -479,7 +504,7 @@
         if (inputStream != null) {
             inputStream.read(data);
         } else {
-            byte[] color = TEST_COLORS[frameIndex % TEST_COLORS.length];
+            byte[] color = TEST_YUV_COLORS[frameIndex % TEST_YUV_COLORS.length];
             int sizeY = width * height;
             Arrays.fill(data, 0, sizeY, color[0]);
             Arrays.fill(data, sizeY, sizeY * 5 / 4, color[1]);
@@ -495,41 +520,57 @@
         mInputIndex++;
     }
 
-    private void generateSurfaceFrame(int frameIndex, int width, int height) {
-        frameIndex %= 4;
+    private static Rect getColorBarRect(int index, int width, int height) {
+        int barWidth = (width - BORDER_WIDTH * 2) / COLOR_BARS.length;
+        return new Rect(BORDER_WIDTH + barWidth * index, BORDER_WIDTH,
+                BORDER_WIDTH + barWidth * (index + 1), height - BORDER_WIDTH);
+    }
 
+    private static Rect getColorBlockRect(int index, int width, int height) {
+        int blockCenterX = (width / 5) * (index % 4 + 1);
+        return new Rect(blockCenterX - width / 10, height / 6,
+                        blockCenterX + width / 10, height / 3);
+    }
+
+    private void generateSurfaceFrame(int frameIndex, int width, int height) {
         GLES20.glViewport(0, 0, width, height);
         GLES20.glDisable(GLES20.GL_SCISSOR_TEST);
         GLES20.glClearColor(1.0f, 0.0f, 0.0f, 1.0f);
         GLES20.glClear(GLES20.GL_COLOR_BUFFER_BIT);
         GLES20.glEnable(GLES20.GL_SCISSOR_TEST);
 
-        int startX, startY;
-        int borderWidth = 16;
-        for (int i = 0; i < 7; i++) {
-            startX = (width - borderWidth * 2) * i / 7 + borderWidth;
-            GLES20.glScissor(startX, borderWidth,
-                    (width - borderWidth * 2) / 7, height - borderWidth * 2);
-            GLES20.glClearColor(((7 - i) & 0x4) * 0.16f,
-                    ((7 - i) & 0x2) * 0.32f,
-                    ((7 - i) & 0x1) * 0.64f,
-                    1.0f);
+        for (int i = 0; i < COLOR_BARS.length; i++) {
+            Rect r = getColorBarRect(i, width, height);
+
+            GLES20.glScissor(r.left, r.top, r.width(), r.height());
+            final Color color = COLOR_BARS[i];
+            GLES20.glClearColor(color.red(), color.green(), color.blue(), 1.0f);
             GLES20.glClear(GLES20.GL_COLOR_BUFFER_BIT);
         }
 
-        startX = (width / 6) + (width / 6) * frameIndex;
-        startY = height / 4;
-        GLES20.glScissor(startX, startY, width / 6, height / 3);
+        Rect r = getColorBlockRect(frameIndex, width, height);
+        GLES20.glScissor(r.left, r.top, r.width(), r.height());
         GLES20.glClearColor(0.5f, 0.5f, 0.5f, 1.0f);
         GLES20.glClear(GLES20.GL_COLOR_BUFFER_BIT);
-        GLES20.glScissor(startX + borderWidth, startY + borderWidth,
-                width / 6 - borderWidth * 2, height / 3 - borderWidth * 2);
-        GLES20.glClearColor(1.0f, 1.0f, 1.0f, 1.0f);
+        r.inset(BORDER_WIDTH, BORDER_WIDTH);
+        GLES20.glScissor(r.left, r.top, r.width(), r.height());
+        GLES20.glClearColor(COLOR_BLOCK.red(), COLOR_BLOCK.green(), COLOR_BLOCK.blue(), 1.0f);
         GLES20.glClear(GLES20.GL_COLOR_BUFFER_BIT);
     }
 
+    /**
+     * Determines if two color values are approximately equal.
+     */
+    private static boolean approxEquals(Color expected, Color actual) {
+        final float MAX_DELTA = 0.025f;
+        return (Math.abs(expected.red() - actual.red()) <= MAX_DELTA)
+            && (Math.abs(expected.green() - actual.green()) <= MAX_DELTA)
+            && (Math.abs(expected.blue() - actual.blue()) <= MAX_DELTA);
+    }
+
     private void verifyResult(
-            String filename, int width, int height, int rotation, boolean useGrid, int numImages)
+            String filename, int width, int height, int rotation,
+            int imageCount, int primary, boolean useGrid, boolean checkColor)
             throws Exception {
         MediaMetadataRetriever retriever = new MediaMetadataRetriever();
         retriever.setDataSource(filename);
@@ -537,9 +578,6 @@
         if (!"yes".equals(hasImage)) {
             throw new Exception("No images found in file " + filename);
         }
-        assertEquals("Wrong image count", numImages,
-                Integer.parseInt(retriever.extractMetadata(
-                    MediaMetadataRetriever.METADATA_KEY_IMAGE_COUNT)));
         assertEquals("Wrong width", width,
                 Integer.parseInt(retriever.extractMetadata(
                     MediaMetadataRetriever.METADATA_KEY_IMAGE_WIDTH)));
@@ -549,6 +587,12 @@
         assertEquals("Wrong rotation", rotation,
                 Integer.parseInt(retriever.extractMetadata(
                     MediaMetadataRetriever.METADATA_KEY_IMAGE_ROTATION)));
+        assertEquals("Wrong image count", imageCount,
+                Integer.parseInt(retriever.extractMetadata(
+                        MediaMetadataRetriever.METADATA_KEY_IMAGE_COUNT)));
+        assertEquals("Wrong primary index", primary,
+                Integer.parseInt(retriever.extractMetadata(
+                        MediaMetadataRetriever.METADATA_KEY_IMAGE_PRIMARY)));
         retriever.release();
 
         if (useGrid) {
@@ -565,5 +609,19 @@
                     ((height + tileHeight - 1) / tileHeight) == gridRows);
             extractor.release();
         }
+
+        if (checkColor) {
+            Bitmap bitmap = BitmapFactory.decodeFile(filename);
+
+            for (int i = 0; i < COLOR_BARS.length; i++) {
+                Rect r = getColorBarRect(i, width, height);
+                assertTrue("Color bar " + i + " doesn't match", approxEquals(COLOR_BARS[i],
+                        Color.valueOf(bitmap.getPixel(r.centerX(), r.centerY()))));
+            }
+
+            Rect r = getColorBlockRect(primary, width, height);
+            assertTrue("Color block doesn't match", approxEquals(COLOR_BLOCK,
+                    Color.valueOf(bitmap.getPixel(r.centerX(), height - r.centerY()))));
+        }
     }
 }
diff --git a/tests/tests/media/src/android/media/cts/ImageReaderDecoderTest.java b/tests/tests/media/src/android/media/cts/ImageReaderDecoderTest.java
index dcac8f0..540e3ff 100644
--- a/tests/tests/media/src/android/media/cts/ImageReaderDecoderTest.java
+++ b/tests/tests/media/src/android/media/cts/ImageReaderDecoderTest.java
@@ -320,8 +320,7 @@
         ArrayList<Decoder> result = new ArrayList<Decoder>();
 
         for (MediaCodecInfo info : mcl.getCodecInfos()) {
-            if (info.isEncoder()
-                    || info.getName().toLowerCase().startsWith("omx.google.") != goog) {
+            if (info.isEncoder() || MediaUtils.isGoogle(info.getName()) != goog) {
                 continue;
             }
             CodecCapabilities caps = null;
diff --git a/tests/tests/media/src/android/media/cts/MediaControllerTest.java b/tests/tests/media/src/android/media/cts/MediaControllerTest.java
index 056483e..6700a70 100644
--- a/tests/tests/media/src/android/media/cts/MediaControllerTest.java
+++ b/tests/tests/media/src/android/media/cts/MediaControllerTest.java
@@ -15,6 +15,7 @@
  */
 package android.media.cts;
 
+import android.content.Intent;
 import android.media.AudioManager;
 import android.media.Rating;
 import android.media.VolumeProvider;
@@ -29,6 +30,7 @@
 import android.os.Process;
 import android.os.ResultReceiver;
 import android.test.AndroidTestCase;
+import android.view.KeyEvent;
 
 /**
  * Test {@link android.media.session.MediaController}.
@@ -289,6 +291,16 @@
             assertEquals(EXTRAS_VALUE, mCallback.mExtras.getString(EXTRAS_KEY));
             assertEquals(mControllerInfo, mCallback.mCallerInfo);
 
+            mCallback.reset();
+            KeyEvent event = new KeyEvent(KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_MEDIA_STOP);
+            mController.dispatchMediaButtonEvent(event);
+            mWaitLock.wait(TIME_OUT_MS);
+            assertTrue(mCallback.mOnMediaButtonEventCalled);
+            // KeyEvent doesn't override equals.
+            assertEquals(KeyEvent.ACTION_DOWN, mCallback.mKeyEvent.getAction());
+            assertEquals(KeyEvent.KEYCODE_MEDIA_STOP, mCallback.mKeyEvent.getKeyCode());
+            assertEquals(mControllerInfo, mCallback.mCallerInfo);
+
             // just call the callback once directly so it's marked as tested
             try {
                 callback.onPlay();
@@ -310,6 +322,9 @@
                 callback.onPrepareFromMediaId(mCallback.mMediaId, mCallback.mExtras);
                 callback.onPrepareFromSearch(mCallback.mQuery, mCallback.mExtras);
                 callback.onPrepareFromUri(Uri.parse("http://d.android.com"), mCallback.mExtras);
+                Intent mediaButtonIntent = new Intent(Intent.ACTION_MEDIA_BUTTON);
+                mediaButtonIntent.putExtra(Intent.EXTRA_KEY_EVENT, event);
+                callback.onMediaButtonEvent(mediaButtonIntent);
             } catch (IllegalStateException ex) {
                 // Expected, since the MediaSession.getCurrentControllerInfo() is called in every
                 // callback method, but no controller is sending any command.
@@ -347,6 +362,7 @@
         private String mCommand;
         private Bundle mExtras;
         private ResultReceiver mCommandCallback;
+        private KeyEvent mKeyEvent;
         private RemoteUserInfo mCallerInfo;
 
         private boolean mOnPlayCalled;
@@ -368,6 +384,7 @@
         private boolean mOnPrepareFromMediaIdCalled;
         private boolean mOnPrepareFromSearchCalled;
         private boolean mOnPrepareFromUriCalled;
+        private boolean mOnMediaButtonEventCalled;
 
         public void reset() {
             mSeekPosition = -1;
@@ -380,6 +397,7 @@
             mExtras = null;
             mCommand = null;
             mCommandCallback = null;
+            mKeyEvent = null;
             mCallerInfo = null;
 
             mOnPlayCalled = false;
@@ -401,6 +419,7 @@
             mOnPrepareFromMediaIdCalled = false;
             mOnPrepareFromSearchCalled = false;
             mOnPrepareFromUriCalled = false;
+            mOnMediaButtonEventCalled = false;
         }
 
         @Override
@@ -593,5 +612,16 @@
                 mWaitLock.notify();
             }
         }
+
+        @Override
+        public boolean onMediaButtonEvent(Intent mediaButtonIntent) {
+            synchronized (mWaitLock) {
+                mOnMediaButtonEventCalled = true;
+                mCallerInfo = mSession.getCurrentControllerInfo();
+                mKeyEvent = mediaButtonIntent.getParcelableExtra(Intent.EXTRA_KEY_EVENT);
+                mWaitLock.notify();
+            }
+            return super.onMediaButtonEvent(mediaButtonIntent);
+        }
     }
 }
diff --git a/tests/tests/media/src/android/media/cts/MediaDrmClearkeyTest.java b/tests/tests/media/src/android/media/cts/MediaDrmClearkeyTest.java
index e392ef1..a5ead3f 100644
--- a/tests/tests/media/src/android/media/cts/MediaDrmClearkeyTest.java
+++ b/tests/tests/media/src/android/media/cts/MediaDrmClearkeyTest.java
@@ -112,7 +112,7 @@
     private byte[] mSessionId;
     private Looper mLooper;
     private MediaCodecClearKeyPlayer mMediaCodecPlayer;
-    private MediaDrm mDrm;
+    private MediaDrm mDrm = null;
     private final Object mLock = new Object();
     private SurfaceHolder mSurfaceHolder;
 
@@ -242,6 +242,10 @@
         new Thread() {
             @Override
             public void run() {
+                if (mDrm != null) {
+                    Log.e(TAG, "Failed to startDrm: already started");
+                    return;
+                }
                 // Set up a looper to handle events
                 Looper.prepare();
 
@@ -293,6 +297,8 @@
             Log.e(TAG, "invalid drm specified in stopDrm");
         }
         mLooper.quit();
+        mDrm.close();
+        mDrm = null;
     }
 
     private @NonNull byte[] openSession(MediaDrm drm) {
@@ -689,52 +695,49 @@
         }
     }
 
-    public void testGetOpenSessionCount() {
-        byte[] sessionId = null;
-        MediaDrm drm = null;
-        try {
-            drm = new MediaDrm(COMMON_PSSH_SCHEME_UUID);
-
-            if (drm.getOpenSessionCount() != 0) {
-                throw new Error("expected open session count to be 0");
-            }
-            sessionId = drm.openSession();
-            if (drm.getOpenSessionCount() != 1) {
-                throw new Error("expected open session count to be 1");
-            }
-            drm.closeSession(sessionId);
-            sessionId = null;
-
-            if (drm.getOpenSessionCount() != 0) {
-                throw new Error("expected open session count to be 0");
-            }
-        } catch(Exception e) {
-            throw new Error("Unexpected exception requesting open sessions", e);
-        } finally  {
-            if (sessionId != null) {
-                drm.closeSession(sessionId);
-            }
-        }
-    }
-
     private final static int CLEARKEY_MAX_SESSIONS = 10;
 
-    public void testMaxSessionCount() {
-        try {
-            MediaDrm drm = new MediaDrm(COMMON_PSSH_SCHEME_UUID);
+    public void testGetNumberOfSessions() {
+        MediaDrm drm = startDrm(new byte[][] { CLEAR_KEY_CENC },
+                "cenc", COMMON_PSSH_SCHEME_UUID);
 
-            if (drm.getMaxSessionCount() != CLEARKEY_MAX_SESSIONS) {
-                throw new Error("expected open session count to be " +
+        try {
+            if (getClearkeyVersion(drm).equals("1.0")) {
+                Log.i(TAG, "Skipping testGetNumberOfSessions: not supported by clearkey 1.0");
+                return;
+            }
+
+            int maxSessionCount = drm.getMaxSessionCount();
+            if (maxSessionCount != CLEARKEY_MAX_SESSIONS) {
+                throw new Error("expected max session count to be " +
                         CLEARKEY_MAX_SESSIONS);
             }
-        } catch(Exception e) {
-            throw new Error("Unexpected exception requesting open sessions", e);
+            int initialOpenSessionCount = drm.getOpenSessionCount();
+            if (initialOpenSessionCount == maxSessionCount) {
+                throw new Error("all sessions open, can't do increment test");
+            }
+            mSessionId = openSession(drm);
+            try {
+                if (drm.getOpenSessionCount() != initialOpenSessionCount + 1) {
+                    throw new Error("openSessionCount didn't increment");
+                }
+            } finally {
+                closeSession(drm, mSessionId);
+            }
+        } finally {
+            stopDrm(drm);
         }
     }
 
     public void testHdcpLevels() {
+        MediaDrm drm = null;
         try {
-            MediaDrm drm = new MediaDrm(COMMON_PSSH_SCHEME_UUID);
+            drm = new MediaDrm(COMMON_PSSH_SCHEME_UUID);
+
+            if (getClearkeyVersion(drm).equals("1.0")) {
+                Log.i(TAG, "Skipping testHdcpLevels: not supported by clearkey 1.0");
+                return;
+            }
 
             if (drm.getConnectedHdcpLevel() != MediaDrm.HDCP_NONE) {
                 throw new Error("expected connected hdcp level to be HDCP_NONE");
@@ -744,7 +747,11 @@
                 throw new Error("expected max hdcp level to be HDCP_NO_DIGITAL_OUTPUT");
             }
         } catch(Exception e) {
-            throw new Error("Unexpected exception requesting open sessions", e);
+            throw new Error("Unexpected exception", e);
+        } finally {
+            if (drm != null) {
+                drm.close();
+            }
         }
     }
 
@@ -754,6 +761,11 @@
         try {
             drm = new MediaDrm(COMMON_PSSH_SCHEME_UUID);
 
+            if (getClearkeyVersion(drm).equals("1.0")) {
+                Log.i(TAG, "Skipping testSecurityLevels: not supported by clearkey 1.0");
+                return;
+            }
+
             sessionId = drm.openSession(MediaDrm.SECURITY_LEVEL_SW_SECURE_CRYPTO);
             if (drm.getSecurityLevel(sessionId) != MediaDrm.SECURITY_LEVEL_SW_SECURE_CRYPTO) {
                 throw new Error("expected security level to be SECURITY_LEVEL_SW_SECURE_CRYPTO");
@@ -778,26 +790,35 @@
             } finally  {
                 if (sessionId != null) {
                     drm.closeSession(sessionId);
+                    sessionId = null;
                 }
             }
         } catch(Exception e) {
-            throw new Error("Unexpected exception requesting open sessions", e);
+            throw new Error("Unexpected exception", e);
         } finally  {
             if (sessionId != null) {
                 drm.closeSession(sessionId);
             }
+            if (drm != null) {
+                drm.close();
+            }
         }
      }
 
     public void testSecureStop() {
         MediaDrm drm = startDrm(new byte[][] {CLEAR_KEY_CENC}, "cenc", COMMON_PSSH_SCHEME_UUID);
-        if (!drm.isCryptoSchemeSupported(COMMON_PSSH_SCHEME_UUID)) {
-            stopDrm(drm);
-            throw new Error(ERR_MSG_CRYPTO_SCHEME_NOT_SUPPORTED);
-        }
 
         byte[] sessionId = null;
         try {
+            if (getClearkeyVersion(drm).equals("1.0")) {
+                Log.i(TAG, "Skipping testSecureStop: not supported in ClearKey v1.0");
+                return;
+            }
+
+            if (!drm.isCryptoSchemeSupported(COMMON_PSSH_SCHEME_UUID)) {
+                throw new Error(ERR_MSG_CRYPTO_SCHEME_NOT_SUPPORTED);
+            }
+
             drm.removeAllSecureStops();
             Log.d(TAG, "Test getSecureStops from an empty list.");
             List<byte[]> secureStops = drm.getSecureStops();
@@ -889,7 +910,7 @@
             mMediaCodecPlayer.reset();
             closeSession(drm, mSessionId);
         } catch (Exception e) {
-            throw new Error("Unexpected exception requesting open sessions", e);
+            throw new Error("Unexpected exception", e);
         } finally {
             if (sessionId != null) {
                 drm.closeSession(sessionId);
@@ -897,4 +918,12 @@
             stopDrm(drm);
         }
     }
+
+    private String getClearkeyVersion(MediaDrm drm) {
+        try {
+            return drm.getPropertyString("version");
+        } catch (Exception e) {
+            return "unavailable";
+        }
+    }
 }
diff --git a/tests/tests/media/src/android/media/cts/MediaDrmMetricsTest.java b/tests/tests/media/src/android/media/cts/MediaDrmMetricsTest.java
index 31a9669..87ae2c0 100644
--- a/tests/tests/media/src/android/media/cts/MediaDrmMetricsTest.java
+++ b/tests/tests/media/src/android/media/cts/MediaDrmMetricsTest.java
@@ -49,10 +49,24 @@
       return joiner.toString();
     }
 
+    private String getClearkeyVersion(MediaDrm drm) {
+        try {
+            return drm.getPropertyString("version");
+        } catch (Exception e) {
+            return "unavailable";
+        }
+    }
+
     public void testGetMetricsEmpty() throws Exception {
         MediaDrm drm = new MediaDrm(CLEARKEY_SCHEME_UUID);
         assertNotNull(drm);
 
+        if (getClearkeyVersion(drm).equals("1.0")) {
+            Log.i(TAG, "Skipping testGetMetricsEmpty: not supported in ClearKey v1.0");
+            drm.close();
+            return;
+        }
+
         PersistableBundle metrics = drm.getMetrics();
         assertNotNull(metrics);
 
@@ -65,6 +79,13 @@
     public void testGetMetricsSession() throws Exception {
         MediaDrm drm = new MediaDrm(CLEARKEY_SCHEME_UUID);
         assertNotNull(drm);
+
+        if (getClearkeyVersion(drm).equals("1.0")) {
+            Log.i(TAG, "Skipping testGetMetricsSession: not supported in ClearKey v1.0");
+            drm.close();
+            return;
+        }
+
         byte[] sid1 = drm.openSession();
         assertNotNull(sid1);
         byte[] sid2 = drm.openSession();
@@ -111,6 +132,13 @@
     public void testGetMetricsGetKeyRequest() throws Exception {
         MediaDrm drm = new MediaDrm(CLEARKEY_SCHEME_UUID);
         assertNotNull(drm);
+
+        if (getClearkeyVersion(drm).equals("1.0")) {
+            Log.i(TAG, "Skipping testGetMetricsGetKeyRequest: not supported in ClearKey v1.0");
+            drm.close();
+            return;
+        }
+
         byte[] sid = drm.openSession();
         assertNotNull(sid);
 
diff --git a/tests/tests/media/src/android/media/cts/MediaPlayer2Test.java b/tests/tests/media/src/android/media/cts/MediaPlayer2Test.java
index e5b4580..c6ff76c 100644
--- a/tests/tests/media/src/android/media/cts/MediaPlayer2Test.java
+++ b/tests/tests/media/src/android/media/cts/MediaPlayer2Test.java
@@ -39,6 +39,7 @@
 import android.media.TimedText;
 import android.media.audiofx.AudioEffect;
 import android.media.audiofx.Visualizer;
+import android.media.cts.TestUtils.Monitor;
 import android.net.Uri;
 import android.os.Bundle;
 import android.os.Environment;
diff --git a/tests/tests/media/src/android/media/cts/MediaPlayer2TestBase.java b/tests/tests/media/src/android/media/cts/MediaPlayer2TestBase.java
index c9ee844..2975d47 100644
--- a/tests/tests/media/src/android/media/cts/MediaPlayer2TestBase.java
+++ b/tests/tests/media/src/android/media/cts/MediaPlayer2TestBase.java
@@ -26,6 +26,7 @@
 import android.media.MediaTimestamp;
 import android.media.TimedMetaData;
 import android.media.TimedText;
+import android.media.cts.TestUtils.Monitor;
 import android.net.Uri;
 import android.os.PersistableBundle;
 import android.test.ActivityInstrumentationTestCase2;
@@ -197,58 +198,6 @@
         return null;
     }
 
-    public static class Monitor {
-        private int numSignal;
-
-        public synchronized void reset() {
-            numSignal = 0;
-        }
-
-        public synchronized void signal() {
-            numSignal++;
-            notifyAll();
-        }
-
-        public synchronized boolean waitForSignal() throws InterruptedException {
-            return waitForCountedSignals(1) > 0;
-        }
-
-        public synchronized int waitForCountedSignals(int targetCount) throws InterruptedException {
-            while (numSignal < targetCount) {
-                wait();
-            }
-            return numSignal;
-        }
-
-        public synchronized boolean waitForSignal(long timeoutMs) throws InterruptedException {
-            return waitForCountedSignals(1, timeoutMs) > 0;
-        }
-
-        public synchronized int waitForCountedSignals(int targetCount, long timeoutMs)
-                throws InterruptedException {
-            if (timeoutMs == 0) {
-                return waitForCountedSignals(targetCount);
-            }
-            long deadline = System.currentTimeMillis() + timeoutMs;
-            while (numSignal < targetCount) {
-                long delay = deadline - System.currentTimeMillis();
-                if (delay <= 0) {
-                    break;
-                }
-                wait(delay);
-            }
-            return numSignal;
-        }
-
-        public synchronized boolean isSignalled() {
-            return numSignal >= 1;
-        }
-
-        public synchronized int getNumSignal() {
-            return numSignal;
-        }
-    }
-
     public MediaPlayer2TestBase() {
         super(MediaStubActivity.class);
     }
diff --git a/tests/tests/media/src/android/media/cts/MediaPlayerDrmTestBase.java b/tests/tests/media/src/android/media/cts/MediaPlayerDrmTestBase.java
index 94e75eb..b65c690 100644
--- a/tests/tests/media/src/android/media/cts/MediaPlayerDrmTestBase.java
+++ b/tests/tests/media/src/android/media/cts/MediaPlayerDrmTestBase.java
@@ -30,7 +30,7 @@
 import android.media.MediaPlayer.DrmInfo;
 import android.media.ResourceBusyException;
 import android.media.UnsupportedSchemeException;
-import android.media.cts.MediaPlayerTestBase.Monitor;
+import android.media.cts.TestUtils.Monitor;
 import android.net.Uri;
 import android.os.Handler;
 import android.os.HandlerThread;
diff --git a/tests/tests/media/src/android/media/cts/MediaPlayerFlakyNetworkTest.java b/tests/tests/media/src/android/media/cts/MediaPlayerFlakyNetworkTest.java
index 5fc71ff..d9076c7 100644
--- a/tests/tests/media/src/android/media/cts/MediaPlayerFlakyNetworkTest.java
+++ b/tests/tests/media/src/android/media/cts/MediaPlayerFlakyNetworkTest.java
@@ -16,6 +16,7 @@
 package android.media.cts;
 
 import android.media.MediaPlayer;
+import android.media.cts.TestUtils.Monitor;
 import android.os.Handler;
 import android.os.Looper;
 import android.os.Message;
diff --git a/tests/tests/media/src/android/media/cts/MediaPlayerTest.java b/tests/tests/media/src/android/media/cts/MediaPlayerTest.java
index 906354c..ac04dfd 100644
--- a/tests/tests/media/src/android/media/cts/MediaPlayerTest.java
+++ b/tests/tests/media/src/android/media/cts/MediaPlayerTest.java
@@ -41,6 +41,7 @@
 import android.media.TimedText;
 import android.media.audiofx.AudioEffect;
 import android.media.audiofx.Visualizer;
+import android.media.cts.TestUtils.Monitor;
 import android.net.Uri;
 import android.os.Bundle;
 import android.os.Environment;
@@ -64,8 +65,10 @@
 import java.util.StringTokenizer;
 import java.util.UUID;
 import java.util.Vector;
+import java.util.concurrent.BlockingDeque;
 import java.util.concurrent.Callable;
 import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.LinkedBlockingDeque;
 import java.util.concurrent.atomic.AtomicInteger;
 import java.util.stream.Collectors;
 import java.util.stream.Stream;
@@ -98,7 +101,6 @@
     private final Monitor mOnSubtitleDataCalled = new Monitor();
     private int mSelectedSubtitleIndex;
 
-    private final LinkedList<MediaTimestamp> mTimestamps = new LinkedList<>();
     private final Monitor mOnMediaTimeDiscontinuityCalled = new Monitor();
 
     private File mOutFile;
@@ -1368,12 +1370,13 @@
                         mOnSeekCompleteCalled.signal();
                     }
                 });
+        final BlockingDeque<MediaTimestamp> timestamps = new LinkedBlockingDeque<>();
         mMediaPlayer.setOnMediaTimeDiscontinuityListener(
                 new MediaPlayer.OnMediaTimeDiscontinuityListener() {
                     @Override
                     public void onMediaTimeDiscontinuity(MediaPlayer mp, MediaTimestamp timestamp) {
                         mOnMediaTimeDiscontinuityCalled.signal();
-                        mTimestamps.add(timestamp);
+                        timestamps.add(timestamp);
                     }
                 });
         mMediaPlayer.setDisplay(mActivity.getSurfaceHolder());
@@ -1382,33 +1385,41 @@
         // Timestamp needs to be reported when playback starts.
         mOnMediaTimeDiscontinuityCalled.reset();
         mMediaPlayer.start();
-        mOnMediaTimeDiscontinuityCalled.waitForSignal();
-        assertEquals(1.0f, mTimestamps.getLast().getMediaClockRate());
+        do {
+            assertTrue(mOnMediaTimeDiscontinuityCalled.waitForSignal(1000));
+        } while (timestamps.getLast().getMediaClockRate() != 1.0f);
 
         // Timestamp needs to be reported when seeking is done.
         mOnSeekCompleteCalled.reset();
         mOnMediaTimeDiscontinuityCalled.reset();
         mMediaPlayer.seekTo(3000);
         mOnSeekCompleteCalled.waitForSignal();
-        while (mTimestamps.getLast().getMediaClockRate() != 1.0f) {
-            // During the seeking the clock might be paused temporarily, but player eventually need
-            // to start the playback after seeking.
-            mOnMediaTimeDiscontinuityCalled.waitForSignal();
-        }
+        do {
+            assertTrue(mOnMediaTimeDiscontinuityCalled.waitForSignal(1000));
+        } while (timestamps.getLast().getMediaClockRate() != 1.0f);
 
         // Timestamp needs to be updated when playback rate changes.
         mOnMediaTimeDiscontinuityCalled.reset();
         mMediaPlayer.setPlaybackParams(new PlaybackParams().setSpeed(0.5f));
-        mOnMediaTimeDiscontinuityCalled.waitForSignal();
-        assertEquals(0.5f, mTimestamps.getLast().getMediaClockRate());
+        do {
+            assertTrue(mOnMediaTimeDiscontinuityCalled.waitForSignal(1000));
+        } while (timestamps.getLast().getMediaClockRate() != 0.5f);
 
         // Timestamp needs to be updated when player is paused.
         mOnMediaTimeDiscontinuityCalled.reset();
         mMediaPlayer.pause();
-        mOnMediaTimeDiscontinuityCalled.waitForSignal();
-        assertEquals(0.0f, mTimestamps.getLast().getMediaClockRate());
+        do {
+            assertTrue(mOnMediaTimeDiscontinuityCalled.waitForSignal(1000));
+        } while (timestamps.getLast().getMediaClockRate() != 0.0f);
 
-        mMediaPlayer.stop();
+        // Check if there is no more notification after clearing listener.
+        mMediaPlayer.clearOnMediaTimeDiscontinuityListener();
+        mMediaPlayer.start();
+        mOnMediaTimeDiscontinuityCalled.reset();
+        Thread.sleep(1000);
+        assertEquals(0, mOnMediaTimeDiscontinuityCalled.getNumSignal());
+
+        mMediaPlayer.reset();
     }
 
     public void testLocalVideo_MKV_H265_1280x720_500kbps_25fps_AAC_Stereo_128kbps_44100Hz()
@@ -1759,6 +1770,62 @@
         mMediaPlayer.stop();
     }
 
+    public void testOnSubtitleDataListener() throws Throwable {
+        if (!checkLoadResource(R.raw.testvideo_with_2_subtitle_tracks)) {
+            return; // skip;
+        }
+
+        mMediaPlayer.setOnSubtitleDataListener(new MediaPlayer.OnSubtitleDataListener() {
+            @Override
+            public void onSubtitleData(MediaPlayer mp, SubtitleData data) {
+                if (data != null && data.getData() != null
+                        && data.getTrackIndex() == mSubtitleTrackIndex.get(0)) {
+                    mOnSubtitleDataCalled.signal();
+                }
+            }
+        });
+        mMediaPlayer.setOnInfoListener(new MediaPlayer.OnInfoListener() {
+            @Override
+            public boolean onInfo(MediaPlayer mp, int what, int extra) {
+                if (what == MediaPlayer.MEDIA_INFO_METADATA_UPDATE) {
+                    mOnInfoCalled.signal();
+                }
+                return false;
+            }
+        });
+
+        mMediaPlayer.setDisplay(getActivity().getSurfaceHolder());
+        mMediaPlayer.setScreenOnWhilePlaying(true);
+        mMediaPlayer.setWakeMode(mContext, PowerManager.PARTIAL_WAKE_LOCK);
+
+        mMediaPlayer.prepare();
+        mMediaPlayer.start();
+        assertTrue(mMediaPlayer.isPlaying());
+
+        // Closed caption tracks are in-band.
+        // So, those tracks will be found after processing a number of frames.
+        mOnInfoCalled.waitForSignal(1500);
+
+        mOnInfoCalled.reset();
+        mOnInfoCalled.waitForSignal(1500);
+
+        readSubtitleTracks();
+
+        // Waits until at least two captions are fired. Timeout is 2.5 sec.
+        selectSubtitleTrack(0);
+        assertTrue(mOnSubtitleDataCalled.waitForCountedSignals(2, 2500) >= 2);
+
+        // Check if there is no more notification after clearing listener.
+        mMediaPlayer.clearOnSubtitleDataListener();
+        mMediaPlayer.seekTo(0);
+        mMediaPlayer.start();
+        mOnSubtitleDataCalled.reset();
+        Thread.sleep(2500);
+        assertEquals(0, mOnSubtitleDataCalled.getNumSignal());
+
+        mMediaPlayer.stop();
+    }
+
     public void testGetTrackInfoForVideoWithSubtitleTracks() throws Throwable {
         if (!checkLoadResource(R.raw.testvideo_with_2_subtitle_tracks)) {
             return; // skip;
diff --git a/tests/tests/media/src/android/media/cts/MediaPlayerTestBase.java b/tests/tests/media/src/android/media/cts/MediaPlayerTestBase.java
index d2b7f23..a21c1ce 100644
--- a/tests/tests/media/src/android/media/cts/MediaPlayerTestBase.java
+++ b/tests/tests/media/src/android/media/cts/MediaPlayerTestBase.java
@@ -20,6 +20,7 @@
 import android.content.res.AssetFileDescriptor;
 import android.content.res.Resources;
 import android.media.MediaPlayer;
+import android.media.cts.TestUtils.Monitor;
 import android.net.Uri;
 import android.os.PersistableBundle;
 import android.test.ActivityInstrumentationTestCase2;
@@ -44,58 +45,6 @@
     protected static final int STREAM_RETRIES = 20;
     protected static boolean sUseScaleToFitMode = false;
 
-    public static class Monitor {
-        private int numSignal;
-
-        public synchronized void reset() {
-            numSignal = 0;
-        }
-
-        public synchronized void signal() {
-            numSignal++;
-            notifyAll();
-        }
-
-        public synchronized boolean waitForSignal() throws InterruptedException {
-            return waitForCountedSignals(1) > 0;
-        }
-
-        public synchronized int waitForCountedSignals(int targetCount) throws InterruptedException {
-            while (numSignal < targetCount) {
-                wait();
-            }
-            return numSignal;
-        }
-
-        public synchronized boolean waitForSignal(long timeoutMs) throws InterruptedException {
-            return waitForCountedSignals(1, timeoutMs) > 0;
-        }
-
-        public synchronized int waitForCountedSignals(int targetCount, long timeoutMs)
-                throws InterruptedException {
-            if (timeoutMs == 0) {
-                return waitForCountedSignals(targetCount);
-            }
-            long deadline = System.currentTimeMillis() + timeoutMs;
-            while (numSignal < targetCount) {
-                long delay = deadline - System.currentTimeMillis();
-                if (delay <= 0) {
-                    break;
-                }
-                wait(delay);
-            }
-            return numSignal;
-        }
-
-        public synchronized boolean isSignalled() {
-            return numSignal >= 1;
-        }
-
-        public synchronized int getNumSignal() {
-            return numSignal;
-        }
-    }
-
     protected Monitor mOnVideoSizeChangedCalled = new Monitor();
     protected Monitor mOnVideoRenderingStartCalled = new Monitor();
     protected Monitor mOnBufferingUpdateCalled = new Monitor();
diff --git a/tests/tests/media/src/android/media/cts/MediaRecorderTest.java b/tests/tests/media/src/android/media/cts/MediaRecorderTest.java
index 7284341..bec1f04 100644
--- a/tests/tests/media/src/android/media/cts/MediaRecorderTest.java
+++ b/tests/tests/media/src/android/media/cts/MediaRecorderTest.java
@@ -633,6 +633,7 @@
         Log.i(TAG, "deviceId:" + microphone.getDescription());
         Log.i(TAG, "portId:" + microphone.getId());
         Log.i(TAG, "type:" + microphone.getType());
+        Log.i(TAG, "address:" + microphone.getAddress());
         Log.i(TAG, "deviceLocation:" + microphone.getLocation());
         Log.i(TAG, "deviceGroup:" + microphone.getGroup()
             + " index:" + microphone.getIndexInTheGroup());
diff --git a/tests/tests/media/src/android/media/cts/MediaSessionTest.java b/tests/tests/media/src/android/media/cts/MediaSessionTest.java
index ce89012..dd42ca7 100644
--- a/tests/tests/media/src/android/media/cts/MediaSessionTest.java
+++ b/tests/tests/media/src/android/media/cts/MediaSessionTest.java
@@ -16,7 +16,6 @@
 package android.media.cts;
 
 import static android.media.AudioAttributes.USAGE_GAME;
-import static android.support.test.InstrumentationRegistry.getInstrumentation;
 
 import android.app.PendingIntent;
 import android.content.ComponentName;
@@ -31,18 +30,19 @@
 import android.media.session.MediaController;
 import android.media.session.MediaSession;
 import android.media.session.MediaSession.QueueItem;
+import android.media.session.MediaSessionManager;
+import android.media.session.MediaSessionManager.RemoteUserInfo;
 import android.media.session.PlaybackState;
 import android.os.Bundle;
 import android.os.Handler;
 import android.os.Looper;
 import android.os.Parcel;
-import android.support.test.filters.LargeTest;
+import android.os.Process;
 import android.test.AndroidTestCase;
 import android.view.KeyEvent;
 
 import java.util.ArrayList;
 import java.util.List;
-import java.util.Set;
 import java.util.concurrent.CountDownLatch;
 import java.util.concurrent.TimeUnit;
 
@@ -66,12 +66,15 @@
     private Object mWaitLock = new Object();
     private MediaControllerCallback mCallback = new MediaControllerCallback();
     private MediaSession mSession;
+    private RemoteUserInfo mKeyDispatcherInfo;
 
     @Override
     protected void setUp() throws Exception {
         super.setUp();
         mAudioManager = (AudioManager) getContext().getSystemService(Context.AUDIO_SERVICE);
         mSession = new MediaSession(getContext(), TEST_SESSION_TAG);
+        mKeyDispatcherInfo = new MediaSessionManager.RemoteUserInfo(
+                getContext().getPackageName(), Process.myPid(), Process.myUid());
     }
 
     @Override
@@ -338,36 +341,43 @@
         simulateMediaKeyInput(KeyEvent.KEYCODE_MEDIA_PLAY);
         assertTrue(sessionCallback.await(TIME_OUT_MS));
         assertEquals(1, sessionCallback.mOnPlayCalledCount);
+        assertEquals(mKeyDispatcherInfo, sessionCallback.mCallerInfo);
 
         sessionCallback.reset(1);
         simulateMediaKeyInput(KeyEvent.KEYCODE_MEDIA_PAUSE);
         assertTrue(sessionCallback.await(TIME_OUT_MS));
         assertTrue(sessionCallback.mOnPauseCalled);
+        assertEquals(mKeyDispatcherInfo, sessionCallback.mCallerInfo);
 
         sessionCallback.reset(1);
         simulateMediaKeyInput(KeyEvent.KEYCODE_MEDIA_NEXT);
         assertTrue(sessionCallback.await(TIME_OUT_MS));
         assertTrue(sessionCallback.mOnSkipToNextCalled);
+        assertEquals(mKeyDispatcherInfo, sessionCallback.mCallerInfo);
 
         sessionCallback.reset(1);
         simulateMediaKeyInput(KeyEvent.KEYCODE_MEDIA_PREVIOUS);
         assertTrue(sessionCallback.await(TIME_OUT_MS));
         assertTrue(sessionCallback.mOnSkipToPreviousCalled);
+        assertEquals(mKeyDispatcherInfo, sessionCallback.mCallerInfo);
 
         sessionCallback.reset(1);
         simulateMediaKeyInput(KeyEvent.KEYCODE_MEDIA_STOP);
         assertTrue(sessionCallback.await(TIME_OUT_MS));
         assertTrue(sessionCallback.mOnStopCalled);
+        assertEquals(mKeyDispatcherInfo, sessionCallback.mCallerInfo);
 
         sessionCallback.reset(1);
         simulateMediaKeyInput(KeyEvent.KEYCODE_MEDIA_FAST_FORWARD);
         assertTrue(sessionCallback.await(TIME_OUT_MS));
         assertTrue(sessionCallback.mOnFastForwardCalled);
+        assertEquals(mKeyDispatcherInfo, sessionCallback.mCallerInfo);
 
         sessionCallback.reset(1);
         simulateMediaKeyInput(KeyEvent.KEYCODE_MEDIA_REWIND);
         assertTrue(sessionCallback.await(TIME_OUT_MS));
         assertTrue(sessionCallback.mOnRewindCalled);
+        assertEquals(mKeyDispatcherInfo, sessionCallback.mCallerInfo);
 
         // Test PLAY_PAUSE button twice.
         // First, simulate PLAY_PAUSE button while in STATE_PAUSED.
@@ -376,6 +386,7 @@
         simulateMediaKeyInput(KeyEvent.KEYCODE_MEDIA_PLAY_PAUSE);
         assertTrue(sessionCallback.await(TIME_OUT_MS));
         assertEquals(1, sessionCallback.mOnPlayCalledCount);
+        assertEquals(mKeyDispatcherInfo, sessionCallback.mCallerInfo);
 
         // Next, simulate PLAY_PAUSE button while in STATE_PLAYING.
         sessionCallback.reset(1);
@@ -383,6 +394,7 @@
         simulateMediaKeyInput(KeyEvent.KEYCODE_MEDIA_PLAY_PAUSE);
         assertTrue(sessionCallback.await(TIME_OUT_MS));
         assertTrue(sessionCallback.mOnPauseCalled);
+        assertEquals(mKeyDispatcherInfo, sessionCallback.mCallerInfo);
 
         // Double tap of PLAY_PAUSE is the next track instead of changing PLAY/PAUSE.
         sessionCallback.reset(2);
@@ -393,6 +405,7 @@
         assertTrue(sessionCallback.mOnSkipToNextCalled);
         assertEquals(0, sessionCallback.mOnPlayCalledCount);
         assertFalse(sessionCallback.mOnPauseCalled);
+        assertEquals(mKeyDispatcherInfo, sessionCallback.mCallerInfo);
 
         // Test if PLAY_PAUSE double tap is considered as two single taps when another media
         // key is pressed.
@@ -404,6 +417,7 @@
         assertTrue(sessionCallback.await(TIME_OUT_MS));
         assertEquals(2, sessionCallback.mOnPlayCalledCount);
         assertTrue(sessionCallback.mOnStopCalled);
+        assertEquals(mKeyDispatcherInfo, sessionCallback.mCallerInfo);
 
         // Test if media keys are handled in order.
         sessionCallback.reset(2);
@@ -413,6 +427,7 @@
         assertTrue(sessionCallback.await(TIME_OUT_MS));
         assertEquals(1, sessionCallback.mOnPlayCalledCount);
         assertTrue(sessionCallback.mOnStopCalled);
+        assertEquals(mKeyDispatcherInfo, sessionCallback.mCallerInfo);
         synchronized (mWaitLock) {
             assertEquals(PlaybackState.STATE_STOPPED,
                     mSession.getController().getPlaybackState().getState());
@@ -472,6 +487,8 @@
         mSession.release();
     }
 
+    // This uses public APIs to dispatch key events, so sessions would consider this as
+    // 'media key event from this application'.
     private void simulateMediaKeyInput(int keyCode) {
         mAudioManager.dispatchMediaKeyEvent(new KeyEvent(KeyEvent.ACTION_DOWN, keyCode));
         mAudioManager.dispatchMediaKeyEvent(new KeyEvent(KeyEvent.ACTION_UP, keyCode));
@@ -659,6 +676,7 @@
         private boolean mOnRewindCalled;
         private boolean mOnSkipToPreviousCalled;
         private boolean mOnSkipToNextCalled;
+        private RemoteUserInfo mCallerInfo;
 
         public void reset(int count) {
             mLatch = new CountDownLatch(count);
@@ -682,6 +700,7 @@
         @Override
         public void onPlay() {
             mOnPlayCalledCount++;
+            mCallerInfo = mSession.getCurrentControllerInfo();
             setPlaybackState(PlaybackState.STATE_PLAYING);
             mLatch.countDown();
         }
@@ -689,6 +708,7 @@
         @Override
         public void onPause() {
             mOnPauseCalled = true;
+            mCallerInfo = mSession.getCurrentControllerInfo();
             setPlaybackState(PlaybackState.STATE_PAUSED);
             mLatch.countDown();
         }
@@ -696,6 +716,7 @@
         @Override
         public void onStop() {
             mOnStopCalled = true;
+            mCallerInfo = mSession.getCurrentControllerInfo();
             setPlaybackState(PlaybackState.STATE_STOPPED);
             mLatch.countDown();
         }
@@ -703,24 +724,28 @@
         @Override
         public void onFastForward() {
             mOnFastForwardCalled = true;
+            mCallerInfo = mSession.getCurrentControllerInfo();
             mLatch.countDown();
         }
 
         @Override
         public void onRewind() {
             mOnRewindCalled = true;
+            mCallerInfo = mSession.getCurrentControllerInfo();
             mLatch.countDown();
         }
 
         @Override
         public void onSkipToPrevious() {
             mOnSkipToPreviousCalled = true;
+            mCallerInfo = mSession.getCurrentControllerInfo();
             mLatch.countDown();
         }
 
         @Override
         public void onSkipToNext() {
             mOnSkipToNextCalled = true;
+            mCallerInfo = mSession.getCurrentControllerInfo();
             mLatch.countDown();
         }
     }
diff --git a/tests/tests/media/src/android/media/cts/NativeMediaDrmClearkeyTest.java b/tests/tests/media/src/android/media/cts/NativeMediaDrmClearkeyTest.java
index 1858da0..fb5880ea9 100644
--- a/tests/tests/media/src/android/media/cts/NativeMediaDrmClearkeyTest.java
+++ b/tests/tests/media/src/android/media/cts/NativeMediaDrmClearkeyTest.java
@@ -131,6 +131,10 @@
         assertTrue(testQueryKeyStatusNative(uuidByteArray(COMMON_PSSH_SCHEME_UUID)));
     }
 
+    public void testFindSessionId() throws Exception {
+        assertTrue(testFindSessionIdNative(uuidByteArray(COMMON_PSSH_SCHEME_UUID)));
+    }
+
     public void testGetPropertyString() throws Exception {
         StringBuffer value = new StringBuffer();
         testGetPropertyStringNative(uuidByteArray(COMMON_PSSH_SCHEME_UUID), "description", value);
@@ -230,6 +234,8 @@
     private static native boolean testClearKeyPlaybackNative(final byte[] uuid,
             PlaybackParams params);
 
+    private static native boolean testFindSessionIdNative(final byte[] uuid);
+
     private static native boolean testGetPropertyStringNative(final byte[] uuid,
             final String name, StringBuffer value);
 
diff --git a/tests/tests/media/src/android/media/cts/RingtoneTest.java b/tests/tests/media/src/android/media/cts/RingtoneTest.java
index 092ac0b..cd4e761 100644
--- a/tests/tests/media/src/android/media/cts/RingtoneTest.java
+++ b/tests/tests/media/src/android/media/cts/RingtoneTest.java
@@ -20,6 +20,7 @@
 import android.app.UiAutomation;
 import android.content.Context;
 import android.content.pm.PackageManager;
+import android.media.AudioAttributes;
 import android.media.AudioManager;
 import android.media.Ringtone;
 import android.media.RingtoneManager;
@@ -162,4 +163,32 @@
         mRingtone.stop();
         assertFalse(mRingtone.isPlaying());
     }
+
+    public void testLoopingVolume() {
+        if (isTV()) {
+            return;
+        }
+        if (!hasAudioOutput()) {
+            Log.i(TAG, "Skipping testRingtone(): device doesn't have audio output.");
+            return;
+        }
+
+        Uri uri = RingtoneManager.getValidRingtoneUri(mContext);
+        assertNotNull("ringtone was unexpectedly null", uri);
+        RingtoneManager.setActualDefaultRingtoneUri(mContext, RingtoneManager.TYPE_RINGTONE, uri);
+        assertNotNull(mRingtone.getTitle(mContext));
+        final AudioAttributes ringtoneAa = new AudioAttributes.Builder()
+                .setUsage(AudioAttributes.USAGE_NOTIFICATION_RINGTONE).
+                build();
+        mRingtone.setAudioAttributes(ringtoneAa);
+        assertEquals(ringtoneAa, mRingtone.getAudioAttributes());
+        mRingtone.setLooping(true);
+        mRingtone.setVolume(0.5f);
+        mRingtone.play();
+        assertTrue("couldn't play ringtone " + uri, mRingtone.isPlaying());
+        assertTrue(mRingtone.isLooping());
+        assertEquals("invalid ringtone player volume", 0.5f, mRingtone.getVolume());
+        mRingtone.stop();
+        assertFalse(mRingtone.isPlaying());
+    }
 }
diff --git a/tests/tests/media/src/android/media/cts/StreamingMediaPlayer2Test.java b/tests/tests/media/src/android/media/cts/StreamingMediaPlayer2Test.java
index 81bcf14..3cc3dce 100644
--- a/tests/tests/media/src/android/media/cts/StreamingMediaPlayer2Test.java
+++ b/tests/tests/media/src/android/media/cts/StreamingMediaPlayer2Test.java
@@ -21,6 +21,7 @@
 import android.media.MediaPlayer2;
 import android.media.MediaPlayer2.TrackInfo;
 import android.media.TimedMetaData;
+import android.media.cts.TestUtils.Monitor;
 import android.net.Uri;
 import android.os.Bundle;
 import android.os.Looper;
diff --git a/tests/tests/media/src/android/media/cts/TestMedia2DataSource.java b/tests/tests/media/src/android/media/cts/TestMedia2DataSource.java
index 89f6111..536d62b 100644
--- a/tests/tests/media/src/android/media/cts/TestMedia2DataSource.java
+++ b/tests/tests/media/src/android/media/cts/TestMedia2DataSource.java
@@ -17,7 +17,7 @@
 package android.media.cts;
 
 import android.content.res.AssetFileDescriptor;
-import android.media.cts.MediaPlayer2TestBase.Monitor;
+import android.media.cts.TestUtils.Monitor;
 import android.media.Media2DataSource;
 import android.util.Log;
 
diff --git a/tests/tests/media/src/android/media/cts/TestMediaDataSource.java b/tests/tests/media/src/android/media/cts/TestMediaDataSource.java
index a10840b..97f41f7 100644
--- a/tests/tests/media/src/android/media/cts/TestMediaDataSource.java
+++ b/tests/tests/media/src/android/media/cts/TestMediaDataSource.java
@@ -17,7 +17,7 @@
 package android.media.cts;
 
 import android.content.res.AssetFileDescriptor;
-import android.media.cts.MediaPlayerTestBase.Monitor;
+import android.media.cts.TestUtils.Monitor;
 import android.media.MediaDataSource;
 import android.util.Log;
 
diff --git a/tests/tests/media/src/android/media/cts/TestUtils.java b/tests/tests/media/src/android/media/cts/TestUtils.java
index 4d4b95f..f86f150 100644
--- a/tests/tests/media/src/android/media/cts/TestUtils.java
+++ b/tests/tests/media/src/android/media/cts/TestUtils.java
@@ -160,4 +160,56 @@
             }
         }
     }
+
+    public static class Monitor {
+        private int mNumSignal;
+
+        public synchronized void reset() {
+            mNumSignal = 0;
+        }
+
+        public synchronized void signal() {
+            mNumSignal++;
+            notifyAll();
+        }
+
+        public synchronized boolean waitForSignal() throws InterruptedException {
+            return waitForCountedSignals(1) > 0;
+        }
+
+        public synchronized int waitForCountedSignals(int targetCount) throws InterruptedException {
+            while (mNumSignal < targetCount) {
+                wait();
+            }
+            return mNumSignal;
+        }
+
+        public synchronized boolean waitForSignal(long timeoutMs) throws InterruptedException {
+            return waitForCountedSignals(1, timeoutMs) > 0;
+        }
+
+        public synchronized int waitForCountedSignals(int targetCount, long timeoutMs)
+                throws InterruptedException {
+            if (timeoutMs == 0) {
+                return waitForCountedSignals(targetCount);
+            }
+            long deadline = System.currentTimeMillis() + timeoutMs;
+            while (mNumSignal < targetCount) {
+                long delay = deadline - System.currentTimeMillis();
+                if (delay <= 0) {
+                    break;
+                }
+                wait(delay);
+            }
+            return mNumSignal;
+        }
+
+        public synchronized boolean isSignalled() {
+            return mNumSignal >= 1;
+        }
+
+        public synchronized int getNumSignal() {
+            return mNumSignal;
+        }
+    }
 }
diff --git a/tests/tests/media/src/android/media/cts/VideoDecoderPerfTest.java b/tests/tests/media/src/android/media/cts/VideoDecoderPerfTest.java
index c7101b5..ba184aa 100644
--- a/tests/tests/media/src/android/media/cts/VideoDecoderPerfTest.java
+++ b/tests/tests/media/src/android/media/cts/VideoDecoderPerfTest.java
@@ -331,8 +331,9 @@
         R.raw.bbb_s1_320x240_mp4_h264_mp2_800kbps_30fps_aac_lc_5ch_240kbps_44100hz,
     };
 
-    public void testAvcCount0320x0240() throws Exception { count(sAvcMedia0320x0240, 1, 4); }
+    public void testAvcCount0320x0240() throws Exception { count(sAvcMedia0320x0240, 2, 4); }
     public void testAvcGoog0Perf0320x0240() throws Exception { perf(sAvcMedia0320x0240, GOOG, 0); }
+    public void testAvcGoog1Perf0320x0240() throws Exception { perf(sAvcMedia0320x0240, GOOG, 1); }
     public void testAvcOther0Perf0320x0240() throws Exception { perf(sAvcMedia0320x0240, OTHER, 0); }
     public void testAvcOther1Perf0320x0240() throws Exception { perf(sAvcMedia0320x0240, OTHER, 1); }
     public void testAvcOther2Perf0320x0240() throws Exception { perf(sAvcMedia0320x0240, OTHER, 2); }
@@ -342,8 +343,9 @@
         R.raw.bbb_s1_720x480_mp4_h264_mp3_2mbps_30fps_aac_lc_5ch_320kbps_48000hz,
     };
 
-    public void testAvcCount0720x0480() throws Exception { count(sAvcMedia0720x0480, 1, 4); }
+    public void testAvcCount0720x0480() throws Exception { count(sAvcMedia0720x0480, 2, 4); }
     public void testAvcGoog0Perf0720x0480() throws Exception { perf(sAvcMedia0720x0480, GOOG, 0); }
+    public void testAvcGoog1Perf0720x0480() throws Exception { perf(sAvcMedia0720x0480, GOOG, 1); }
     public void testAvcOther0Perf0720x0480() throws Exception { perf(sAvcMedia0720x0480, OTHER, 0); }
     public void testAvcOther1Perf0720x0480() throws Exception { perf(sAvcMedia0720x0480, OTHER, 1); }
     public void testAvcOther2Perf0720x0480() throws Exception { perf(sAvcMedia0720x0480, OTHER, 2); }
@@ -356,8 +358,9 @@
         R.raw.bbb_s3_1280x720_mp4_h264_mp32_8mbps_60fps_aac_he_v2_6ch_144kbps_44100hz,
     };
 
-    public void testAvcCount1280x0720() throws Exception { count(sAvcMedia1280x0720, 1, 4); }
+    public void testAvcCount1280x0720() throws Exception { count(sAvcMedia1280x0720, 2, 4); }
     public void testAvcGoog0Perf1280x0720() throws Exception { perf(sAvcMedia1280x0720, GOOG, 0); }
+    public void testAvcGoog1Perf1280x0720() throws Exception { perf(sAvcMedia1280x0720, GOOG, 1); }
     public void testAvcOther0Perf1280x0720() throws Exception { perf(sAvcMedia1280x0720, OTHER, 0); }
     public void testAvcOther1Perf1280x0720() throws Exception { perf(sAvcMedia1280x0720, OTHER, 1); }
     public void testAvcOther2Perf1280x0720() throws Exception { perf(sAvcMedia1280x0720, OTHER, 2); }
@@ -371,8 +374,9 @@
         R.raw.bbb_s2_1920x1080_mp4_h264_mp42_20mbps_60fps_aac_he_v2_5ch_160kbps_48000hz,
     };
 
-    public void testAvcCount1920x1080() throws Exception { count(sAvcMedia1920x1080, 1, 4); }
+    public void testAvcCount1920x1080() throws Exception { count(sAvcMedia1920x1080, 2, 4); }
     public void testAvcGoog0Perf1920x1080() throws Exception { perf(sAvcMedia1920x1080, GOOG, 0); }
+    public void testAvcGoog1Perf1920x1080() throws Exception { perf(sAvcMedia1920x1080, GOOG, 1); }
     public void testAvcOther0Perf1920x1080() throws Exception { perf(sAvcMedia1920x1080, OTHER, 0); }
     public void testAvcOther1Perf1920x1080() throws Exception { perf(sAvcMedia1920x1080, OTHER, 1); }
     public void testAvcOther2Perf1920x1080() throws Exception { perf(sAvcMedia1920x1080, OTHER, 2); }
@@ -384,8 +388,9 @@
         R.raw.video_176x144_3gp_h263_300kbps_12fps_aac_stereo_128kbps_22050hz,
     };
 
-    public void testH263Count0176x0144() throws Exception { count(sH263Media0176x0144, 1, 2); }
+    public void testH263Count0176x0144() throws Exception { count(sH263Media0176x0144, 2, 2); }
     public void testH263Goog0Perf0176x0144() throws Exception { perf(sH263Media0176x0144, GOOG, 0); }
+    public void testH263Goog1Perf0176x0144() throws Exception { perf(sH263Media0176x0144, GOOG, 1); }
     public void testH263Other0Perf0176x0144() throws Exception { perf(sH263Media0176x0144, OTHER, 0); }
     public void testH263Other1Perf0176x0144() throws Exception { perf(sH263Media0176x0144, OTHER, 1); }
 
@@ -393,8 +398,9 @@
         R.raw.video_352x288_3gp_h263_300kbps_12fps_aac_stereo_128kbps_22050hz,
     };
 
-    public void testH263Count0352x0288() throws Exception { count(sH263Media0352x0288, 1, 2); }
+    public void testH263Count0352x0288() throws Exception { count(sH263Media0352x0288, 2, 2); }
     public void testH263Goog0Perf0352x0288() throws Exception { perf(sH263Media0352x0288, GOOG, 0); }
+    public void testH263Goog1Perf0352x0288() throws Exception { perf(sH263Media0352x0288, GOOG, 1); }
     public void testH263Other0Perf0352x0288() throws Exception { perf(sH263Media0352x0288, OTHER, 0); }
     public void testH263Other1Perf0352x0288() throws Exception { perf(sH263Media0352x0288, OTHER, 1); }
 
@@ -408,8 +414,9 @@
         R.raw.bbb_s1_352x288_mp4_hevc_mp2_600kbps_30fps_aac_he_stereo_96kbps_48000hz,
     };
 
-    public void testHevcCount0352x0288() throws Exception { count(sHevcMedia0352x0288, 1, 4); }
+    public void testHevcCount0352x0288() throws Exception { count(sHevcMedia0352x0288, 2, 4); }
     public void testHevcGoog0Perf0352x0288() throws Exception { perf(sHevcMedia0352x0288, GOOG, 0); }
+    public void testHevcGoog1Perf0352x0288() throws Exception { perf(sHevcMedia0352x0288, GOOG, 1); }
     public void testHevcOther0Perf0352x0288() throws Exception { perf(sHevcMedia0352x0288, OTHER, 0); }
     public void testHevcOther1Perf0352x0288() throws Exception { perf(sHevcMedia0352x0288, OTHER, 1); }
     public void testHevcOther2Perf0352x0288() throws Exception { perf(sHevcMedia0352x0288, OTHER, 2); }
@@ -419,8 +426,9 @@
         R.raw.bbb_s1_640x360_mp4_hevc_mp21_1600kbps_30fps_aac_he_6ch_288kbps_44100hz,
     };
 
-    public void testHevcCount0640x0360() throws Exception { count(sHevcMedia0640x0360, 1, 4); }
+    public void testHevcCount0640x0360() throws Exception { count(sHevcMedia0640x0360, 2, 4); }
     public void testHevcGoog0Perf0640x0360() throws Exception { perf(sHevcMedia0640x0360, GOOG, 0); }
+    public void testHevcGoog1Perf0640x0360() throws Exception { perf(sHevcMedia0640x0360, GOOG, 1); }
     public void testHevcOther0Perf0640x0360() throws Exception { perf(sHevcMedia0640x0360, OTHER, 0); }
     public void testHevcOther1Perf0640x0360() throws Exception { perf(sHevcMedia0640x0360, OTHER, 1); }
     public void testHevcOther2Perf0640x0360() throws Exception { perf(sHevcMedia0640x0360, OTHER, 2); }
@@ -430,8 +438,9 @@
         R.raw.bbb_s1_720x480_mp4_hevc_mp3_1600kbps_30fps_aac_he_6ch_240kbps_48000hz,
     };
 
-    public void testHevcCount0720x0480() throws Exception { count(sHevcMedia0720x0480, 1, 4); }
+    public void testHevcCount0720x0480() throws Exception { count(sHevcMedia0720x0480, 2, 4); }
     public void testHevcGoog0Perf0720x0480() throws Exception { perf(sHevcMedia0720x0480, GOOG, 0); }
+    public void testHevcGoog1Perf0720x0480() throws Exception { perf(sHevcMedia0720x0480, GOOG, 1); }
     public void testHevcOther0Perf0720x0480() throws Exception { perf(sHevcMedia0720x0480, OTHER, 0); }
     public void testHevcOther1Perf0720x0480() throws Exception { perf(sHevcMedia0720x0480, OTHER, 1); }
     public void testHevcOther2Perf0720x0480() throws Exception { perf(sHevcMedia0720x0480, OTHER, 2); }
@@ -441,8 +450,9 @@
         R.raw.bbb_s4_1280x720_mp4_hevc_mp31_4mbps_30fps_aac_he_stereo_80kbps_32000hz,
     };
 
-    public void testHevcCount1280x0720() throws Exception { count(sHevcMedia1280x0720, 1, 4); }
+    public void testHevcCount1280x0720() throws Exception { count(sHevcMedia1280x0720, 2, 4); }
     public void testHevcGoog0Perf1280x0720() throws Exception { perf(sHevcMedia1280x0720, GOOG, 0); }
+    public void testHevcGoog1Perf1280x0720() throws Exception { perf(sHevcMedia1280x0720, GOOG, 1); }
     public void testHevcOther0Perf1280x0720() throws Exception { perf(sHevcMedia1280x0720, OTHER, 0); }
     public void testHevcOther1Perf1280x0720() throws Exception { perf(sHevcMedia1280x0720, OTHER, 1); }
     public void testHevcOther2Perf1280x0720() throws Exception { perf(sHevcMedia1280x0720, OTHER, 2); }
@@ -452,8 +462,9 @@
         R.raw.bbb_s2_1920x1080_mp4_hevc_mp41_10mbps_60fps_aac_lc_6ch_384kbps_22050hz,
     };
 
-    public void testHevcCount1920x1080() throws Exception { count(sHevcMedia1920x1080, 1, 4); }
+    public void testHevcCount1920x1080() throws Exception { count(sHevcMedia1920x1080, 2, 4); }
     public void testHevcGoog0Perf1920x1080() throws Exception { perf(sHevcMedia1920x1080, GOOG, 0); }
+    public void testHevcGoog1Perf1920x1080() throws Exception { perf(sHevcMedia1920x1080, GOOG, 1); }
     public void testHevcOther0Perf1920x1080() throws Exception { perf(sHevcMedia1920x1080, OTHER, 0); }
     public void testHevcOther1Perf1920x1080() throws Exception { perf(sHevcMedia1920x1080, OTHER, 1); }
     public void testHevcOther2Perf1920x1080() throws Exception { perf(sHevcMedia1920x1080, OTHER, 2); }
@@ -465,8 +476,9 @@
         R.raw.bbb_s2_3840x2160_mp4_hevc_mp51_20mbps_60fps_aac_lc_6ch_384kbps_32000hz,
     };
 
-    public void testHevcCount3840x2160() throws Exception { count(sHevcMedia3840x2160, 1, 4); }
+    public void testHevcCount3840x2160() throws Exception { count(sHevcMedia3840x2160, 2, 4); }
     public void testHevcGoog0Perf3840x2160() throws Exception { perf(sHevcMedia3840x2160, GOOG, 0); }
+    public void testHevcGoog1Perf3840x2160() throws Exception { perf(sHevcMedia3840x2160, GOOG, 1); }
     public void testHevcOther0Perf3840x2160() throws Exception { perf(sHevcMedia3840x2160, OTHER, 0); }
     public void testHevcOther1Perf3840x2160() throws Exception { perf(sHevcMedia3840x2160, OTHER, 1); }
     public void testHevcOther2Perf3840x2160() throws Exception { perf(sHevcMedia3840x2160, OTHER, 2); }
@@ -490,8 +502,9 @@
         R.raw.video_176x144_mp4_mpeg4_300kbps_25fps_aac_stereo_128kbps_44100hz,
     };
 
-    public void testMpeg4Count0176x0144() throws Exception { count(sMpeg4Media0176x0144, 1, 4); }
+    public void testMpeg4Count0176x0144() throws Exception { count(sMpeg4Media0176x0144, 2, 4); }
     public void testMpeg4Goog0Perf0176x0144() throws Exception { perf(sMpeg4Media0176x0144, GOOG, 0); }
+    public void testMpeg4Goog1Perf0176x0144() throws Exception { perf(sMpeg4Media0176x0144, GOOG, 1); }
     public void testMpeg4Other0Perf0176x0144() throws Exception { perf(sMpeg4Media0176x0144, OTHER, 0); }
     public void testMpeg4Other1Perf0176x0144() throws Exception { perf(sMpeg4Media0176x0144, OTHER, 1); }
     public void testMpeg4Other2Perf0176x0144() throws Exception { perf(sMpeg4Media0176x0144, OTHER, 2); }
@@ -501,8 +514,9 @@
         R.raw.video_480x360_mp4_mpeg4_860kbps_25fps_aac_stereo_128kbps_44100hz,
     };
 
-    public void testMpeg4Count0480x0360() throws Exception { count(sMpeg4Media0480x0360, 1, 4); }
+    public void testMpeg4Count0480x0360() throws Exception { count(sMpeg4Media0480x0360, 2, 4); }
     public void testMpeg4Goog0Perf0480x0360() throws Exception { perf(sMpeg4Media0480x0360, GOOG, 0); }
+    public void testMpeg4Goog1Perf0480x0360() throws Exception { perf(sMpeg4Media0480x0360, GOOG, 1); }
     public void testMpeg4Other0Perf0480x0360() throws Exception { perf(sMpeg4Media0480x0360, OTHER, 0); }
     public void testMpeg4Other1Perf0480x0360() throws Exception { perf(sMpeg4Media0480x0360, OTHER, 1); }
     public void testMpeg4Other2Perf0480x0360() throws Exception { perf(sMpeg4Media0480x0360, OTHER, 2); }
@@ -514,8 +528,9 @@
         R.raw.video_1280x720_mp4_mpeg4_1000kbps_25fps_aac_stereo_128kbps_44100hz,
     };
 
-    public void testMpeg4Count1280x0720() throws Exception { count(sMpeg4Media1280x0720, 1, 4); }
+    public void testMpeg4Count1280x0720() throws Exception { count(sMpeg4Media1280x0720, 2, 4); }
     public void testMpeg4Goog0Perf1280x0720() throws Exception { perf(sMpeg4Media1280x0720, GOOG, 0); }
+    public void testMpeg4Goog1Perf1280x0720() throws Exception { perf(sMpeg4Media1280x0720, GOOG, 1); }
     public void testMpeg4Other0Perf1280x0720() throws Exception { perf(sMpeg4Media1280x0720, OTHER, 0); }
     public void testMpeg4Other1Perf1280x0720() throws Exception { perf(sMpeg4Media1280x0720, OTHER, 1); }
     public void testMpeg4Other2Perf1280x0720() throws Exception { perf(sMpeg4Media1280x0720, OTHER, 2); }
@@ -527,8 +542,9 @@
         R.raw.bbb_s1_320x180_webm_vp8_800kbps_30fps_opus_5ch_320kbps_48000hz,
     };
 
-    public void testVp8Count0320x0180() throws Exception { count(sVp8Media0320x0180, 1, 2); }
+    public void testVp8Count0320x0180() throws Exception { count(sVp8Media0320x0180, 2, 2); }
     public void testVp8Goog0Perf0320x0180() throws Exception { perf(sVp8Media0320x0180, GOOG, 0); }
+    public void testVp8Goog1Perf0320x0180() throws Exception { perf(sVp8Media0320x0180, GOOG, 1); }
     public void testVp8Other0Perf0320x0180() throws Exception { perf(sVp8Media0320x0180, OTHER, 0); }
     public void testVp8Other1Perf0320x0180() throws Exception { perf(sVp8Media0320x0180, OTHER, 1); }
 
@@ -536,8 +552,9 @@
         R.raw.bbb_s1_640x360_webm_vp8_2mbps_30fps_vorbis_5ch_320kbps_48000hz,
     };
 
-    public void testVp8Count0640x0360() throws Exception { count(sVp8Media0640x0360, 1, 2); }
+    public void testVp8Count0640x0360() throws Exception { count(sVp8Media0640x0360, 2, 2); }
     public void testVp8Goog0Perf0640x0360() throws Exception { perf(sVp8Media0640x0360, GOOG, 0); }
+    public void testVp8Goog1Perf0640x0360() throws Exception { perf(sVp8Media0640x0360, GOOG, 1); }
     public void testVp8Other0Perf0640x0360() throws Exception { perf(sVp8Media0640x0360, OTHER, 0); }
     public void testVp8Other1Perf0640x0360() throws Exception { perf(sVp8Media0640x0360, OTHER, 1); }
 
@@ -547,8 +564,9 @@
         R.raw.bbb_s3_1280x720_webm_vp8_8mbps_60fps_opus_6ch_384kbps_48000hz,
     };
 
-    public void testVp8Count1280x0720() throws Exception { count(sVp8Media1280x0720, 1, 2); }
+    public void testVp8Count1280x0720() throws Exception { count(sVp8Media1280x0720, 2, 2); }
     public void testVp8Goog0Perf1280x0720() throws Exception { perf(sVp8Media1280x0720, GOOG, 0); }
+    public void testVp8Goog1Perf1280x0720() throws Exception { perf(sVp8Media1280x0720, GOOG, 1); }
     public void testVp8Other0Perf1280x0720() throws Exception { perf(sVp8Media1280x0720, OTHER, 0); }
     public void testVp8Other1Perf1280x0720() throws Exception { perf(sVp8Media1280x0720, OTHER, 1); }
 
@@ -558,8 +576,9 @@
         R.raw.bbb_s2_1920x1080_webm_vp8_20mbps_60fps_vorbis_6ch_384kbps_48000hz,
     };
 
-    public void testVp8Count1920x1080() throws Exception { count(sVp8Media1920x1080, 1, 2); }
+    public void testVp8Count1920x1080() throws Exception { count(sVp8Media1920x1080, 2, 2); }
     public void testVp8Goog0Perf1920x1080() throws Exception { perf(sVp8Media1920x1080, GOOG, 0); }
+    public void testVp8Goog1Perf1920x1080() throws Exception { perf(sVp8Media1920x1080, GOOG, 1); }
     public void testVp8Other0Perf1920x1080() throws Exception { perf(sVp8Media1920x1080, OTHER, 0); }
     public void testVp8Other1Perf1920x1080() throws Exception { perf(sVp8Media1920x1080, OTHER, 1); }
 
@@ -569,8 +588,9 @@
         R.raw.bbb_s1_320x180_webm_vp9_0p11_600kbps_30fps_vorbis_mono_64kbps_48000hz,
     };
 
-    public void testVp9Count0320x0180() throws Exception { count(sVp9Media0320x0180, 1, 4); }
+    public void testVp9Count0320x0180() throws Exception { count(sVp9Media0320x0180, 2, 4); }
     public void testVp9Goog0Perf0320x0180() throws Exception { perf(sVp9Media0320x0180, GOOG, 0); }
+    public void testVp9Goog1Perf0320x0180() throws Exception { perf(sVp9Media0320x0180, GOOG, 1); }
     public void testVp9Other0Perf0320x0180() throws Exception { perf(sVp9Media0320x0180, OTHER, 0); }
     public void testVp9Other1Perf0320x0180() throws Exception { perf(sVp9Media0320x0180, OTHER, 1); }
     public void testVp9Other2Perf0320x0180() throws Exception { perf(sVp9Media0320x0180, OTHER, 2); }
@@ -580,8 +600,9 @@
         R.raw.bbb_s1_640x360_webm_vp9_0p21_1600kbps_30fps_vorbis_stereo_128kbps_48000hz,
     };
 
-    public void testVp9Count0640x0360() throws Exception { count(sVp9Media0640x0360, 1, 4); }
+    public void testVp9Count0640x0360() throws Exception { count(sVp9Media0640x0360, 2, 4); }
     public void testVp9Goog0Perf0640x0360() throws Exception { perf(sVp9Media0640x0360, GOOG, 0); }
+    public void testVp9Goog1Perf0640x0360() throws Exception { perf(sVp9Media0640x0360, GOOG, 1); }
     public void testVp9Other0Perf0640x0360() throws Exception { perf(sVp9Media0640x0360, OTHER, 0); }
     public void testVp9Other1Perf0640x0360() throws Exception { perf(sVp9Media0640x0360, OTHER, 1); }
     public void testVp9Other2Perf0640x0360() throws Exception { perf(sVp9Media0640x0360, OTHER, 2); }
@@ -591,8 +612,9 @@
         R.raw.bbb_s4_1280x720_webm_vp9_0p31_4mbps_30fps_opus_stereo_128kbps_48000hz,
     };
 
-    public void testVp9Count1280x0720() throws Exception { count(sVp9Media1280x0720, 1, 4); }
+    public void testVp9Count1280x0720() throws Exception { count(sVp9Media1280x0720, 2, 4); }
     public void testVp9Goog0Perf1280x0720() throws Exception { perf(sVp9Media1280x0720, GOOG, 0); }
+    public void testVp9Goog1Perf1280x0720() throws Exception { perf(sVp9Media1280x0720, GOOG, 1); }
     public void testVp9Other0Perf1280x0720() throws Exception { perf(sVp9Media1280x0720, OTHER, 0); }
     public void testVp9Other1Perf1280x0720() throws Exception { perf(sVp9Media1280x0720, OTHER, 1); }
     public void testVp9Other2Perf1280x0720() throws Exception { perf(sVp9Media1280x0720, OTHER, 2); }
@@ -602,8 +624,9 @@
         R.raw.bbb_s2_1920x1080_webm_vp9_0p41_10mbps_60fps_vorbis_6ch_384kbps_22050hz,
     };
 
-    public void testVp9Count1920x1080() throws Exception { count(sVp9Media1920x1080, 1, 4); }
+    public void testVp9Count1920x1080() throws Exception { count(sVp9Media1920x1080, 2, 4); }
     public void testVp9Goog0Perf1920x1080() throws Exception { perf(sVp9Media1920x1080, GOOG, 0); }
+    public void testVp9Goog1Perf1920x1080() throws Exception { perf(sVp9Media1920x1080, GOOG, 1); }
     public void testVp9Other0Perf1920x1080() throws Exception { perf(sVp9Media1920x1080, OTHER, 0); }
     public void testVp9Other1Perf1920x1080() throws Exception { perf(sVp9Media1920x1080, OTHER, 1); }
     public void testVp9Other2Perf1920x1080() throws Exception { perf(sVp9Media1920x1080, OTHER, 2); }
@@ -615,8 +638,9 @@
         R.raw.bbb_s2_3840x2160_webm_vp9_0p51_20mbps_60fps_vorbis_6ch_384kbps_32000hz,
     };
 
-    public void testVp9Count3840x2160() throws Exception { count(sVp9Media3840x2160, 1, 4); }
+    public void testVp9Count3840x2160() throws Exception { count(sVp9Media3840x2160, 2, 4); }
     public void testVp9Goog0Perf3840x2160() throws Exception { perf(sVp9Media3840x2160, GOOG, 0); }
+    public void testVp9Goog1Perf3840x2160() throws Exception { perf(sVp9Media3840x2160, GOOG, 1); }
     public void testVp9Other0Perf3840x2160() throws Exception { perf(sVp9Media3840x2160, OTHER, 0); }
     public void testVp9Other1Perf3840x2160() throws Exception { perf(sVp9Media3840x2160, OTHER, 1); }
     public void testVp9Other2Perf3840x2160() throws Exception { perf(sVp9Media3840x2160, OTHER, 2); }
diff --git a/tests/tests/media/src/android/media/cts/VideoEncoderTest.java b/tests/tests/media/src/android/media/cts/VideoEncoderTest.java
index 8dbdefb..8d1225b 100644
--- a/tests/tests/media/src/android/media/cts/VideoEncoderTest.java
+++ b/tests/tests/media/src/android/media/cts/VideoEncoderTest.java
@@ -1190,8 +1190,7 @@
         ArrayList<Encoder> result = new ArrayList<Encoder>();
 
         for (MediaCodecInfo info : mcl.getCodecInfos()) {
-            if (!info.isEncoder()
-                    || info.getName().toLowerCase().startsWith("omx.google.") != goog) {
+            if (!info.isEncoder() || MediaUtils.isGoogle(info.getName()) != goog) {
                 continue;
             }
             CodecCapabilities caps = null;
diff --git a/tests/tests/media/src/android/media/cts/VpxCodecTestBase.java b/tests/tests/media/src/android/media/cts/VpxCodecTestBase.java
index df9372f..c82a96b 100644
--- a/tests/tests/media/src/android/media/cts/VpxCodecTestBase.java
+++ b/tests/tests/media/src/android/media/cts/VpxCodecTestBase.java
@@ -32,6 +32,8 @@
 import android.util.Log;
 import android.media.cts.R;
 
+import com.android.compatibility.common.util.MediaUtils;
+
 import java.io.File;
 import java.io.FileInputStream;
 import java.io.FileOutputStream;
@@ -55,7 +57,6 @@
     protected static final String TAG = "VPxCodecTestBase";
     protected static final String VP8_MIME = MediaFormat.MIMETYPE_VIDEO_VP8;
     protected static final String VP9_MIME = MediaFormat.MIMETYPE_VIDEO_VP9;
-    private static final String GOOGLE_CODEC_PREFIX = "omx.google.";
     protected static final String SDCARD_DIR =
             Environment.getExternalStorageDirectory().getAbsolutePath();
 
@@ -100,7 +101,7 @@
             this.colorFormat = colorFormat;
         }
         public boolean  isGoogleCodec() {
-            return codecName.toLowerCase().startsWith(GOOGLE_CODEC_PREFIX);
+            return MediaUtils.isGoogle(codecName);
         }
 
         public final String codecName; // OpenMax component name for VPx codec.
@@ -138,8 +139,7 @@
             Log.v(TAG, codecInfo.getName());
             // TODO: remove dependence of Google from the test
             // Check if this is Google codec - we should ignore it.
-            boolean isGoogleCodec =
-                codecInfo.getName().toLowerCase().startsWith(GOOGLE_CODEC_PREFIX);
+            boolean isGoogleCodec = MediaUtils.isGoogle(codecInfo.getName());
             if (!isGoogleCodec && forceGoogleCodec) {
                 continue;
             }
@@ -2018,4 +2018,3 @@
         return statistics;
     }
 }
-
diff --git a/tests/tests/multiuser/AndroidManifest.xml b/tests/tests/multiuser/AndroidManifest.xml
index f983fad..cacadfb 100644
--- a/tests/tests/multiuser/AndroidManifest.xml
+++ b/tests/tests/multiuser/AndroidManifest.xml
@@ -17,7 +17,8 @@
   -->
 
 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
-          package="android.multiuser.cts">
+          package="android.multiuser.cts"
+          android:targetSandboxVersion="2">
 
     <application>
         <uses-library android:name="android.test.runner" />
diff --git a/tests/tests/nativehardware/src/android/hardware/cts/AHardwareBufferNativeTests.java b/tests/tests/nativehardware/src/android/hardware/nativehardware/cts/AHardwareBufferNativeTests.java
similarity index 94%
rename from tests/tests/nativehardware/src/android/hardware/cts/AHardwareBufferNativeTests.java
rename to tests/tests/nativehardware/src/android/hardware/nativehardware/cts/AHardwareBufferNativeTests.java
index f4851f6..7d94939 100644
--- a/tests/tests/nativehardware/src/android/hardware/cts/AHardwareBufferNativeTests.java
+++ b/tests/tests/nativehardware/src/android/hardware/nativehardware/cts/AHardwareBufferNativeTests.java
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package android.hardware.cts;
+package android.hardware.nativehardware.cts;
 
 import org.junit.runner.RunWith;
 import com.android.gtestrunner.GtestRunner;
diff --git a/tests/tests/nativehardware/src/android/hardware/cts/HardwareBufferVrTest.java b/tests/tests/nativehardware/src/android/hardware/nativehardware/cts/HardwareBufferVrTest.java
similarity index 97%
rename from tests/tests/nativehardware/src/android/hardware/cts/HardwareBufferVrTest.java
rename to tests/tests/nativehardware/src/android/hardware/nativehardware/cts/HardwareBufferVrTest.java
index daf0a82..0c4d250 100644
--- a/tests/tests/nativehardware/src/android/hardware/cts/HardwareBufferVrTest.java
+++ b/tests/tests/nativehardware/src/android/hardware/nativehardware/cts/HardwareBufferVrTest.java
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package android.hardware.cts;
+package android.hardware.nativehardware.cts;
 
 import android.content.pm.PackageManager;
 import android.hardware.HardwareBuffer;
diff --git a/tests/tests/net/native/qtaguid/Android.mk b/tests/tests/net/native/qtaguid/Android.mk
index 6c92b5c..bf89e5f 100644
--- a/tests/tests/net/native/qtaguid/Android.mk
+++ b/tests/tests/net/native/qtaguid/Android.mk
@@ -29,10 +29,10 @@
 LOCAL_SHARED_LIBRARIES := \
     libutils \
     liblog \
-    libcutils \
 
 LOCAL_STATIC_LIBRARIES := \
-    libgtest
+    libgtest \
+    libqtaguid \
 
 LOCAL_CTS_TEST_PACKAGE := android.net.native
 # Tag this module as a cts test artifact
diff --git a/tests/tests/net/native/qtaguid/src/NativeQtaguidTest.cpp b/tests/tests/net/native/qtaguid/src/NativeQtaguidTest.cpp
index 7f790fb..1892a44 100644
--- a/tests/tests/net/native/qtaguid/src/NativeQtaguidTest.cpp
+++ b/tests/tests/net/native/qtaguid/src/NativeQtaguidTest.cpp
@@ -23,7 +23,7 @@
 #include <sys/utsname.h>
 
 #include <gtest/gtest.h>
-#include <cutils/qtaguid.h>
+#include <qtaguid/qtaguid.h>
 
 int hasQtaguidKernelSupport() {
     struct utsname buf;
@@ -87,7 +87,7 @@
     uint64_t sk_addr;
     uint64_t expect_addr = 0;
 
-    EXPECT_EQ(0, qtaguid_tagSocket(sockfd, tag, uid));
+    EXPECT_EQ(0, legacy_tagSocket(sockfd, tag, uid));
     EXPECT_EQ(0, getCtrlSkInfo(tag, uid, &sk_addr, &ref_cnt));
     EXPECT_EQ(expect_addr, sk_addr);
     close(sockfd);
@@ -106,7 +106,7 @@
     int tag = arc4random();
     int ref_cnt;
     uint64_t dummy_sk;
-    EXPECT_EQ(0, qtaguid_tagSocket(sockfd, tag, uid));
+    EXPECT_EQ(0, legacy_tagSocket(sockfd, tag, uid));
     EXPECT_EQ(0, getCtrlSkInfo(tag, uid, &dummy_sk, &ref_cnt));
     EXPECT_EQ(2, ref_cnt);
     close(sockfd);
@@ -125,7 +125,7 @@
     int tag = arc4random();
     int ref_cnt;
     uint64_t dummy_sk;
-    EXPECT_EQ(0, qtaguid_tagSocket(sockfd, tag, uid));
+    EXPECT_EQ(0, legacy_tagSocket(sockfd, tag, uid));
     EXPECT_EQ(0, getCtrlSkInfo(tag, uid, &dummy_sk, &ref_cnt));
     EXPECT_EQ(2, ref_cnt);
     close(sockfd);
diff --git a/tests/tests/net/src/android/net/cts/IpSecManagerTest.java b/tests/tests/net/src/android/net/cts/IpSecManagerTest.java
index 95d91a2..a18b2f0 100644
--- a/tests/tests/net/src/android/net/cts/IpSecManagerTest.java
+++ b/tests/tests/net/src/android/net/cts/IpSecManagerTest.java
@@ -353,7 +353,8 @@
         private static void assertUidStatsDelta(
                 int expectedTxByteDelta,
                 int expectedTxPacketDelta,
-                int expectedRxByteDelta,
+                int minRxByteDelta,
+                int maxRxByteDelta,
                 int expectedRxPacketDelta) {
             long newUidTxBytes = TrafficStats.getUidTxBytes(Os.getuid());
             long newUidRxBytes = TrafficStats.getUidRxBytes(Os.getuid());
@@ -361,7 +362,9 @@
             long newUidRxPackets = TrafficStats.getUidRxPackets(Os.getuid());
 
             assertEquals(expectedTxByteDelta, newUidTxBytes - uidTxBytes);
-            assertEquals(expectedRxByteDelta, newUidRxBytes - uidRxBytes);
+            assertTrue(
+                    newUidRxBytes - uidRxBytes >= minRxByteDelta
+                            && newUidRxBytes - uidRxBytes <= maxRxByteDelta);
             assertEquals(expectedTxPacketDelta, newUidTxPackets - uidTxPackets);
             assertEquals(expectedRxPacketDelta, newUidRxPackets - uidRxPackets);
         }
@@ -561,13 +564,13 @@
 
         StatsChecker.waitForNumPackets(expectedPackets);
 
-        if (udpEncapLen != 0) {
-            StatsChecker.assertUidStatsDelta(
-                    expectedOuterBytes, expectedPackets, expectedOuterBytes, expectedPackets);
-        } else {
-            StatsChecker.assertUidStatsDelta(
-                    expectedOuterBytes, expectedPackets, expectedInnerBytes, expectedPackets);
-        }
+        // eBPF only counts inner packets, whereas xt_qtaguid counts outer packets. Allow both
+        StatsChecker.assertUidStatsDelta(
+                expectedOuterBytes,
+                expectedPackets,
+                expectedInnerBytes,
+                expectedOuterBytes,
+                expectedPackets);
 
         // Unreliable at low numbers due to potential interference from other processes.
         if (sendCount >= 1000) {
@@ -607,7 +610,11 @@
 
             StatsChecker.waitForNumPackets(expectedNumPkts);
             StatsChecker.assertUidStatsDelta(
-                    expectedPacketSize, expectedNumPkts, expectedPacketSize, expectedNumPkts);
+                    expectedPacketSize,
+                    expectedNumPkts,
+                    expectedPacketSize,
+                    expectedPacketSize,
+                    expectedNumPkts);
             StatsChecker.assertIfaceStatsDelta(
                     expectedPacketSize, expectedNumPkts, expectedPacketSize, expectedNumPkts);
         }
diff --git a/tests/tests/net/src/android/net/wifi/cts/WifiManagerTest.java b/tests/tests/net/src/android/net/wifi/cts/WifiManagerTest.java
index 1a08d3d..af91fbf 100644
--- a/tests/tests/net/src/android/net/wifi/cts/WifiManagerTest.java
+++ b/tests/tests/net/src/android/net/wifi/cts/WifiManagerTest.java
@@ -874,10 +874,9 @@
 
         TestLocalOnlyHotspotCallback callback = startLocalOnlyHotspot();
 
-        // at this point, wifi should be off
-        assertFalse(mWifiManager.isWifiEnabled());
-
         stopLocalOnlyHotspot(callback, wifiEnabled);
+
+        // wifi should either stay on, or come back on
         assertEquals(wifiEnabled, mWifiManager.isWifiEnabled());
     }
 
@@ -889,7 +888,7 @@
      * tethering is started.
      * Note: Location mode must be enabled for this test.
      */
-    public void testSetWifiEnabledByAppDoesNotStopHotspot() {
+    public void testSetWifiEnabledByAppDoesNotStopHotspot() throws Exception {
         if (!WifiFeature.isWifiSupported(getContext())) {
             // skip the test if WiFi is not supported
             return;
@@ -901,15 +900,18 @@
 
         boolean wifiEnabled = mWifiManager.isWifiEnabled();
 
+        if (wifiEnabled) {
+            // disable wifi so we have something to turn on (some devices may be able to run
+            // simultaneous modes)
+            setWifiEnabled(false);
+        }
+
         TestLocalOnlyHotspotCallback callback = startLocalOnlyHotspot();
-        // at this point, wifi should be off
-        assertFalse(mWifiManager.isWifiEnabled());
 
         // now we should fail to turn on wifi
         assertFalse(mWifiManager.setWifiEnabled(true));
 
         stopLocalOnlyHotspot(callback, wifiEnabled);
-        assertEquals(wifiEnabled, mWifiManager.isWifiEnabled());
     }
 
     /**
@@ -933,9 +935,6 @@
 
         TestLocalOnlyHotspotCallback callback = startLocalOnlyHotspot();
 
-        // at this point, wifi should be off
-        assertFalse(mWifiManager.isWifiEnabled());
-
         // now make a second request - this should fail.
         TestLocalOnlyHotspotCallback callback2 = new TestLocalOnlyHotspotCallback(mLOHSLock);
         try {
@@ -944,9 +943,12 @@
             Log.d(TAG, "Caught the IllegalStateException we expected: called startLOHS twice");
             caughtException = true;
         }
+        if (!caughtException) {
+            // second start did not fail, should clean up the hotspot.
+            stopLocalOnlyHotspot(callback2, wifiEnabled);
+        }
         assertTrue(caughtException);
 
         stopLocalOnlyHotspot(callback, wifiEnabled);
-        assertEquals(wifiEnabled, mWifiManager.isWifiEnabled());
     }
 }
diff --git a/tests/tests/neuralnetworks/Android.mk b/tests/tests/neuralnetworks/Android.mk
index c63ca99..b467b44 100644
--- a/tests/tests/neuralnetworks/Android.mk
+++ b/tests/tests/neuralnetworks/Android.mk
@@ -27,8 +27,10 @@
      src/TestGenerated.cpp \
      src/TestMemory.cpp \
      src/TestTrivialModel.cpp \
+     src/TestUnknownDimensions.cpp \
      src/TestValidateOperations.cpp \
-     src/TestValidation.cpp
+     src/TestValidation.cpp \
+     src/TestWrapper.cpp
 
 LOCAL_C_INCLUDES := frameworks/ml/nn/runtime/include/
 LOCAL_C_INCLUDES += frameworks/ml/nn/runtime/test/
diff --git a/hostsidetests/devicepolicy/app/DeviceOwner/src/com/android/cts/deviceowner/KeyManagementActivity.java b/tests/tests/neuralnetworks/src/TestUnknownDimensions.cpp
similarity index 75%
copy from hostsidetests/devicepolicy/app/DeviceOwner/src/com/android/cts/deviceowner/KeyManagementActivity.java
copy to tests/tests/neuralnetworks/src/TestUnknownDimensions.cpp
index fda124f..764d9b8 100644
--- a/hostsidetests/devicepolicy/app/DeviceOwner/src/com/android/cts/deviceowner/KeyManagementActivity.java
+++ b/tests/tests/neuralnetworks/src/TestUnknownDimensions.cpp
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2014 The Android Open Source Project
+ * 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.
@@ -14,9 +14,5 @@
  * limitations under the License.
  */
 
-package com.android.cts.deviceowner;
-
-import android.app.Activity;
-
-public class KeyManagementActivity extends Activity {
-}
+// Include corresponding NNAPI unit tests in frameworks/ml/nn/runtime/test
+#include "test/TestUnknownDimensions.cpp"
diff --git a/hostsidetests/devicepolicy/app/DeviceOwner/src/com/android/cts/deviceowner/KeyManagementActivity.java b/tests/tests/neuralnetworks/src/TestWrapper.cpp
similarity index 75%
copy from hostsidetests/devicepolicy/app/DeviceOwner/src/com/android/cts/deviceowner/KeyManagementActivity.java
copy to tests/tests/neuralnetworks/src/TestWrapper.cpp
index fda124f..f77963b 100644
--- a/hostsidetests/devicepolicy/app/DeviceOwner/src/com/android/cts/deviceowner/KeyManagementActivity.java
+++ b/tests/tests/neuralnetworks/src/TestWrapper.cpp
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2014 The Android Open Source Project
+ * 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.
@@ -14,9 +14,5 @@
  * limitations under the License.
  */
 
-package com.android.cts.deviceowner;
-
-import android.app.Activity;
-
-public class KeyManagementActivity extends Activity {
-}
+// Include corresponding NNAPI unit tests in frameworks/ml/nn/runtime/test
+#include "test/TestWrapper.cpp"
diff --git a/tests/tests/openglperf/src/android/openglperf/cts/GlVboPerfTest.java b/tests/tests/openglperf/src/android/openglperf/cts/GlVboPerfTest.java
index 80cf3c2..f3a38bb 100644
--- a/tests/tests/openglperf/src/android/openglperf/cts/GlVboPerfTest.java
+++ b/tests/tests/openglperf/src/android/openglperf/cts/GlVboPerfTest.java
@@ -28,8 +28,8 @@
     private static final long RENDERING_TIMEOUT = 5 * 60;
     // 30% of fps_no_vbo is allowed to compensate variations in measurement
     private static final float FPS_COMPARISON_MARGIN = 0.3f;
-    // the worst case should be above 70% of the best case
-    private static final float FPS_MIN_MAX_COMPARISON_PERCENTILE = 0.7f;
+    // the worst case should be above 30% of the best case
+    private static final float FPS_MIN_MAX_COMPARISON_PERCENTILE = 0.3f;
 
     private float mFps;
     private int mNumTriangles;
diff --git a/tests/tests/os/src/android/os/cts/SecurityPatchTest.java b/tests/tests/os/src/android/os/cts/SecurityPatchTest.java
index d6fb646..da72966 100644
--- a/tests/tests/os/src/android/os/cts/SecurityPatchTest.java
+++ b/tests/tests/os/src/android/os/cts/SecurityPatchTest.java
@@ -30,17 +30,21 @@
 
     private static final String TAG = SecurityPatchTest.class.getSimpleName();
     private static final String SECURITY_PATCH_ERROR =
-            "ro.build.version.security_patch should be in the format \"YYYY-MM-DD\". Found \"%s\"";
+            "security_patch should be in the format \"YYYY-MM-DD\". Found \"%s\"";
     private static final String SECURITY_PATCH_DATE_ERROR =
-            "ro.build.version.security_patch should be \"%d-%02d\" or later. Found \"%s\"";
+            "security_patch should be \"%d-%02d\" or later. Found \"%s\"";
     private static final int SECURITY_PATCH_YEAR = 2016;
     private static final int SECURITY_PATCH_MONTH = 12;
 
     private boolean mSkipTests = false;
+    private String mVendorSecurityPatch;
+    private String mBuildSecurityPatch;
 
     @Override
     protected void setUp() {
         mSkipTests = (ApiLevelUtil.isBefore(Build.VERSION_CODES.M));
+        mVendorSecurityPatch = SystemProperties.get("ro.vendor.build.security_patch", "");
+        mBuildSecurityPatch = Build.VERSION.SECURITY_PATCH;
     }
 
     /** Security patch string must exist in M or higher **/
@@ -49,54 +53,79 @@
             Log.w(TAG, "Skipping M+ Test.");
             return;
         }
+        String error = String.format(SECURITY_PATCH_ERROR, mBuildSecurityPatch);
+        assertTrue(error, !mBuildSecurityPatch.isEmpty());
+    }
 
-        String buildSecurityPatch = Build.VERSION.SECURITY_PATCH;
-        String error = String.format(SECURITY_PATCH_ERROR, buildSecurityPatch);
-        assertTrue(error, !buildSecurityPatch.isEmpty());
+    public void testVendorSecurityPatchFound() {
+        if (Build.VERSION.FIRST_SDK_INT <= Build.VERSION_CODES.O) {
+            Log.w(TAG, "Skipping P+ Test");
+            return;
+        }
+        assertTrue(!mVendorSecurityPatch.isEmpty());
+    }
+
+    public void testSecurityPatchesFormat() {
+        if (mSkipTests) {
+            Log.w(TAG, "Skipping M+ Test.");
+            return;
+        }
+        String error = String.format(SECURITY_PATCH_ERROR, mBuildSecurityPatch);
+        testSecurityPatchFormat(mBuildSecurityPatch, error);
+
+        if (Build.VERSION.FIRST_SDK_INT <= Build.VERSION_CODES.O) {
+            Log.w(TAG, "Skipping P+ Test");
+            return;
+        }
+        error = String.format(SECURITY_PATCH_ERROR, mVendorSecurityPatch);
+        testSecurityPatchFormat(mVendorSecurityPatch, error);
     }
 
     /** Security patch should be of the form YYYY-MM-DD in M or higher */
-    public void testSecurityPatchFormat() {
-        if (mSkipTests) {
-            Log.w(TAG, "Skipping M+ Test.");
-            return;
-        }
-
-        String buildSecurityPatch = Build.VERSION.SECURITY_PATCH;
-        String error = String.format(SECURITY_PATCH_ERROR, buildSecurityPatch);
-
-        assertEquals(error, 10, buildSecurityPatch.length());
-        assertTrue(error, Character.isDigit(buildSecurityPatch.charAt(0)));
-        assertTrue(error, Character.isDigit(buildSecurityPatch.charAt(1)));
-        assertTrue(error, Character.isDigit(buildSecurityPatch.charAt(2)));
-        assertTrue(error, Character.isDigit(buildSecurityPatch.charAt(3)));
-        assertEquals(error, '-', buildSecurityPatch.charAt(4));
-        assertTrue(error, Character.isDigit(buildSecurityPatch.charAt(5)));
-        assertTrue(error, Character.isDigit(buildSecurityPatch.charAt(6)));
-        assertEquals(error, '-', buildSecurityPatch.charAt(7));
-        assertTrue(error, Character.isDigit(buildSecurityPatch.charAt(8)));
-        assertTrue(error, Character.isDigit(buildSecurityPatch.charAt(9)));
+    private void testSecurityPatchFormat(String patch, String error) {
+        assertEquals(error, 10, patch.length());
+        assertTrue(error, Character.isDigit(patch.charAt(0)));
+        assertTrue(error, Character.isDigit(patch.charAt(1)));
+        assertTrue(error, Character.isDigit(patch.charAt(2)));
+        assertTrue(error, Character.isDigit(patch.charAt(3)));
+        assertEquals(error, '-', patch.charAt(4));
+        assertTrue(error, Character.isDigit(patch.charAt(5)));
+        assertTrue(error, Character.isDigit(patch.charAt(6)));
+        assertEquals(error, '-', patch.charAt(7));
+        assertTrue(error, Character.isDigit(patch.charAt(8)));
+        assertTrue(error, Character.isDigit(patch.charAt(9)));
     }
 
-    /** Security patch should no older than the month this test was updated in M or higher **/
-    public void testSecurityPatchDate() {
+    public void testSecurityPatchDates() {
         if (mSkipTests) {
             Log.w(TAG, "Skipping M+ Test.");
             return;
         }
 
-        String buildSecurityPatch = Build.VERSION.SECURITY_PATCH;
         String error = String.format(SECURITY_PATCH_DATE_ERROR,
                                      SECURITY_PATCH_YEAR,
                                      SECURITY_PATCH_MONTH,
-                                     buildSecurityPatch);
+                                     mBuildSecurityPatch);
+        testSecurityPatchDate(mBuildSecurityPatch, error);
 
+        if (Build.VERSION.FIRST_SDK_INT <= Build.VERSION_CODES.O) {
+            Log.w(TAG, "Skipping P+ Test");
+            return;
+        }
+        error = String.format(SECURITY_PATCH_DATE_ERROR,
+                                     SECURITY_PATCH_YEAR,
+                                     SECURITY_PATCH_MONTH,
+                                     mVendorSecurityPatch);
+        testSecurityPatchDate(mVendorSecurityPatch, error);
+    }
+    /** Security patch should no older than the month this test was updated in M or higher **/
+    private void testSecurityPatchDate(String patch, String error) {
         int declaredYear = 0;
         int declaredMonth = 0;
 
         try {
-            declaredYear = Integer.parseInt(buildSecurityPatch.substring(0,4));
-            declaredMonth = Integer.parseInt(buildSecurityPatch.substring(5,7));
+            declaredYear = Integer.parseInt(patch.substring(0,4));
+            declaredMonth = Integer.parseInt(patch.substring(5,7));
         } catch (Exception e) {
             assertTrue(error, false);
         }
diff --git a/tests/tests/os/src/android/os/cts/StrictModeTest.java b/tests/tests/os/src/android/os/cts/StrictModeTest.java
index ceac035..dc868fc 100644
--- a/tests/tests/os/src/android/os/cts/StrictModeTest.java
+++ b/tests/tests/os/src/android/os/cts/StrictModeTest.java
@@ -18,6 +18,8 @@
 
 import static com.google.common.truth.Truth.assertThat;
 import static com.google.common.truth.Truth.assertWithMessage;
+
+import static org.junit.Assert.assertTrue;
 import static org.junit.Assert.fail;
 
 import android.content.ComponentName;
@@ -32,12 +34,21 @@
 import android.os.StrictMode;
 import android.os.StrictMode.ThreadPolicy.Builder;
 import android.os.StrictMode.ViolationInfo;
+import android.os.strictmode.CustomViolation;
+import android.os.strictmode.FileUriExposedViolation;
 import android.os.strictmode.UntaggedSocketViolation;
+import android.os.strictmode.Violation;
 import android.support.test.InstrumentationRegistry;
 import android.support.test.runner.AndroidJUnit4;
 import android.system.Os;
 import android.system.OsConstants;
 import android.util.Log;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
 import java.io.File;
 import java.io.FileDescriptor;
 import java.io.FileInputStream;
@@ -56,10 +67,6 @@
 import java.util.concurrent.LinkedBlockingQueue;
 import java.util.concurrent.TimeUnit;
 import java.util.function.Consumer;
-import org.junit.After;
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
 
 /** Tests for {@link StrictMode} */
 @RunWith(AndroidJUnit4.class)
@@ -473,22 +480,66 @@
 
     @Test
     public void testNonSdkApiUsage() throws Exception {
-        StrictMode.VmPolicy oldPolicy = StrictMode.getVmPolicy();
+        StrictMode.VmPolicy oldVmPolicy = StrictMode.getVmPolicy();
+        StrictMode.ThreadPolicy oldThreadPolicy = StrictMode.getThreadPolicy();
         try {
             StrictMode.setVmPolicy(
                     new StrictMode.VmPolicy.Builder().detectNonSdkApiUsage().build());
             checkNonSdkApiUsageViolation(
                 true, "dalvik.system.VMRuntime", "setHiddenApiExemptions", String[].class);
             // verify that mutliple uses of a light greylist API are detected.
-            Log.i(TAG, "testNonSdkApiUsage: dalvik.system.VMRuntime.getRuntime: first try");
             checkNonSdkApiUsageViolation(false, "dalvik.system.VMRuntime", "getRuntime");
-            Log.i(TAG, "testNonSdkApiUsage: dalvik.system.VMRuntime.getRuntime: second try");
             checkNonSdkApiUsageViolation(false, "dalvik.system.VMRuntime", "getRuntime");
+
+            // Verify that the VM policy is turned off after a call to permitNonSdkApiUsage.
+            StrictMode.setVmPolicy(
+                new StrictMode.VmPolicy.Builder().permitNonSdkApiUsage().build());
+            assertNoViolation(() -> {
+                  Class<?> clazz = Class.forName("dalvik.system.VMRuntime");
+                  try {
+                      clazz.getDeclaredMethod("getRuntime");
+                  } catch (NoSuchMethodException maybe) {
+                  }
+            });
         } finally {
-            StrictMode.setVmPolicy(oldPolicy);
+            StrictMode.setVmPolicy(oldVmPolicy);
+            StrictMode.setThreadPolicy(oldThreadPolicy);
         }
     }
 
+    @Test
+    public void testThreadPenaltyListener() throws Exception {
+        final BlockingQueue<Violation> violations = new ArrayBlockingQueue<>(1);
+        StrictMode.setThreadPolicy(
+                new StrictMode.ThreadPolicy.Builder().detectCustomSlowCalls()
+                        .penaltyListener(getContext().getMainExecutor(), (v) -> {
+                            violations.add(v);
+                        }).build());
+
+        StrictMode.noteSlowCall("foo");
+
+        final Violation v = violations.poll(5, TimeUnit.SECONDS);
+        assertTrue(v instanceof CustomViolation);
+    }
+
+    @Test
+    public void testVmPenaltyListener() throws Exception {
+        final BlockingQueue<Violation> violations = new ArrayBlockingQueue<>(1);
+        StrictMode.setVmPolicy(
+                new StrictMode.VmPolicy.Builder().detectFileUriExposure()
+                        .penaltyListener(getContext().getMainExecutor(), (v) -> {
+                            violations.add(v);
+                        }).build());
+
+        Intent intent = new Intent(Intent.ACTION_VIEW);
+        intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+        intent.setDataAndType(Uri.fromFile(new File("/sdcard/meow.jpg")), "image/jpeg");
+        getContext().startActivity(intent);
+
+        final Violation v = violations.poll(5, TimeUnit.SECONDS);
+        assertTrue(v instanceof FileUriExposedViolation);
+    }
+
     private static void runWithRemoteServiceBound(Context context, Consumer<ISecondary> consumer)
             throws ExecutionException, InterruptedException, RemoteException {
         BlockingQueue<IBinder> binderHolder = new ArrayBlockingQueue<>(1);
diff --git a/tests/tests/permission/src/android/permission/cts/ObserveAppUsagePermissionTest.java b/tests/tests/permission/src/android/permission/cts/ObserveAppUsagePermissionTest.java
deleted file mode 100644
index 720797e..0000000
--- a/tests/tests/permission/src/android/permission/cts/ObserveAppUsagePermissionTest.java
+++ /dev/null
@@ -1,52 +0,0 @@
-/*
- * Copyright (C) 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package android.permission.cts;
-
-import static android.Manifest.permission.OBSERVE_APP_USAGE;
-
-import static org.junit.Assert.assertTrue;
-
-import android.content.pm.PackageInfo;
-import android.content.pm.PackageManager;
-import android.support.test.InstrumentationRegistry;
-import android.support.test.filters.SmallTest;
-import android.support.test.runner.AndroidJUnit4;
-
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-
-import java.util.List;
-
-@SmallTest
-@RunWith(AndroidJUnit4.class)
-public class ObserveAppUsagePermissionTest {
-
-    private PackageManager mPackageManager;
-
-    @Before
-    public void setUp() {
-        mPackageManager = InstrumentationRegistry.getTargetContext().getPackageManager();
-    }
-
-    @Test
-    public void testNumberOfAppsWithPermission() {
-        final List<PackageInfo> packagesWithPerm = mPackageManager.getPackagesHoldingPermissions(
-                new String[]{OBSERVE_APP_USAGE}, 0);
-        assertTrue("At most one app can hold the permission " + OBSERVE_APP_USAGE
-                + ", but found more: " + packagesWithPerm, packagesWithPerm.size() <= 1);
-    }
-}
diff --git a/tests/tests/permission2/res/raw/android_manifest.xml b/tests/tests/permission2/res/raw/android_manifest.xml
index 39ca729..95cfdff 100644
--- a/tests/tests/permission2/res/raw/android_manifest.xml
+++ b/tests/tests/permission2/res/raw/android_manifest.xml
@@ -1423,6 +1423,13 @@
     <permission android:name="android.permission.NETWORK_SETTINGS"
         android:protectionLevel="signature" />
 
+    <!-- Allows SetupWizard to call methods in Networking services
+         <p>Not for use by any other third-party or privileged applications.
+         @hide This should only be used by SetupWizard.
+    -->
+    <permission android:name="android.permission.NETWORK_SETUP_WIZARD"
+        android:protectionLevel="signature|setup" />
+
     <!-- #SystemApi @hide Allows applications to access information about LoWPAN interfaces.
          <p>Not for use by third-party applications. -->
     <permission android:name="android.permission.ACCESS_LOWPAN_STATE"
@@ -1450,6 +1457,11 @@
     <permission android:name="android.permission.MANAGE_WIFI_WHEN_PERMISSION_REVIEW_REQUIRED"
         android:protectionLevel="signature" />
 
+    <!-- @hide Allows an app to bypass Private DNS.
+         <p>Not for use by third-party applications. -->
+    <permission android:name="android.permission.NETWORK_BYPASS_PRIVATE_DNS"
+        android:protectionLevel="signature" />
+
     <!-- ======================================= -->
     <!-- Permissions for short range, peripheral networks -->
     <!-- ======================================= -->
@@ -4230,7 +4242,7 @@
         <receiver android:name="com.android.server.updates.CarrierIdInstallReceiver"
                   android:permission="android.permission.UPDATE_CONFIG">
             <intent-filter>
-                <action android:name="com.android.internal.intent.action.UPDATE_CARRIER_ID_DB" />
+                <action android:name="android.os.action.UPDATE_CARRIER_ID_DB" />
                 <data android:scheme="content" android:host="*" android:mimeType="*/*" />
             </intent-filter>
         </receiver>
diff --git a/tests/tests/permission2/src/android/permission2/cts/ProtectedBroadcastsTest.java b/tests/tests/permission2/src/android/permission2/cts/ProtectedBroadcastsTest.java
index be999f5..1b1e669 100644
--- a/tests/tests/permission2/src/android/permission2/cts/ProtectedBroadcastsTest.java
+++ b/tests/tests/permission2/src/android/permission2/cts/ProtectedBroadcastsTest.java
@@ -17,6 +17,7 @@
 package android.permission2.cts;
 
 import android.content.Intent;
+import android.content.pm.PackageManager;
 import android.test.AndroidTestCase;
 
 /**
@@ -47,21 +48,7 @@
         Intent.ACTION_SHUTDOWN,
         Intent.ACTION_DEVICE_STORAGE_LOW,
         Intent.ACTION_DEVICE_STORAGE_OK,
-        Intent.ACTION_NEW_OUTGOING_CALL,
         Intent.ACTION_REBOOT,
-        "android.intent.action.SERVICE_STATE",
-        "android.intent.action.RADIO_TECHNOLOGY",
-        "android.intent.action.EMERGENCY_CALLBACK_MODE_CHANGED",
-        "android.intent.action.SIG_STR",
-        "android.intent.action.ANY_DATA_STATE",
-        "android.intent.action.DATA_CONNECTION_FAILED",
-        "android.intent.action.SIM_STATE_CHANGED",
-        "android.intent.action.NETWORK_SET_TIME",
-        "android.intent.action.NETWORK_SET_TIMEZONE",
-        "com.android.internal.intent.action.ACTION_SHOW_NOTICE_ECM_BLOCK_OTHERS",
-        "android.intent.action.ACTION_MDN_STATE_CHANGED",
-        "android.provider.Telephony.SPN_STRINGS_UPDATED",
-        "android.intent.action.ANY_DATA_STATE",
         "com.android.server.WifiManager.action.START_SCAN",
         "com.android.server.WifiManager.action.DELAYED_DRIVER_STOP",
         "android.net.wifi.WIFI_STATE_CHANGED",
@@ -82,10 +69,26 @@
         "android.net.conn.TETHER_STATE_CHANGED",
         "android.net.conn.INET_CONDITION_ACTION",
         "android.net.conn.CAPTIVE_PORTAL_TEST_COMPLETED",
-        "android.telephony.action.SUBSCRIPTION_CARRIER_IDENTITY_CHANGED",
         "com.android.server.InputMethodManagerService.SHOW_INPUT_METHOD_PICKER"
     };
 
+    private static final String BROADCASTS_TELEPHONY[] = new String[] {
+        Intent.ACTION_NEW_OUTGOING_CALL,
+        "android.intent.action.SERVICE_STATE",
+        "android.intent.action.SIG_STR",
+        "android.intent.action.RADIO_TECHNOLOGY",
+        "android.intent.action.ANY_DATA_STATE",
+        "android.intent.action.ACTION_MDN_STATE_CHANGED",
+        "android.provider.Telephony.SPN_STRINGS_UPDATED",
+        "android.intent.action.EMERGENCY_CALLBACK_MODE_CHANGED",
+        "android.intent.action.SIM_STATE_CHANGED",
+        "android.intent.action.DATA_CONNECTION_FAILED",
+        "android.intent.action.NETWORK_SET_TIME",
+        "android.intent.action.NETWORK_SET_TIMEZONE",
+        "com.android.internal.intent.action.ACTION_SHOW_NOTICE_ECM_BLOCK_OTHERS",
+        "android.telephony.action.SUBSCRIPTION_CARRIER_IDENTITY_CHANGED",
+    };
+
     /**
      * Verify that protected broadcast actions can't be sent.
      */
@@ -100,4 +103,19 @@
             }
         }
     }
+
+    public void testSendProtectedTelephonyBroadcasts() {
+        if (!getContext().getPackageManager().hasSystemFeature(PackageManager.FEATURE_TELEPHONY)) {
+            return;
+        }
+        for (String action : BROADCASTS_TELEPHONY) {
+            try {
+                Intent intent = new Intent(action);
+                getContext().sendBroadcast(intent);
+                fail("expected security exception broadcasting telephony action: " + action);
+            } catch (SecurityException expected) {
+                assertNotNull("security exception's error message.", expected.getMessage());
+            }
+        }
+    }
 }
diff --git a/tests/tests/preference/AndroidManifest.xml b/tests/tests/preference/AndroidManifest.xml
index e5fd710..b0a60ed 100644
--- a/tests/tests/preference/AndroidManifest.xml
+++ b/tests/tests/preference/AndroidManifest.xml
@@ -16,7 +16,8 @@
  -->
 
 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
-    package="android.preference.cts">
+    package="android.preference.cts"
+    android:targetSandboxVersion="2">
 
     <uses-permission android:name="android.permission.DISABLE_KEYGUARD" />
     <application>
diff --git a/tests/tests/preference2/AndroidManifest.xml b/tests/tests/preference2/AndroidManifest.xml
index 50e1ea9..e6929c3 100644
--- a/tests/tests/preference2/AndroidManifest.xml
+++ b/tests/tests/preference2/AndroidManifest.xml
@@ -15,7 +15,8 @@
 -->
 
 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
-    package="android.preference2.cts">
+    package="android.preference2.cts"
+    android:targetSandboxVersion="2">
 
     <uses-permission android:name="android.permission.DISABLE_KEYGUARD" />
     <application>
diff --git a/tests/tests/provider/src/android/provider/cts/MediaStore_Video_ThumbnailsTest.java b/tests/tests/provider/src/android/provider/cts/MediaStore_Video_ThumbnailsTest.java
index 8b62530..c256722 100644
--- a/tests/tests/provider/src/android/provider/cts/MediaStore_Video_ThumbnailsTest.java
+++ b/tests/tests/provider/src/android/provider/cts/MediaStore_Video_ThumbnailsTest.java
@@ -125,6 +125,13 @@
     }
 
     public void testThumbnailGenerationAndCleanup() throws Exception {
+
+        if (!hasCodec()) {
+            // we don't support video, so no need to run the test
+            Log.i(TAG, "SKIPPING testThumbnailGenerationAndCleanup(): codec not supported");
+            return;
+        }
+
         // insert a video
         Uri uri = insertVideo();
 
diff --git a/tests/tests/secure_element/access_control/Android.mk b/tests/tests/secure_element/access_control/Android.mk
index 5c7187e..f776e48 100644
--- a/tests/tests/secure_element/access_control/Android.mk
+++ b/tests/tests/secure_element/access_control/Android.mk
@@ -12,5 +12,9 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 
+cts_out_dir := $(HOST_OUT)/cts/android-cts/testcases
+$(call dist-for-goals,cts,$(cts_out_dir)/CtsSecureElementAccessControlTestCases1.apk)
+$(call dist-for-goals,cts,$(cts_out_dir)/CtsSecureElementAccessControlTestCases2.apk)
+$(call dist-for-goals,cts,$(cts_out_dir)/CtsSecureElementAccessControlTestCases3.apk)
 include $(call all-subdir-makefiles)
 
diff --git a/tests/tests/security/res/raw/bug_23452792.webm b/tests/tests/security/res/raw/bug_23452792.webm
new file mode 100644
index 0000000..ff70fc0
--- /dev/null
+++ b/tests/tests/security/res/raw/bug_23452792.webm
Binary files differ
diff --git a/tests/tests/security/res/raw/cve_2016_0815.mp4 b/tests/tests/security/res/raw/cve_2016_0815.mp4
new file mode 100755
index 0000000..0fea03f
--- /dev/null
+++ b/tests/tests/security/res/raw/cve_2016_0815.mp4
Binary files differ
diff --git a/tests/tests/security/res/raw/cve_2016_0824.mp4 b/tests/tests/security/res/raw/cve_2016_0824.mp4
new file mode 100644
index 0000000..3e567b4
--- /dev/null
+++ b/tests/tests/security/res/raw/cve_2016_0824.mp4
Binary files differ
diff --git a/tests/tests/security/res/raw/cve_2016_2454.webm b/tests/tests/security/res/raw/cve_2016_2454.webm
new file mode 100755
index 0000000..a811ba2
--- /dev/null
+++ b/tests/tests/security/res/raw/cve_2016_2454.webm
Binary files differ
diff --git a/tests/tests/security/res/raw/cve_2016_3741.mp4 b/tests/tests/security/res/raw/cve_2016_3741.mp4
new file mode 100755
index 0000000..6171153
--- /dev/null
+++ b/tests/tests/security/res/raw/cve_2016_3741.mp4
Binary files differ
diff --git a/tests/tests/security/res/raw/cve_2016_3820.mp4 b/tests/tests/security/res/raw/cve_2016_3820.mp4
new file mode 100755
index 0000000..488e987
--- /dev/null
+++ b/tests/tests/security/res/raw/cve_2016_3820.mp4
Binary files differ
diff --git a/tests/tests/security/res/raw/cve_2016_6765.mp4 b/tests/tests/security/res/raw/cve_2016_6765.mp4
new file mode 100644
index 0000000..d95eefa
--- /dev/null
+++ b/tests/tests/security/res/raw/cve_2016_6765.mp4
Binary files differ
diff --git a/tests/tests/security/res/raw/cve_2016_6766.mp4 b/tests/tests/security/res/raw/cve_2016_6766.mp4
new file mode 100644
index 0000000..4370dfb
--- /dev/null
+++ b/tests/tests/security/res/raw/cve_2016_6766.mp4
Binary files differ
diff --git a/tests/tests/security/src/android/security/cts/StagefrightTest.java b/tests/tests/security/src/android/security/cts/StagefrightTest.java
index c046fd3..7d255a0 100755
--- a/tests/tests/security/src/android/security/cts/StagefrightTest.java
+++ b/tests/tests/security/src/android/security/cts/StagefrightTest.java
@@ -239,6 +239,11 @@
     }
 
     @SecurityTest
+    public void testStagefright_cve_2016_6766() throws Exception {
+        doStagefrightTest(R.raw.cve_2016_6766);
+    }
+
+    @SecurityTest
     public void testStagefright_bug_26366256() throws Exception {
         doStagefrightTest(R.raw.bug_26366256);
     }
@@ -524,6 +529,21 @@
     }
 
     @SecurityTest
+    public void testStagefright_bug_23452792() throws Exception {
+        doStagefrightTest(R.raw.bug_23452792);
+    }
+
+    @SecurityTest
+    public void testStagefright_cve_2016_3820() throws Exception {
+        doStagefrightTest(R.raw.cve_2016_3820);
+    }
+
+    @SecurityTest
+    public void testStagefright_cve_2016_3741() throws Exception {
+        doStagefrightTest(R.raw.cve_2016_3741);
+    }
+
+    @SecurityTest
     public void testStagefright_bug_36592202() throws Exception {
         Resources resources = getInstrumentation().getContext().getResources();
         AssetFileDescriptor fd = resources.openRawResourceFd(R.raw.bug_36592202);
@@ -731,6 +751,26 @@
         bitmap.recycle();
     }
 
+    @SecurityTest
+    public void testStagefright_cve_2016_0824() throws Exception {
+        doStagefrightTest(R.raw.cve_2016_0824);
+    }
+
+    @SecurityTest
+    public void testStagefright_cve_2016_0815() throws Exception {
+        doStagefrightTest(R.raw.cve_2016_0815);
+    }
+
+    @SecurityTest
+    public void testStagefright_cve_2016_2454() throws Exception {
+        doStagefrightTest(R.raw.cve_2016_2454);
+    }
+
+    @SecurityTest
+    public void testStagefright_cve_2016_6765() throws Exception {
+        doStagefrightTest(R.raw.cve_2016_6765);
+    }
+
     private void doStagefrightTest(final int rid) throws Exception {
         doStagefrightTestMediaPlayer(rid);
         doStagefrightTestMediaCodec(rid);
@@ -1471,8 +1511,14 @@
             Log.i(TAG, "Decoding blob " + rname + " using codec " + codecName);
             MediaCodec codec = MediaCodec.createByCodecName(codecName);
             MediaFormat format = MediaFormat.createVideoFormat(mime, initWidth, initHeight);
-            codec.configure(format, null, null, 0);
-            codec.start();
+            try {
+                codec.configure(format, null, null, 0);
+                codec.start();
+            } catch (Exception e) {
+                Log.i(TAG, "Exception from codec " + codecName);
+                releaseCodec(codec);
+                continue;
+            }
 
             try {
                 MediaCodec.BufferInfo info = new MediaCodec.BufferInfo();
diff --git a/tests/tests/speech/src/android/speech/tts/cts/StubTextToSpeechService.java b/tests/tests/speech/src/android/speech/tts/cts/StubTextToSpeechService.java
index 6b3abf6..4665644 100644
--- a/tests/tests/speech/src/android/speech/tts/cts/StubTextToSpeechService.java
+++ b/tests/tests/speech/src/android/speech/tts/cts/StubTextToSpeechService.java
@@ -113,7 +113,7 @@
     public String onGetDefaultVoiceNameFor(String lang, String country, String variant) {
         Locale locale = new Locale(lang, country);
         if (supportedCountries.contains(locale)) {
-          return TtsEngines.normalizeTTSLocale(locale).toLanguageTag();
+            return locale.toLanguageTag();
         }
         if (lang.equals("eng")) {
             if (GBFallbacks.contains(new Locale(lang, country))) {
diff --git a/tests/tests/speech/src/android/speech/tts/cts/TextToSpeechTest.java b/tests/tests/speech/src/android/speech/tts/cts/TextToSpeechTest.java
deleted file mode 100644
index c117745..0000000
--- a/tests/tests/speech/src/android/speech/tts/cts/TextToSpeechTest.java
+++ /dev/null
@@ -1,181 +0,0 @@
-/*
- * Copyright (C) 2009 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.speech.tts.cts;
-
-import android.content.pm.PackageManager;
-import android.os.Environment;
-import android.speech.tts.TextToSpeech;
-import android.test.AndroidTestCase;
-
-import java.io.File;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Locale;
-
-/**
- * Tests for {@link android.speech.tts.TextToSpeech}
- */
-public class TextToSpeechTest extends AndroidTestCase {
-    private static final String SAMPLE_TEXT = "This is a sample text to speech string";
-    private static final String SAMPLE_FILE_NAME = "mytts.wav";
-
-    private TextToSpeechWrapper mTts;
-
-    @Override
-    protected void setUp() throws Exception {
-        super.setUp();
-        mTts = TextToSpeechWrapper.createTextToSpeechWrapper(getContext());
-        if (mTts == null) {
-            PackageManager pm = getContext().getPackageManager();
-            if (!pm.hasSystemFeature(PackageManager.FEATURE_AUDIO_OUTPUT)) {
-                // It is OK to have no TTS, when audio-out is not supported.
-                return;
-            } else {
-                fail("FEATURE_AUDIO_OUTPUT is set, but there is no TTS engine");
-            }
-        }
-        assertNotNull(mTts);
-        assertTrue(checkAndSetLanguageAvailable());
-    }
-
-    @Override
-    protected void tearDown() throws Exception {
-        super.tearDown();
-        if (mTts != null) {
-            mTts.shutdown();
-        }
-    }
-
-    private TextToSpeech getTts() {
-        return mTts.getTts();
-    }
-
-    /**
-     * Ensures at least one language is available for tts
-     */
-    private boolean checkAndSetLanguageAvailable() {
-        // checks if at least one language is available in Tts
-        final Locale defaultLocale = Locale.getDefault();
-        // If the language for the default locale is available, then
-        // use that.
-        int defaultAvailability = getTts().isLanguageAvailable(defaultLocale);
-
-        if (defaultAvailability == TextToSpeech.LANG_AVAILABLE ||
-            defaultAvailability == TextToSpeech.LANG_COUNTRY_AVAILABLE ||
-            defaultAvailability == TextToSpeech.LANG_COUNTRY_VAR_AVAILABLE) {
-            getTts().setLanguage(defaultLocale);
-            return true;
-        }
-
-        for (Locale locale : Locale.getAvailableLocales()) {
-            int availability = getTts().isLanguageAvailable(locale);
-            if (availability == TextToSpeech.LANG_AVAILABLE ||
-                availability == TextToSpeech.LANG_COUNTRY_AVAILABLE ||
-                availability == TextToSpeech.LANG_COUNTRY_VAR_AVAILABLE) {
-                getTts().setLanguage(locale);
-                return true;
-            }
-        }
-        return false;
-    }
-
-    private void assertContainsEngine(String engine, List<TextToSpeech.EngineInfo> engines) {
-        for (TextToSpeech.EngineInfo engineInfo : engines) {
-            if (engineInfo.name.equals(engine)) {
-                return;
-            }
-        }
-        fail("Engine " + engine + " not found");
-    }
-
-    private HashMap<String, String> createParams(String utteranceId) {
-        HashMap<String, String> params = new HashMap<>();
-        params.put(TextToSpeech.Engine.KEY_PARAM_UTTERANCE_ID, utteranceId);
-        return params;
-    }
-
-    private boolean waitForUtterance(String utteranceId) throws InterruptedException {
-        return mTts.waitForComplete(utteranceId);
-    }
-
-    public void testSynthesizeToFile() throws Exception {
-        if (mTts == null) {
-            return;
-        }
-        File sampleFile = new File(Environment.getExternalStorageDirectory(), SAMPLE_FILE_NAME);
-        try {
-            assertFalse(sampleFile.exists());
-
-            int result = getTts().synthesizeToFile(SAMPLE_TEXT, createParams("tofile"),
-                    sampleFile.getPath());
-            assertEquals("synthesizeToFile() failed", TextToSpeech.SUCCESS, result);
-
-            assertTrue("synthesizeToFile() completion timeout", waitForUtterance("tofile"));
-            assertTrue("synthesizeToFile() didn't produce a file", sampleFile.exists());
-            assertTrue("synthesizeToFile() produced a non-sound file",
-                    TextToSpeechWrapper.isSoundFile(sampleFile.getPath()));
-        } finally {
-            sampleFile.delete();
-        }
-        mTts.verify("tofile");
-    }
-
-    public void testSpeak() throws Exception {
-        if (mTts == null) {
-            return;
-        }
-        int result = getTts().speak(SAMPLE_TEXT, TextToSpeech.QUEUE_FLUSH, createParams("speak"));
-        assertEquals("speak() failed", TextToSpeech.SUCCESS, result);
-        assertTrue("speak() completion timeout", waitForUtterance("speak"));
-        mTts.verify("speak");
-    }
-
-    public void testSpeakStop() throws Exception {
-        if (mTts == null) {
-            return;
-        }
-        getTts().stop();
-        final int iterations = 20;
-        for (int i = 0; i < iterations; i++) {
-            int result = getTts().speak(SAMPLE_TEXT, TextToSpeech.QUEUE_ADD, null,
-                    "stop_" + Integer.toString(i));
-            assertEquals("speak() failed", TextToSpeech.SUCCESS, result);
-        }
-        getTts().stop();
-        for (int i = 0; i < iterations; i++) {
-            assertTrue("speak() stop callback timeout", mTts.waitForStop(
-                    "stop_" + Integer.toString(i)));
-        }
-    }
-
-    public void testGetEnginesIncludesDefault() throws Exception {
-        if (mTts == null) {
-            return;
-        }
-        List<TextToSpeech.EngineInfo> engines = getTts().getEngines();
-        assertNotNull("getEngines() returned null", engines);
-        assertContainsEngine(getTts().getDefaultEngine(), engines);
-    }
-
-    public void testGetEnginesIncludesMock() throws Exception {
-        if (mTts == null) {
-            return;
-        }
-        List<TextToSpeech.EngineInfo> engines = getTts().getEngines();
-        assertNotNull("getEngines() returned null", engines);
-        assertContainsEngine(TextToSpeechWrapper.MOCK_TTS_ENGINE, engines);
-    }
-}
diff --git a/tests/tests/syncmanager/AndroidTest.xml b/tests/tests/syncmanager/AndroidTest.xml
index 1e80dfe..0668895 100644
--- a/tests/tests/syncmanager/AndroidTest.xml
+++ b/tests/tests/syncmanager/AndroidTest.xml
@@ -31,6 +31,7 @@
     </target_preparer>
 
     <target_preparer class="com.android.tradefed.targetprep.RunCommandTargetPreparer">
+        <option name="run-command" value="am wait-for-broadcast-idle" />
         <option name="run-command" value="am set-standby-bucket android.content.syncmanager.cts.app1 10" />
         <option name="run-command" value="am set-standby-bucket android.content.syncmanager.cts.app2 10" />
         <option name="run-command" value="setprop log.tag.SyncManager VERBOSE" />
diff --git a/tests/tests/syncmanager/src/android/content/syncmanager/cts/CtsSyncManagerTest.java b/tests/tests/syncmanager/src/android/content/syncmanager/cts/CtsSyncManagerTest.java
index c77abff..c70dcbe 100644
--- a/tests/tests/syncmanager/src/android/content/syncmanager/cts/CtsSyncManagerTest.java
+++ b/tests/tests/syncmanager/src/android/content/syncmanager/cts/CtsSyncManagerTest.java
@@ -23,7 +23,6 @@
 import static com.android.compatibility.common.util.ConnectivityUtils.assertNetworkConnected;
 import static com.android.compatibility.common.util.SettingsUtils.putGlobalSetting;
 import static com.android.compatibility.common.util.SystemUtil.runCommandAndPrintOnLogcat;
-import static com.android.compatibility.common.util.TestUtils.waitUntil;
 
 import static junit.framework.TestCase.assertEquals;
 
@@ -52,6 +51,8 @@
 import com.android.compatibility.common.util.OnFailureRule;
 import com.android.compatibility.common.util.ParcelUtils;
 import com.android.compatibility.common.util.SystemUtil;
+import com.android.compatibility.common.util.TestUtils;
+import com.android.compatibility.common.util.TestUtils.BooleanSupplierWithThrow;
 
 import org.junit.After;
 import org.junit.Before;
@@ -72,6 +73,7 @@
     public static final int DEFAULT_TIMEOUT_SECONDS = 30;
 
     public static final boolean DEBUG = false;
+    private static final int TIMEOUT_MS = 10 * 60 * 1000;
 
     @Rule
     public final OnFailureRule mDumpOnFailureRule = new OnFailureRule(TAG) {
@@ -133,6 +135,10 @@
         return out;
     }
 
+    private void waitUntil(String message, BooleanSupplierWithThrow predicate) throws Exception {
+        TestUtils.waitUntil(message, TIMEOUT_MS, predicate);
+    }
+
     private void removeAllAccounts() throws Exception {
         mRpc.invoke(APP1_PACKAGE,
                 rb -> rb.setRemoveAllAccounts(RemoveAllAccounts.newBuilder()));
diff --git a/tests/tests/telecom/src/android/telecom/cts/BaseTelecomTestWithMockServices.java b/tests/tests/telecom/src/android/telecom/cts/BaseTelecomTestWithMockServices.java
index 7610176..8a4c275 100644
--- a/tests/tests/telecom/src/android/telecom/cts/BaseTelecomTestWithMockServices.java
+++ b/tests/tests/telecom/src/android/telecom/cts/BaseTelecomTestWithMockServices.java
@@ -102,7 +102,7 @@
 
         @Override
         public void onCallStateChanged(int state, String number) {
-            Log.i(TAG, "onCallStateChanged: state=" + state + ", number=%s" + number);
+            Log.i(TAG, "onCallStateChanged: state=" + state + ", number=" + number);
             mCallStates.add(Pair.create(state, number));
             mCallbackSemaphore.release();
         }
@@ -585,6 +585,26 @@
     void verifyPhoneStateListenerCallbacksForCall(int expectedCallState) throws Exception {
         assertTrue(mPhoneStateListener.mCallbackSemaphore.tryAcquire(
                 TestUtils.WAIT_FOR_PHONE_STATE_LISTENER_CALLBACK_TIMEOUT_S, TimeUnit.SECONDS));
+        // At this point we can only be sure that we got AN update, but not necessarily the one we
+        // are looking for; wait until we see the state we want before verifying further.
+        waitUntilConditionIsTrueOrTimeout(new Condition() {
+                                              @Override
+                                              public Object expected() {
+                                                  return true;
+                                              }
+
+                                              @Override
+                                              public Object actual() {
+                                                  return mPhoneStateListener.mCallStates
+                                                          .stream()
+                                                          .filter(p -> p.first.equals(
+                                                                  expectedCallState))
+                                                          .count() > 0;
+                                              }
+                                          },
+                WAIT_FOR_STATE_CHANGE_TIMEOUT_MS,
+                "Expected call state " + expectedCallState);
+
         // Get the most recent callback; it is possible that there was an initial state reported due
         // to the fact that TelephonyManager will sometimes give an initial state back to the caller
         // when the listener is registered.
diff --git a/tests/tests/telecom/src/android/telecom/cts/CallDetailsTest.java b/tests/tests/telecom/src/android/telecom/cts/CallDetailsTest.java
index cd64163..77f16ec 100644
--- a/tests/tests/telecom/src/android/telecom/cts/CallDetailsTest.java
+++ b/tests/tests/telecom/src/android/telecom/cts/CallDetailsTest.java
@@ -68,7 +68,7 @@
     public static final String TEST_EXTRA_KEY3 = "com.test.extra.TEST3";
     public static final int TEST_EXTRA_VALUE = 10;
     public static final String TEST_EVENT = "com.test.event.TEST";
-
+    public static final Uri TEST_DEFLECT_URI = Uri.fromParts("tel", "+16505551212", null);
     private StatusHints mStatusHints;
     private Bundle mExtras = new Bundle();
 
@@ -615,6 +615,25 @@
     }
 
     /**
+     * Verifies that a request to deflect a ringing {@link Call} is relayed to a {@link Connection}.
+     */
+    public void testDeflect() {
+        if (!mShouldTestTelecom) {
+            return;
+        }
+        // Only ringing calls support deflection
+        mConnection.setRinging();
+        assertCallState(mCall, Call.STATE_RINGING);
+
+        final InvokeCounter counter = mConnection.getInvokeCounter(MockConnection.ON_DEFLECT);
+        mCall.deflect(TEST_DEFLECT_URI);
+        counter.waitForCount(1, WAIT_FOR_STATE_CHANGE_TIMEOUT_MS);
+        Uri address = (Uri) (counter.getArgs(0)[0]);
+
+        assertEquals(TEST_DEFLECT_URI, address);
+    }
+
+    /**
      * Tests that {@link Call} events are propagated from {@link Call#sendCallEvent(String, Bundle)}
      * to {@link Connection#onCallEvent(String, Bundle)}.
      */
diff --git a/tests/tests/telecom/src/android/telecom/cts/ConferenceTest.java b/tests/tests/telecom/src/android/telecom/cts/ConferenceTest.java
index c1a2e76..fede567 100644
--- a/tests/tests/telecom/src/android/telecom/cts/ConferenceTest.java
+++ b/tests/tests/telecom/src/android/telecom/cts/ConferenceTest.java
@@ -178,7 +178,10 @@
         mConferenceObject.setConferenceableConnections(connectionList);
         assertCallConferenceableList(conf, callList);
 
+        // Consumed internally in Telecom; no verifiable manner to see the end point of this data
+        // through public APIs.
         mConferenceObject.setConnectionTime(0);
+        mConferenceObject.setConnectionStartElapsedRealTime(0);
 
         Bundle extras = new Bundle();
         extras.putString(TelecomManager.EXTRA_CALL_DISCONNECT_MESSAGE, "Test");
diff --git a/tests/tests/telecom/src/android/telecom/cts/CtsSelfManagedConnectionService.java b/tests/tests/telecom/src/android/telecom/cts/CtsSelfManagedConnectionService.java
index e6070ce..70f68a0 100644
--- a/tests/tests/telecom/src/android/telecom/cts/CtsSelfManagedConnectionService.java
+++ b/tests/tests/telecom/src/android/telecom/cts/CtsSelfManagedConnectionService.java
@@ -143,6 +143,7 @@
     @Override
     public void onConnectionServiceFocusLost() {
         mLocks[FOCUS_LOST_LOCK].countDown();
+        connectionServiceFocusReleased();
     }
 
     public void tearDown() {
diff --git a/tests/tests/telecom/src/android/telecom/cts/ExtendedInCallServiceTest.java b/tests/tests/telecom/src/android/telecom/cts/ExtendedInCallServiceTest.java
index ca12b34..a36c28a 100644
--- a/tests/tests/telecom/src/android/telecom/cts/ExtendedInCallServiceTest.java
+++ b/tests/tests/telecom/src/android/telecom/cts/ExtendedInCallServiceTest.java
@@ -243,6 +243,55 @@
         assertConnectionState(connection, Connection.STATE_ACTIVE);
     }
 
+    /**
+     * Verifies that the {@link TelecomManager#endCall()} API is able to end a ringing call.
+     */
+    public void testEndRingingCall() {
+        if (!mShouldTestTelecom) {
+            return;
+        }
+
+        addAndVerifyNewIncomingCall(createTestNumber(), null);
+        MockConnection connection = verifyConnectionForIncomingCall(0);
+        final MockInCallService inCallService = mInCallCallbacks.getService();
+        final Call call = inCallService.getLastCall();
+
+        assertCallState(call, Call.STATE_RINGING);
+        assertConnectionState(connection, Connection.STATE_RINGING);
+
+        mTelecomManager.endCall();
+
+        assertCallState(call, Call.STATE_DISCONNECTED);
+        assertConnectionState(connection, Connection.STATE_DISCONNECTED);
+    }
+
+    /**
+     * Verifies that the {@link TelecomManager#endCall()} API is able to end an active call.
+     */
+    public void testEndCall() {
+        if (!mShouldTestTelecom) {
+            return;
+        }
+
+        addAndVerifyNewIncomingCall(createTestNumber(), null);
+        MockConnection connection = verifyConnectionForIncomingCall(0);
+        final MockInCallService inCallService = mInCallCallbacks.getService();
+        final Call call = inCallService.getLastCall();
+
+        assertCallState(call, Call.STATE_RINGING);
+        assertConnectionState(connection, Connection.STATE_RINGING);
+
+        mTelecomManager.acceptRingingCall();
+
+        assertCallState(call, Call.STATE_ACTIVE);
+        assertConnectionState(connection, Connection.STATE_ACTIVE);
+
+        mTelecomManager.endCall();
+
+        assertCallState(call, Call.STATE_DISCONNECTED);
+        assertConnectionState(connection, Connection.STATE_DISCONNECTED);
+    }
+
 
     /**
      * Tests that if there is the device is in a call and a second call comes in,
diff --git a/tests/tests/telecom/src/android/telecom/cts/MockConnection.java b/tests/tests/telecom/src/android/telecom/cts/MockConnection.java
index da4fcf5..a761c6a 100644
--- a/tests/tests/telecom/src/android/telecom/cts/MockConnection.java
+++ b/tests/tests/telecom/src/android/telecom/cts/MockConnection.java
@@ -18,6 +18,7 @@
 
 import static android.telecom.CallAudioState.*;
 
+import android.net.Uri;
 import android.os.Bundle;
 import android.telecom.CallAudioState;
 import android.telecom.Connection;
@@ -40,6 +41,7 @@
     public static final int ON_START_RTT = 5;
     public static final int ON_RTT_REQUEST_RESPONSE = 6;
     public static final int ON_STOP_RTT = 7;
+    public static final int ON_DEFLECT = 8;
 
     private CallAudioState mCallAudioState =
             new CallAudioState(false, CallAudioState.ROUTE_EARPIECE, ROUTE_EARPIECE | ROUTE_SPEAKER);
@@ -221,6 +223,13 @@
         }
     }
 
+    @Override
+    public void onDeflect(Uri address) {
+        if (mInvokeCounterMap.get(ON_DEFLECT) != null) {
+            mInvokeCounterMap.get(ON_DEFLECT).invoke(address);
+        }
+    }
+
     public int getCurrentState()  {
         return mState;
     }
@@ -322,6 +331,8 @@
                 return "onRttRequestResponse";
             case ON_STOP_RTT:
                 return "onStopRtt";
+            case ON_DEFLECT:
+                return "onDeflect";
             default:
                 return "Callback";
         }
diff --git a/tests/tests/telecom/src/android/telecom/cts/MockConnectionService.java b/tests/tests/telecom/src/android/telecom/cts/MockConnectionService.java
index 1ce49a9..88772b0 100644
--- a/tests/tests/telecom/src/android/telecom/cts/MockConnectionService.java
+++ b/tests/tests/telecom/src/android/telecom/cts/MockConnectionService.java
@@ -160,6 +160,7 @@
     @Override
     public void onConnectionServiceFocusLost() {
         mEventLock[EVENT_CONNECTION_SERVICE_FOCUS_LOST].release();
+        connectionServiceFocusReleased();
     }
 
     public void setCreateVideoProvider(boolean createVideoProvider) {
diff --git a/tests/tests/telecom2/src/android/telecom/cts/TelecomManagerNoPermissionsTest.java b/tests/tests/telecom2/src/android/telecom/cts/TelecomManagerNoPermissionsTest.java
new file mode 100644
index 0000000..4b1c7db
--- /dev/null
+++ b/tests/tests/telecom2/src/android/telecom/cts/TelecomManagerNoPermissionsTest.java
@@ -0,0 +1,57 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+
+package android.telecom.cts;
+
+import android.content.Context;
+import android.telecom.TelecomManager;
+import android.test.InstrumentationTestCase;
+import android.text.TextUtils;
+
+/**
+ * Verifies correct operation of TelecomManager APIs when the correct permissions have not been
+ * granted.
+ */
+public class TelecomManagerNoPermissionsTest extends InstrumentationTestCase {
+    private Context mContext;
+    private TelecomManager mTelecomManager;
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+        mContext = getInstrumentation().getContext();
+        if (!TestUtils.shouldTestTelecom(mContext)) {
+            return;
+        }
+        mTelecomManager = (TelecomManager) mContext.getSystemService(Context.TELECOM_SERVICE);
+    }
+
+    @Override
+    protected void tearDown() throws Exception {
+        super.tearDown();
+    }
+
+    public void testCannotEndCall() throws Exception {
+        if (!TestUtils.shouldTestTelecom(mContext)) {
+            return;
+        }
+        try {
+            mTelecomManager.endCall();
+            fail("Shouldn't be able to call endCall without permission grant.");
+        } catch (SecurityException se) {
+        }
+    }
+}
diff --git a/tests/tests/telephony/src/android/telephony/cts/SubscriptionManagerTest.java b/tests/tests/telephony/src/android/telephony/cts/SubscriptionManagerTest.java
index b8a21a9b..a6f82fd 100644
--- a/tests/tests/telephony/src/android/telephony/cts/SubscriptionManagerTest.java
+++ b/tests/tests/telephony/src/android/telephony/cts/SubscriptionManagerTest.java
@@ -43,7 +43,9 @@
 
 import com.android.compatibility.common.util.SystemUtil;
 
+import org.junit.AfterClass;
 import org.junit.Before;
+import org.junit.BeforeClass;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 
@@ -62,6 +64,18 @@
     private int mSubId;
     private String mPackageName;
 
+    @BeforeClass
+    public static void setUpClass() throws Exception {
+        InstrumentationRegistry.getInstrumentation().getUiAutomation()
+                .executeShellCommand("svc wifi disable");
+    }
+
+    @AfterClass
+    public static void tearDownClass() throws Exception {
+        InstrumentationRegistry.getInstrumentation().getUiAutomation()
+                .executeShellCommand("svc wifi enable");
+    }
+
     @Before
     public void setUp() throws Exception {
         mSm = InstrumentationRegistry.getContext().getSystemService(SubscriptionManager.class);
diff --git a/tests/tests/telephony/src/android/telephony/cts/TelephonyManagerTest.java b/tests/tests/telephony/src/android/telephony/cts/TelephonyManagerTest.java
index c1196f5..9f2139a 100644
--- a/tests/tests/telephony/src/android/telephony/cts/TelephonyManagerTest.java
+++ b/tests/tests/telephony/src/android/telephony/cts/TelephonyManagerTest.java
@@ -99,11 +99,9 @@
             return;
         }
 
-        // Test register
         TestThread t = new TestThread(new Runnable() {
             public void run() {
                 Looper.prepare();
-
                 mListener = new PhoneStateListener() {
                     @Override
                     public void onCellLocationChanged(CellLocation location) {
@@ -115,36 +113,54 @@
                         }
                     }
                 };
-                mTelephonyManager.listen(mListener, PhoneStateListener.LISTEN_CELL_LOCATION);
-                CellLocation.requestLocationUpdate();
+
+                synchronized (mLock) {
+                    mLock.notify(); // mListener is ready
+                }
+
                 Looper.loop();
             }
         });
-        t.start();
+
         synchronized (mLock) {
-            mLock.wait(TOLERANCE);
+            t.start();
+            mLock.wait(TOLERANCE); // wait for mListener
         }
-        assertTrue(mOnCellLocationChangedCalled);
+
+        // Test register
+        synchronized (mLock) {
+            // .listen generates an onCellLocationChanged event
+            mTelephonyManager.listen(mListener, PhoneStateListener.LISTEN_CELL_LOCATION);
+            mLock.wait(TOLERANCE);
+
+            assertTrue("Test register, mOnCellLocationChangedCalled should be true.",
+                mOnCellLocationChangedCalled);
+        }
+
+        synchronized (mLock) {
+            mOnCellLocationChangedCalled = false;
+            CellLocation.requestLocationUpdate();
+            mLock.wait(TOLERANCE);
+
+            assertTrue("Test register, mOnCellLocationChangedCalled should be true.",
+                mOnCellLocationChangedCalled);
+        }
+
+        // unregister the listener
+        mTelephonyManager.listen(mListener, PhoneStateListener.LISTEN_NONE);
+        Thread.sleep(TOLERANCE);
 
         // Test unregister
-        t = new TestThread(new Runnable() {
-            public void run() {
-                Looper.prepare();
-                // unregister the listener
-                mTelephonyManager.listen(mListener, PhoneStateListener.LISTEN_NONE);
-                mOnCellLocationChangedCalled = false;
-                // unregister again, to make sure doing so does not call the listener
-                mTelephonyManager.listen(mListener, PhoneStateListener.LISTEN_NONE);
-                CellLocation.requestLocationUpdate();
-                Looper.loop();
-            }
-        });
-
-        t.start();
         synchronized (mLock) {
+            mOnCellLocationChangedCalled = false;
+            // unregister again, to make sure doing so does not call the listener
+            mTelephonyManager.listen(mListener, PhoneStateListener.LISTEN_NONE);
+            CellLocation.requestLocationUpdate();
             mLock.wait(TOLERANCE);
+
+            assertFalse("Test unregister, mOnCellLocationChangedCalled should be false.",
+                mOnCellLocationChangedCalled);
         }
-        assertFalse(mOnCellLocationChangedCalled);
     }
 
     /**
@@ -474,8 +490,9 @@
                 Looper.loop();
             }
         });
-        t.start();
+
         synchronized (mLock) {
+            t.start();
             mLock.wait(TOLERANCE);
         }
 
diff --git a/tests/tests/text/AndroidManifest.xml b/tests/tests/text/AndroidManifest.xml
index 6a998a8..bae8481 100644
--- a/tests/tests/text/AndroidManifest.xml
+++ b/tests/tests/text/AndroidManifest.xml
@@ -16,7 +16,8 @@
  -->
 
 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
-    package="android.text.cts">
+    package="android.text.cts"
+    android:targetSandboxVersion="2">
 
     <uses-permission android:name="android.permission.DISABLE_KEYGUARD" />
     <uses-permission android:name="android.permission.WRITE_SETTINGS" />
diff --git a/tests/tests/toast/AndroidManifest.xml b/tests/tests/toast/AndroidManifest.xml
index 1fa71c4..82465b0 100644
--- a/tests/tests/toast/AndroidManifest.xml
+++ b/tests/tests/toast/AndroidManifest.xml
@@ -15,7 +15,8 @@
 -->
 
 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
-      package="android.widget.toast.cts">
+      package="android.widget.toast.cts"
+      android:targetSandboxVersion="2">
 
     <uses-sdk android:minSdkVersion="25" android:targetSdkVersion="26" />
 
diff --git a/tests/tests/transition/src/android/transition/cts/BaseTransitionTest.java b/tests/tests/transition/src/android/transition/cts/BaseTransitionTest.java
index 5917ace..b12bcc8 100644
--- a/tests/tests/transition/src/android/transition/cts/BaseTransitionTest.java
+++ b/tests/tests/transition/src/android/transition/cts/BaseTransitionTest.java
@@ -61,6 +61,7 @@
         mInstrumentation = InstrumentationRegistry.getInstrumentation();
         mInstrumentation.setInTouchMode(false);
         mActivity = mActivityRule.getActivity();
+        mActivity.setTurnScreenOn(true);
         mSceneRoot = (FrameLayout) mActivity.findViewById(R.id.container);
         mTargets.clear();
         mTransition = new TestTransition();
diff --git a/tests/tests/view/AndroidManifest.xml b/tests/tests/view/AndroidManifest.xml
index e79a2e3..a9cb2cd 100644
--- a/tests/tests/view/AndroidManifest.xml
+++ b/tests/tests/view/AndroidManifest.xml
@@ -16,7 +16,8 @@
  -->
 
 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
-    package="android.view.cts">
+    package="android.view.cts"
+    android:targetSandboxVersion="2">
 
     <uses-permission android:name="android.permission.CAMERA" />
     <uses-permission android:name="android.permission.DISABLE_KEYGUARD" />
diff --git a/tests/tests/view/src/android/view/cts/TextureViewCtsActivity.java b/tests/tests/view/src/android/view/cts/TextureViewCtsActivity.java
index 3dad097..fd0bd66 100644
--- a/tests/tests/view/src/android/view/cts/TextureViewCtsActivity.java
+++ b/tests/tests/view/src/android/view/cts/TextureViewCtsActivity.java
@@ -21,7 +21,10 @@
 import static android.opengl.GLES20.glClearColor;
 
 import android.app.Activity;
+import android.content.pm.ActivityInfo;
+import android.graphics.Bitmap;
 import android.graphics.Color;
+import android.graphics.ColorSpace;
 import android.graphics.Matrix;
 import android.graphics.SurfaceTexture;
 import android.opengl.GLUtils;
@@ -59,8 +62,14 @@
     private int mSurfaceHeight;
     private int mSurfaceUpdatedCount;
 
+    private int mEglColorSpace = 0;
+    private boolean mIsEGLWideGamut = false;
+
     static final int EGL_CONTEXT_CLIENT_VERSION = 0x3098;
     static final int EGL_OPENGL_ES2_BIT = 4;
+    static final int EGL_GL_COLORSPACE_KHR = 0x309D;
+    static final int EGL_COLOR_COMPONENT_TYPE_EXT = 0x3339;
+    static final int EGL_COLOR_COMPONENT_TYPE_FLOAT_EXT = 0x333B;
 
     private EGL10 mEgl;
     private EGLDisplay mEglDisplay;
@@ -115,6 +124,38 @@
         }
     }
 
+    public boolean setWideColorGamut() throws Throwable {
+        CountDownLatch fence = new CountDownLatch(1);
+        RunSignalAndCatch wrapper = new RunSignalAndCatch(() -> {
+            this.getWindow().setColorMode(ActivityInfo.COLOR_MODE_WIDE_COLOR_GAMUT);
+        }, fence);
+        runOnUiThread(wrapper);
+        if (!fence.await(TIME_OUT_MS, TimeUnit.MILLISECONDS)) {
+            throw new TimeoutException();
+        }
+        if (wrapper.error != null) {
+            throw wrapper.error;
+        }
+        return this.getWindow().getColorMode() == ActivityInfo.COLOR_MODE_WIDE_COLOR_GAMUT;
+    }
+
+    public Bitmap getContents(Bitmap.Config config, ColorSpace colorSpace) throws Throwable {
+        CountDownLatch fence = new CountDownLatch(1);
+        final Bitmap bitmap = Bitmap.createBitmap(this.getWindow().getDecorView().getWidth(),
+                this.getWindow().getDecorView().getHeight(), config, true, colorSpace);
+        RunSignalAndCatch wrapper = new RunSignalAndCatch(() -> {
+            this.getTextureView().getBitmap(bitmap);
+        }, fence);
+        runOnUiThread(wrapper);
+        if (!fence.await(TIME_OUT_MS, TimeUnit.MILLISECONDS)) {
+            throw new TimeoutException();
+        }
+        if (wrapper.error != null) {
+            throw wrapper.error;
+        }
+        return bitmap;
+    }
+
     private class RunSignalAndCatch implements Runnable {
         public Throwable error;
         private Runnable mRunnable;
@@ -162,16 +203,31 @@
     }
 
     public void initGl() throws Throwable {
-        if (mEglSurface != null) return;
+        initGl(0, false);
+    }
+
+    public void initGl(int eglColorSpace, boolean useHalfFloat) throws Throwable {
+        if (mEglSurface != null) {
+            if (eglColorSpace != mEglColorSpace || useHalfFloat != mIsEGLWideGamut) {
+                throw new RuntimeException("Cannot change config after initialization");
+            }
+            return;
+        }
+        mEglColorSpace = eglColorSpace;
+        mIsEGLWideGamut = useHalfFloat;
         runOnGLThread(mDoInitGL);
     }
 
     public void drawColor(int color) throws Throwable {
+        drawColor(Color.red(color) / 255.0f,
+                Color.green(color) / 255.0f,
+                Color.blue(color) / 255.0f,
+                Color.alpha(color) / 255.0f);
+    }
+
+    public void drawColor(float red, float green, float blue, float alpha) throws Throwable {
         runOnGLThread(() -> {
-            glClearColor(Color.red(color) / 255.0f,
-                    Color.green(color) / 255.0f,
-                    Color.blue(color) / 255.0f,
-                    Color.alpha(color) / 255.0f);
+            glClearColor(red, green, blue, alpha);
             glClear(GL_COLOR_BUFFER_BIT);
             if (!mEgl.eglSwapBuffers(mEglDisplay, mEglSurface)) {
                 throw new RuntimeException("Cannot swap buffers");
@@ -292,7 +348,7 @@
             mEglContext = createContext(mEgl, mEglDisplay, mEglConfig);
 
             mEglSurface = mEgl.eglCreateWindowSurface(mEglDisplay, mEglConfig,
-                    mSurface, null);
+                    mSurface, new int[] { EGL_GL_COLORSPACE_KHR, mEglColorSpace, EGL10.EGL_NONE });
 
             if (mEglSurface == null || mEglSurface == EGL10.EGL_NO_SURFACE) {
                 int error = mEgl.eglGetError();
@@ -326,15 +382,29 @@
     }
 
     private int[] getConfig() {
-        return new int[] {
-                EGL10.EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT,
-                EGL10.EGL_RED_SIZE, 8,
-                EGL10.EGL_GREEN_SIZE, 8,
-                EGL10.EGL_BLUE_SIZE, 8,
-                EGL10.EGL_ALPHA_SIZE, 8,
-                EGL10.EGL_DEPTH_SIZE, 0,
-                EGL10.EGL_STENCIL_SIZE, 0,
-                EGL10.EGL_NONE
-        };
+        if (mIsEGLWideGamut) {
+            return new int[]{
+                    EGL10.EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT,
+                    EGL_COLOR_COMPONENT_TYPE_EXT, EGL_COLOR_COMPONENT_TYPE_FLOAT_EXT,
+                    EGL10.EGL_RED_SIZE, 16,
+                    EGL10.EGL_GREEN_SIZE, 16,
+                    EGL10.EGL_BLUE_SIZE, 16,
+                    EGL10.EGL_ALPHA_SIZE, 16,
+                    EGL10.EGL_DEPTH_SIZE, 0,
+                    EGL10.EGL_STENCIL_SIZE, 0,
+                    EGL10.EGL_NONE
+            };
+        } else {
+            return new int[]{
+                    EGL10.EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT,
+                    EGL10.EGL_RED_SIZE, 8,
+                    EGL10.EGL_GREEN_SIZE, 8,
+                    EGL10.EGL_BLUE_SIZE, 8,
+                    EGL10.EGL_ALPHA_SIZE, 8,
+                    EGL10.EGL_DEPTH_SIZE, 0,
+                    EGL10.EGL_STENCIL_SIZE, 0,
+                    EGL10.EGL_NONE
+            };
+        }
     }
 }
diff --git a/tests/tests/view/src/android/view/cts/TextureViewTest.java b/tests/tests/view/src/android/view/cts/TextureViewTest.java
index 8f284d9..8a474e7 100644
--- a/tests/tests/view/src/android/view/cts/TextureViewTest.java
+++ b/tests/tests/view/src/android/view/cts/TextureViewTest.java
@@ -25,14 +25,17 @@
 
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
 
 import android.graphics.Bitmap;
 import android.graphics.Color;
+import android.graphics.ColorSpace;
 import android.graphics.Matrix;
 import android.graphics.Point;
 import android.support.test.filters.MediumTest;
 import android.support.test.rule.ActivityTestRule;
 import android.support.test.runner.AndroidJUnit4;
+import android.util.Half;
 import android.view.PixelCopy;
 import android.view.TextureView;
 import android.view.View;
@@ -45,12 +48,18 @@
 import org.junit.Test;
 import org.junit.runner.RunWith;
 
+import java.nio.ByteBuffer;
+import java.nio.ByteOrder;
 import java.util.concurrent.TimeoutException;
 
 @MediumTest
 @RunWith(AndroidJUnit4.class)
 public class TextureViewTest {
 
+    static final int EGL_GL_COLORSPACE_SRGB_KHR = 0x3089;
+    static final int EGL_GL_COLORSPACE_DISPLAY_P3_EXT = 0x3363;
+    static final int EGL_GL_COLORSPACE_SCRGB_LINEAR_EXT = 0x3350;
+
     @Rule
     public ActivityTestRule<TextureViewCtsActivity> mActivityRule =
             new ActivityTestRule<>(TextureViewCtsActivity.class, false, false);
@@ -123,6 +132,133 @@
                 Color.BLACK, Color.BLUE, Color.GREEN, Color.RED);
     }
 
+    @Test
+    public void testGetBitmap_8888_P3() throws Throwable {
+        testGetBitmap(EGL_GL_COLORSPACE_DISPLAY_P3_EXT, ColorSpace.Named.DISPLAY_P3, false,
+                new FP16Compare(ColorSpace.Named.EXTENDED_SRGB));
+    }
+
+    @Test
+    public void testGetBitmap_FP16_P3() throws Throwable {
+        testGetBitmap(EGL_GL_COLORSPACE_DISPLAY_P3_EXT, ColorSpace.Named.DISPLAY_P3, true,
+                new FP16Compare(ColorSpace.Named.EXTENDED_SRGB));
+    }
+
+    @Test
+    public void testGetBitmap_FP16_LinearExtendedSRGB() throws Throwable {
+        testGetBitmap(EGL_GL_COLORSPACE_SCRGB_LINEAR_EXT, ColorSpace.Named.LINEAR_EXTENDED_SRGB,
+                true, new FP16Compare(ColorSpace.Named.EXTENDED_SRGB));
+    }
+
+    @Test
+    public void testGet565Bitmap_SRGB() throws Throwable {
+        testGetBitmap(EGL_GL_COLORSPACE_SRGB_KHR, ColorSpace.Named.SRGB, true,
+                new SRGBCompare(Bitmap.Config.RGB_565));
+    }
+
+    @Test
+    public void testGetBitmap_SRGB() throws Throwable {
+        testGetBitmap(EGL_GL_COLORSPACE_SRGB_KHR, ColorSpace.Named.SRGB, true,
+                new SRGBCompare(Bitmap.Config.ARGB_8888));
+    }
+
+    interface CompareFunction {
+        Bitmap.Config getConfig();
+        ColorSpace getColorSpace();
+        void verify(float[] srcColor, ColorSpace.Named srcColorSpace, Bitmap dstBitmap);
+    }
+
+    private class FP16Compare implements CompareFunction {
+        private ColorSpace mDstColorSpace;
+
+        FP16Compare(ColorSpace.Named namedCS) {
+            mDstColorSpace = ColorSpace.get(namedCS);
+        }
+
+        public Bitmap.Config getConfig() {
+            return Bitmap.Config.RGBA_F16;
+        }
+
+        public ColorSpace getColorSpace() {
+            return mDstColorSpace;
+        }
+
+        public void verify(float[] srcColor, ColorSpace.Named srcColorSpace, Bitmap dstBitmap) {
+            // read pixels into buffer and compare using colorspace connector
+            ByteBuffer buffer = ByteBuffer.allocate(dstBitmap.getAllocationByteCount());
+            buffer.order(ByteOrder.LITTLE_ENDIAN);
+            dstBitmap.copyPixelsToBuffer(buffer);
+            Half alpha = Half.valueOf(buffer.getShort(6));
+            assertEquals(1.0f, alpha.floatValue(), 0.0f);
+
+            final ColorSpace srcSpace = ColorSpace.get(srcColorSpace);
+            final ColorSpace dstSpace = getColorSpace();
+            float[] expectedColor = ColorSpace.connect(srcSpace, dstSpace).transform(srcColor);
+            float[] outputColor = {
+                    Half.valueOf(buffer.getShort(0)).floatValue(),
+                    Half.valueOf(buffer.getShort(2)).floatValue(),
+                    Half.valueOf(buffer.getShort(4)).floatValue() };
+
+            assertEquals(expectedColor[0], outputColor[0], 0.01f);
+            assertEquals(expectedColor[1], outputColor[1], 0.01f);
+            assertEquals(expectedColor[2], outputColor[2], 0.01f);
+        }
+    }
+
+    private class SRGBCompare implements CompareFunction {
+        private Bitmap.Config mConfig;
+
+        SRGBCompare(Bitmap.Config config) {
+            mConfig = config;
+        }
+
+        public Bitmap.Config getConfig() {
+            return mConfig;
+        }
+
+        public ColorSpace getColorSpace() {
+            return ColorSpace.get(ColorSpace.Named.SRGB);
+        }
+
+        public void verify(float[] srcColor, ColorSpace.Named srcColorSpace, Bitmap dstBitmap) {
+            int color = dstBitmap.getPixel(0, 0);
+            assertEquals(1.0f, Color.alpha(color) / 255.0f, 0.0f);
+            assertEquals(srcColor[0], Color.red(color) / 255.0f, 0.01f);
+            assertEquals(srcColor[1], Color.green(color) / 255.0f, 0.01f);
+            assertEquals(srcColor[2], Color.blue(color) / 255.0f, 0.01f);
+        }
+    }
+
+    private void testGetBitmap(int eglColorSpace, ColorSpace.Named colorSpace,
+            boolean useHalfFloat, CompareFunction compareFunction) throws Throwable {
+        final TextureViewCtsActivity activity = mActivityRule.launchActivity(null);
+        activity.waitForSurface();
+
+        try {
+            activity.initGl(eglColorSpace, useHalfFloat);
+        } catch (RuntimeException e) {
+            // failure to init GL with the right colorspace is not a TextureView failure as some
+            // devices may not support 16-bits
+            if (!useHalfFloat) {
+                fail("Unable to initGL : " + e);
+            }
+            return;
+        }
+
+        final float[] inputColor = { 1.0f, 128 / 255.0f, 0.0f};
+
+        int updatedCount;
+        updatedCount = activity.waitForSurfaceUpdateCount(0);
+        assertEquals(0, updatedCount);
+        activity.drawColor(inputColor[0], inputColor[1], inputColor[2], 1.0f);
+        updatedCount = activity.waitForSurfaceUpdateCount(1);
+        assertEquals(1, updatedCount);
+
+        final Bitmap bitmap = activity.getContents(compareFunction.getConfig(),
+                compareFunction.getColorSpace());
+        compareFunction.verify(inputColor, colorSpace, bitmap);
+    }
+
     private static void drawGlQuad(int width, int height) {
         int cx = width / 2;
         int cy = height / 2;
diff --git a/tests/tests/voicesettings/AndroidTest.xml b/tests/tests/voicesettings/AndroidTest.xml
index dfb50d8..5b97823 100644
--- a/tests/tests/voicesettings/AndroidTest.xml
+++ b/tests/tests/voicesettings/AndroidTest.xml
@@ -24,6 +24,10 @@
     </target_preparer>
     <target_preparer class="com.android.tradefed.targetprep.RunCommandTargetPreparer">
         <option name="run-command" value="settings put secure voice_interaction_service android.voicesettings.service/.MainInteractionService" />
+
+        <!-- Close the "turn on battery saver?" dialog, and wait for the broadcast queue to drain. -->
+        <option name="teardown-command" value="am broadcast --receiver-foreground -a android.intent.action.CLOSE_SYSTEM_DIALOGS" />
+        <option name="teardown-command" value="am wait-for-broadcast-idle" />
     </target_preparer>
     <test class="com.android.tradefed.testtype.AndroidJUnitTest" >
         <option name="package" value="android.voicesettings.cts" />
diff --git a/tests/tests/webkit/src/android/webkit/cts/GeolocationTest.java b/tests/tests/webkit/src/android/webkit/cts/GeolocationTest.java
index 9f27081..9384f8a 100644
--- a/tests/tests/webkit/src/android/webkit/cts/GeolocationTest.java
+++ b/tests/tests/webkit/src/android/webkit/cts/GeolocationTest.java
@@ -46,6 +46,7 @@
 import java.io.UnsupportedEncodingException;
 import java.util.concurrent.Callable;
 import java.util.Date;
+import java.util.HashSet;
 import java.util.List;
 import java.util.Random;
 import java.util.regex.Matcher;
@@ -208,8 +209,13 @@
     }
 
     private void addTestProviders() {
+        Set<String> unavailableProviders = new HashSet<>();
         for (String providerName : mProviders) {
             LocationProvider provider = mLocationManager.getProvider(providerName);
+            if (provider == null) {
+                unavailableProviders.add(providerName);
+                continue;
+            }
             mLocationManager.addTestProvider(provider.getName(),
                     provider.requiresNetwork(), //requiresNetwork,
                     provider.requiresSatellite(), // requiresSatellite,
@@ -222,6 +228,7 @@
                     provider.getAccuracy()); // accuracy
             mLocationManager.setTestProviderEnabled(provider.getName(), true);
         }
+        mProviders.removeAll(unavailableProviders);
     }
 
     private static final String TEST_PROVIDER_NAME = "location_provider_test";
diff --git a/tests/tests/widget/AndroidManifest.xml b/tests/tests/widget/AndroidManifest.xml
index adfefbe..80e65f7 100644
--- a/tests/tests/widget/AndroidManifest.xml
+++ b/tests/tests/widget/AndroidManifest.xml
@@ -16,7 +16,8 @@
  -->
 
 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
-    package="android.widget.cts">
+    package="android.widget.cts"
+    android:targetSandboxVersion="2">
 
     <uses-permission android:name="android.permission.DISABLE_KEYGUARD" />
     <uses-permission android:name="android.permission.WRITE_SETTINGS" />
diff --git a/tests/tests/widget/src/android/widget/cts/AbsListViewTest.java b/tests/tests/widget/src/android/widget/cts/AbsListViewTest.java
index 7bbc08a..6833771 100644
--- a/tests/tests/widget/src/android/widget/cts/AbsListViewTest.java
+++ b/tests/tests/widget/src/android/widget/cts/AbsListViewTest.java
@@ -129,6 +129,7 @@
     public void setup() throws Exception {
         mInstrumentation = InstrumentationRegistry.getInstrumentation();
         final Activity activity = mActivityRule.getActivity();
+        activity.setTurnScreenOn(true);
         // Always use the activity context
         mContext = activity;
 
diff --git a/tests/tests/widget/src/android/widget/cts/RemoteViewsWidgetTest.java b/tests/tests/widget/src/android/widget/cts/RemoteViewsWidgetTest.java
index 0e2f5cf..0e05a0d 100644
--- a/tests/tests/widget/src/android/widget/cts/RemoteViewsWidgetTest.java
+++ b/tests/tests/widget/src/android/widget/cts/RemoteViewsWidgetTest.java
@@ -37,6 +37,7 @@
 import android.content.pm.PackageManager;
 import android.os.Bundle;
 import android.os.Process;
+import android.platform.test.annotations.AppModeFull;
 import android.support.test.InstrumentationRegistry;
 import android.support.test.filters.LargeTest;
 import android.support.test.rule.ActivityTestRule;
@@ -73,6 +74,7 @@
  * Test {@link RemoteViews} that expect to operate within a {@link AppWidgetHostView} root.
  */
 @LargeTest
+@AppModeFull
 @RunWith(AndroidJUnit4.class)
 public class RemoteViewsWidgetTest {
     public static final String[] COUNTRY_LIST = new String[] {
diff --git a/tests/tests/widget/src/android/widget/cts/TextViewTest.java b/tests/tests/widget/src/android/widget/cts/TextViewTest.java
index 7c55f90..62407b7 100644
--- a/tests/tests/widget/src/android/widget/cts/TextViewTest.java
+++ b/tests/tests/widget/src/android/widget/cts/TextViewTest.java
@@ -73,8 +73,6 @@
 import android.os.Looper;
 import android.os.Parcelable;
 import android.os.SystemClock;
-import androidx.annotation.IntDef;
-import androidx.annotation.Nullable;
 import android.support.test.InstrumentationRegistry;
 import android.support.test.annotation.UiThreadTest;
 import android.support.test.filters.MediumTest;
@@ -150,6 +148,9 @@
 import android.widget.TextView.BufferType;
 import android.widget.cts.util.TestUtils;
 
+import androidx.annotation.IntDef;
+import androidx.annotation.Nullable;
+
 import com.android.compatibility.common.util.CtsKeyEventUtil;
 import com.android.compatibility.common.util.CtsTouchUtils;
 import com.android.compatibility.common.util.PollingCheck;
@@ -206,6 +207,7 @@
     public void setup() {
         mInstrumentation = InstrumentationRegistry.getInstrumentation();
         mActivity = mActivityRule.getActivity();
+        mActivity.setTurnScreenOn(true);
         PollingCheck.waitFor(mActivity::hasWindowFocus);
     }
 
diff --git a/tests/ui/AndroidManifest.xml b/tests/ui/AndroidManifest.xml
index 5ed06b4..56826f9 100644
--- a/tests/ui/AndroidManifest.xml
+++ b/tests/ui/AndroidManifest.xml
@@ -16,7 +16,8 @@
 -->
 
 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
-    package="android.ui.cts" >
+    package="android.ui.cts"
+    android:targetSandboxVersion="2">
 
     <uses-permission android:name="android.permission.DISABLE_KEYGUARD" />
     <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
diff --git a/tests/video/src/android/video/cts/VideoEncoderDecoderTest.java b/tests/video/src/android/video/cts/VideoEncoderDecoderTest.java
index 7b1dc11..07e7c6c 100644
--- a/tests/video/src/android/video/cts/VideoEncoderDecoderTest.java
+++ b/tests/video/src/android/video/cts/VideoEncoderDecoderTest.java
@@ -195,9 +195,12 @@
     // tests and change the count if there can be more encoders.
 
     // AVC tests
-    public void testAvcCount0320x0240() throws Exception { count(AVC, 320, 240, 1, 4); }
+    public void testAvcCount0320x0240() throws Exception { count(AVC, 320, 240, 2, 4); }
     public void testAvcGoog0Qual0320x0240() throws Exception { qual(AVC, 320, 240, GOOG, 0); }
     public void testAvcGoog0Perf0320x0240() throws Exception { perf(AVC, 320, 240, GOOG, 0); }
+    public void testAvcGoog1Qual0320x0240() throws Exception { qual(AVC, 320, 240, GOOG, 1); }
+    public void testAvcGoog1Perf0320x0240() throws Exception { perf(AVC, 320, 240, GOOG, 1); }
+
     public void testAvcOther0Qual0320x0240() throws Exception { qual(AVC, 320, 240, OTHER, 0); }
     public void testAvcOther0Perf0320x0240() throws Exception { perf(AVC, 320, 240, OTHER, 0); }
     public void testAvcOther1Qual0320x0240() throws Exception { qual(AVC, 320, 240, OTHER, 1); }
@@ -206,9 +209,12 @@
     public void testAvcOther2Perf0320x0240() throws Exception { perf(AVC, 320, 240, OTHER, 2); }
     public void testAvcOther3Qual0320x0240() throws Exception { qual(AVC, 320, 240, OTHER, 3); }
     public void testAvcOther3Perf0320x0240() throws Exception { perf(AVC, 320, 240, OTHER, 3); }
-    public void testAvcCount0720x0480() throws Exception { count(AVC, 720, 480, 1, 4); }
+    public void testAvcCount0720x0480() throws Exception { count(AVC, 720, 480, 2, 4); }
     public void testAvcGoog0Qual0720x0480() throws Exception { qual(AVC, 720, 480, GOOG, 0); }
     public void testAvcGoog0Perf0720x0480() throws Exception { perf(AVC, 720, 480, GOOG, 0); }
+    public void testAvcGoog1Qual0720x0480() throws Exception { qual(AVC, 720, 480, GOOG, 1); }
+    public void testAvcGoog1Perf0720x0480() throws Exception { perf(AVC, 720, 480, GOOG, 1); }
+
     public void testAvcOther0Qual0720x0480() throws Exception { qual(AVC, 720, 480, OTHER, 0); }
     public void testAvcOther0Perf0720x0480() throws Exception { perf(AVC, 720, 480, OTHER, 0); }
     public void testAvcOther1Qual0720x0480() throws Exception { qual(AVC, 720, 480, OTHER, 1); }
@@ -217,9 +223,12 @@
     public void testAvcOther2Perf0720x0480() throws Exception { perf(AVC, 720, 480, OTHER, 2); }
     public void testAvcOther3Qual0720x0480() throws Exception { qual(AVC, 720, 480, OTHER, 3); }
     public void testAvcOther3Perf0720x0480() throws Exception { perf(AVC, 720, 480, OTHER, 3); }
-    public void testAvcCount1280x0720() throws Exception { count(AVC, 1280, 720, 1, 4); }
+    public void testAvcCount1280x0720() throws Exception { count(AVC, 1280, 720, 2, 4); }
     public void testAvcGoog0Qual1280x0720() throws Exception { qual(AVC, 1280, 720, GOOG, 0); }
     public void testAvcGoog0Perf1280x0720() throws Exception { perf(AVC, 1280, 720, GOOG, 0); }
+    public void testAvcGoog1Qual1280x0720() throws Exception { qual(AVC, 1280, 720, GOOG, 1); }
+    public void testAvcGoog1Perf1280x0720() throws Exception { perf(AVC, 1280, 720, GOOG, 1); }
+
     public void testAvcOther0Qual1280x0720() throws Exception { qual(AVC, 1280, 720, OTHER, 0); }
     public void testAvcOther0Perf1280x0720() throws Exception { perf(AVC, 1280, 720, OTHER, 0); }
     public void testAvcOther1Qual1280x0720() throws Exception { qual(AVC, 1280, 720, OTHER, 1); }
@@ -228,9 +237,12 @@
     public void testAvcOther2Perf1280x0720() throws Exception { perf(AVC, 1280, 720, OTHER, 2); }
     public void testAvcOther3Qual1280x0720() throws Exception { qual(AVC, 1280, 720, OTHER, 3); }
     public void testAvcOther3Perf1280x0720() throws Exception { perf(AVC, 1280, 720, OTHER, 3); }
-    public void testAvcCount1920x1080() throws Exception { count(AVC, 1920, 1080, 1, 4); }
+    public void testAvcCount1920x1080() throws Exception { count(AVC, 1920, 1080, 2, 4); }
     public void testAvcGoog0Qual1920x1080() throws Exception { qual(AVC, 1920, 1080, GOOG, 0); }
     public void testAvcGoog0Perf1920x1080() throws Exception { perf(AVC, 1920, 1080, GOOG, 0); }
+    public void testAvcGoog1Qual1920x1080() throws Exception { qual(AVC, 1920, 1080, GOOG, 1); }
+    public void testAvcGoog1Perf1920x1080() throws Exception { perf(AVC, 1920, 1080, GOOG, 1); }
+
     public void testAvcOther0Qual1920x1080() throws Exception { qual(AVC, 1920, 1080, OTHER, 0); }
     public void testAvcOther0Perf1920x1080() throws Exception { perf(AVC, 1920, 1080, OTHER, 0); }
     public void testAvcOther1Qual1920x1080() throws Exception { qual(AVC, 1920, 1080, OTHER, 1); }
@@ -241,28 +253,34 @@
     public void testAvcOther3Perf1920x1080() throws Exception { perf(AVC, 1920, 1080, OTHER, 3); }
 
     // H263 tests
-    public void testH263Count0176x0144() throws Exception { count(H263, 176, 144, 1, 2); }
+    public void testH263Count0176x0144() throws Exception { count(H263, 176, 144, 2, 2); }
     public void testH263Goog0Qual0176x0144() throws Exception { qual(H263, 176, 144, GOOG, 0); }
     public void testH263Goog0Perf0176x0144() throws Exception { perf(H263, 176, 144, GOOG, 0); }
+    public void testH263Goog1Qual0176x0144() throws Exception { qual(H263, 176, 144, GOOG, 1); }
+    public void testH263Goog1Perf0176x0144() throws Exception { perf(H263, 176, 144, GOOG, 1); }
+
     public void testH263Other0Qual0176x0144() throws Exception { qual(H263, 176, 144, OTHER, 0); }
     public void testH263Other0Perf0176x0144() throws Exception { perf(H263, 176, 144, OTHER, 0); }
     public void testH263Other1Qual0176x0144() throws Exception { qual(H263, 176, 144, OTHER, 1); }
     public void testH263Other1Perf0176x0144() throws Exception { perf(H263, 176, 144, OTHER, 1); }
-    public void testH263Count0352x0288() throws Exception { count(H263, 352, 288, 1, 2); }
+    public void testH263Count0352x0288() throws Exception { count(H263, 352, 288, 2, 2); }
     public void testH263Goog0Qual0352x0288() throws Exception { qual(H263, 352, 288, GOOG, 0); }
     public void testH263Goog0Perf0352x0288() throws Exception { perf(H263, 352, 288, GOOG, 0); }
+    public void testH263Goog1Qual0352x0288() throws Exception { qual(H263, 352, 288, GOOG, 1); }
+    public void testH263Goog1Perf0352x0288() throws Exception { perf(H263, 352, 288, GOOG, 1); }
+
     public void testH263Other0Qual0352x0288() throws Exception { qual(H263, 352, 288, OTHER, 0); }
     public void testH263Other0Perf0352x0288() throws Exception { perf(H263, 352, 288, OTHER, 0); }
     public void testH263Other1Qual0352x0288() throws Exception { qual(H263, 352, 288, OTHER, 1); }
     public void testH263Other1Perf0352x0288() throws Exception { perf(H263, 352, 288, OTHER, 1); }
-    public void testH263Count0704x0576() throws Exception { count(H263, 704, 576, 1, 2); }
+    public void testH263Count0704x0576() throws Exception { count(H263, 704, 576, 2, 2); }
     public void testH263Goog0Qual0704x0576() throws Exception { qual(H263, 704, 576, GOOG, 0, 25); }
     public void testH263Goog0Perf0704x0576() throws Exception { perf(H263, 704, 576, GOOG, 0); }
     public void testH263Other0Qual0704x0576() throws Exception { qual(H263, 704, 576, OTHER, 0, 25); }
     public void testH263Other0Perf0704x0576() throws Exception { perf(H263, 704, 576, OTHER, 0); }
     public void testH263Other1Qual0704x0576() throws Exception { qual(H263, 704, 576, OTHER, 1, 25); }
     public void testH263Other1Perf0704x0576() throws Exception { perf(H263, 704, 576, OTHER, 1); }
-    public void testH263Count1408x1152() throws Exception { count(H263, 1408, 1152, 1, 2); }
+    public void testH263Count1408x1152() throws Exception { count(H263, 1408, 1152, 2, 2); }
     public void testH263Goog0Qual1408x1152() throws Exception { qual(H263, 1408, 1152, GOOG, 0, 25); }
     public void testH263Goog0Perf1408x1152() throws Exception { perf(H263, 1408, 1152, GOOG, 0); }
     public void testH263Other0Qual1408x1152() throws Exception { qual(H263, 1408, 1152, OTHER, 0, 25); }
@@ -271,9 +289,12 @@
     public void testH263Other1Perf1408x1152() throws Exception { perf(H263, 1408, 1152, OTHER, 1); }
 
     // HEVC tests
-    public void testHevcCount0320x0240() throws Exception { count(HEVC, 320, 240, 1, 4); }
+    public void testHevcCount0320x0240() throws Exception { count(HEVC, 320, 240, 2, 4); }
     public void testHevcGoog0Qual0320x0240() throws Exception { qual(HEVC, 320, 240, GOOG, 0); }
     public void testHevcGoog0Perf0320x0240() throws Exception { perf(HEVC, 320, 240, GOOG, 0); }
+    public void testHevcGoog1Qual0320x0240() throws Exception { qual(HEVC, 320, 240, GOOG, 1); }
+    public void testHevcGoog1Perf0320x0240() throws Exception { perf(HEVC, 320, 240, GOOG, 1); }
+
     public void testHevcOther0Qual0320x0240() throws Exception { qual(HEVC, 320, 240, OTHER, 0); }
     public void testHevcOther0Perf0320x0240() throws Exception { perf(HEVC, 320, 240, OTHER, 0); }
     public void testHevcOther1Qual0320x0240() throws Exception { qual(HEVC, 320, 240, OTHER, 1); }
@@ -282,9 +303,12 @@
     public void testHevcOther2Perf0320x0240() throws Exception { perf(HEVC, 320, 240, OTHER, 2); }
     public void testHevcOther3Qual0320x0240() throws Exception { qual(HEVC, 320, 240, OTHER, 3); }
     public void testHevcOther3Perf0320x0240() throws Exception { perf(HEVC, 320, 240, OTHER, 3); }
-    public void testHevcCount0720x0480() throws Exception { count(HEVC, 720, 480, 1, 4); }
+    public void testHevcCount0720x0480() throws Exception { count(HEVC, 720, 480, 2, 4); }
     public void testHevcGoog0Qual0720x0480() throws Exception { qual(HEVC, 720, 480, GOOG, 0); }
     public void testHevcGoog0Perf0720x0480() throws Exception { perf(HEVC, 720, 480, GOOG, 0); }
+    public void testHevcGoog1Qual0720x0480() throws Exception { qual(HEVC, 720, 480, GOOG, 1); }
+    public void testHevcGoog1Perf0720x0480() throws Exception { perf(HEVC, 720, 480, GOOG, 1); }
+
     public void testHevcOther0Qual0720x0480() throws Exception { qual(HEVC, 720, 480, OTHER, 0); }
     public void testHevcOther0Perf0720x0480() throws Exception { perf(HEVC, 720, 480, OTHER, 0); }
     public void testHevcOther1Qual0720x0480() throws Exception { qual(HEVC, 720, 480, OTHER, 1); }
@@ -293,9 +317,12 @@
     public void testHevcOther2Perf0720x0480() throws Exception { perf(HEVC, 720, 480, OTHER, 2); }
     public void testHevcOther3Qual0720x0480() throws Exception { qual(HEVC, 720, 480, OTHER, 3); }
     public void testHevcOther3Perf0720x0480() throws Exception { perf(HEVC, 720, 480, OTHER, 3); }
-    public void testHevcCount1280x0720() throws Exception { count(HEVC, 1280, 720, 1, 4); }
+    public void testHevcCount1280x0720() throws Exception { count(HEVC, 1280, 720, 2, 4); }
     public void testHevcGoog0Qual1280x0720() throws Exception { qual(HEVC, 1280, 720, GOOG, 0); }
     public void testHevcGoog0Perf1280x0720() throws Exception { perf(HEVC, 1280, 720, GOOG, 0); }
+    public void testHevcGoog1Qual1280x0720() throws Exception { qual(HEVC, 1280, 720, GOOG, 1); }
+    public void testHevcGoog1Perf1280x0720() throws Exception { perf(HEVC, 1280, 720, GOOG, 1); }
+
     public void testHevcOther0Qual1280x0720() throws Exception { qual(HEVC, 1280, 720, OTHER, 0); }
     public void testHevcOther0Perf1280x0720() throws Exception { perf(HEVC, 1280, 720, OTHER, 0); }
     public void testHevcOther1Qual1280x0720() throws Exception { qual(HEVC, 1280, 720, OTHER, 1); }
@@ -304,9 +331,12 @@
     public void testHevcOther2Perf1280x0720() throws Exception { perf(HEVC, 1280, 720, OTHER, 2); }
     public void testHevcOther3Qual1280x0720() throws Exception { qual(HEVC, 1280, 720, OTHER, 3); }
     public void testHevcOther3Perf1280x0720() throws Exception { perf(HEVC, 1280, 720, OTHER, 3); }
-    public void testHevcCount1920x1080() throws Exception { count(HEVC, 1920, 1080, 1, 4); }
+    public void testHevcCount1920x1080() throws Exception { count(HEVC, 1920, 1080, 2, 4); }
     public void testHevcGoog0Qual1920x1080() throws Exception { qual(HEVC, 1920, 1080, GOOG, 0); }
     public void testHevcGoog0Perf1920x1080() throws Exception { perf(HEVC, 1920, 1080, GOOG, 0); }
+    public void testHevcGoog1Qual1920x1080() throws Exception { qual(HEVC, 1920, 1080, GOOG, 1); }
+    public void testHevcGoog1Perf1920x1080() throws Exception { perf(HEVC, 1920, 1080, GOOG, 1); }
+
     public void testHevcOther0Qual1920x1080() throws Exception { qual(HEVC, 1920, 1080, OTHER, 0); }
     public void testHevcOther0Perf1920x1080() throws Exception { perf(HEVC, 1920, 1080, OTHER, 0); }
     public void testHevcOther1Qual1920x1080() throws Exception { qual(HEVC, 1920, 1080, OTHER, 1); }
@@ -315,9 +345,12 @@
     public void testHevcOther2Perf1920x1080() throws Exception { perf(HEVC, 1920, 1080, OTHER, 2); }
     public void testHevcOther3Qual1920x1080() throws Exception { qual(HEVC, 1920, 1080, OTHER, 3); }
     public void testHevcOther3Perf1920x1080() throws Exception { perf(HEVC, 1920, 1080, OTHER, 3); }
-    public void testHevcCount3840x2160() throws Exception { count(HEVC, 3840, 2160, 1, 4); }
+    public void testHevcCount3840x2160() throws Exception { count(HEVC, 3840, 2160, 2, 4); }
     public void testHevcGoog0Qual3840x2160() throws Exception { qual(HEVC, 3840, 2160, GOOG, 0); }
     public void testHevcGoog0Perf3840x2160() throws Exception { perf(HEVC, 3840, 2160, GOOG, 0); }
+    public void testHevcGoog1Qual3840x2160() throws Exception { qual(HEVC, 3840, 2160, GOOG, 1); }
+    public void testHevcGoog1Perf3840x2160() throws Exception { perf(HEVC, 3840, 2160, GOOG, 1); }
+
     public void testHevcOther0Qual3840x2160() throws Exception { qual(HEVC, 3840, 2160, OTHER, 0); }
     public void testHevcOther0Perf3840x2160() throws Exception { perf(HEVC, 3840, 2160, OTHER, 0); }
     public void testHevcOther1Qual3840x2160() throws Exception { qual(HEVC, 3840, 2160, OTHER, 1); }
@@ -328,9 +361,12 @@
     public void testHevcOther3Perf3840x2160() throws Exception { perf(HEVC, 3840, 2160, OTHER, 3); }
 
     // MPEG2 tests
-    public void testMpeg2Count0176x0144() throws Exception { count(MPEG2, 176, 144, 1, 4); }
+    public void testMpeg2Count0176x0144() throws Exception { count(MPEG2, 176, 144, 2, 4); }
     public void testMpeg2Goog0Qual0176x0144() throws Exception { qual(MPEG2, 176, 144, GOOG, 0); }
     public void testMpeg2Goog0Perf0176x0144() throws Exception { perf(MPEG2, 176, 144, GOOG, 0); }
+    public void testMpeg2Goog1Qual0176x0144() throws Exception { qual(MPEG2, 176, 144, GOOG, 1); }
+    public void testMpeg2Goog1Perf0176x0144() throws Exception { perf(MPEG2, 176, 144, GOOG, 1); }
+
     public void testMpeg2Other0Qual0176x0144() throws Exception { qual(MPEG2, 176, 144, OTHER, 0); }
     public void testMpeg2Other0Perf0176x0144() throws Exception { perf(MPEG2, 176, 144, OTHER, 0); }
     public void testMpeg2Other1Qual0176x0144() throws Exception { qual(MPEG2, 176, 144, OTHER, 1); }
@@ -339,9 +375,12 @@
     public void testMpeg2Other2Perf0176x0144() throws Exception { perf(MPEG2, 176, 144, OTHER, 2); }
     public void testMpeg2Other3Qual0176x0144() throws Exception { qual(MPEG2, 176, 144, OTHER, 3); }
     public void testMpeg2Other3Perf0176x0144() throws Exception { perf(MPEG2, 176, 144, OTHER, 3); }
-    public void testMpeg2Count0352x0288() throws Exception { count(MPEG2, 352, 288, 1, 4); }
+    public void testMpeg2Count0352x0288() throws Exception { count(MPEG2, 352, 288, 2, 4); }
     public void testMpeg2Goog0Qual0352x0288() throws Exception { qual(MPEG2, 352, 288, GOOG, 0); }
     public void testMpeg2Goog0Perf0352x0288() throws Exception { perf(MPEG2, 352, 288, GOOG, 0); }
+    public void testMpeg2Goog1Qual0352x0288() throws Exception { qual(MPEG2, 352, 288, GOOG, 1); }
+    public void testMpeg2Goog1Perf0352x0288() throws Exception { perf(MPEG2, 352, 288, GOOG, 1); }
+
     public void testMpeg2Other0Qual0352x0288() throws Exception { qual(MPEG2, 352, 288, OTHER, 0); }
     public void testMpeg2Other0Perf0352x0288() throws Exception { perf(MPEG2, 352, 288, OTHER, 0); }
     public void testMpeg2Other1Qual0352x0288() throws Exception { qual(MPEG2, 352, 288, OTHER, 1); }
@@ -350,9 +389,12 @@
     public void testMpeg2Other2Perf0352x0288() throws Exception { perf(MPEG2, 352, 288, OTHER, 2); }
     public void testMpeg2Other3Qual0352x0288() throws Exception { qual(MPEG2, 352, 288, OTHER, 3); }
     public void testMpeg2Other3Perf0352x0288() throws Exception { perf(MPEG2, 352, 288, OTHER, 3); }
-    public void testMpeg2Count0640x0480() throws Exception { count(MPEG2, 640, 480, 1, 4); }
+    public void testMpeg2Count0640x0480() throws Exception { count(MPEG2, 640, 480, 2, 4); }
     public void testMpeg2Goog0Qual0640x0480() throws Exception { qual(MPEG2, 640, 480, GOOG, 0); }
     public void testMpeg2Goog0Perf0640x0480() throws Exception { perf(MPEG2, 640, 480, GOOG, 0); }
+    public void testMpeg2Goog1Qual0640x0480() throws Exception { qual(MPEG2, 640, 480, GOOG, 1); }
+    public void testMpeg2Goog1Perf0640x0480() throws Exception { perf(MPEG2, 640, 480, GOOG, 1); }
+
     public void testMpeg2Other0Qual0640x0480() throws Exception { qual(MPEG2, 640, 480, OTHER, 0); }
     public void testMpeg2Other0Perf0640x0480() throws Exception { perf(MPEG2, 640, 480, OTHER, 0); }
     public void testMpeg2Other1Qual0640x0480() throws Exception { qual(MPEG2, 640, 480, OTHER, 1); }
@@ -361,9 +403,12 @@
     public void testMpeg2Other2Perf0640x0480() throws Exception { perf(MPEG2, 640, 480, OTHER, 2); }
     public void testMpeg2Other3Qual0640x0480() throws Exception { qual(MPEG2, 640, 480, OTHER, 3); }
     public void testMpeg2Other3Perf0640x0480() throws Exception { perf(MPEG2, 640, 480, OTHER, 3); }
-    public void testMpeg2Count1280x0720() throws Exception { count(MPEG2, 1280, 720, 1, 4); }
+    public void testMpeg2Count1280x0720() throws Exception { count(MPEG2, 1280, 720, 2, 4); }
     public void testMpeg2Goog0Qual1280x0720() throws Exception { qual(MPEG2, 1280, 720, GOOG, 0); }
     public void testMpeg2Goog0Perf1280x0720() throws Exception { perf(MPEG2, 1280, 720, GOOG, 0); }
+    public void testMpeg2Goog1Qual1280x0720() throws Exception { qual(MPEG2, 1280, 720, GOOG, 1); }
+    public void testMpeg2Goog1Perf1280x0720() throws Exception { perf(MPEG2, 1280, 720, GOOG, 1); }
+
     public void testMpeg2Other0Qual1280x0720() throws Exception { qual(MPEG2, 1280, 720, OTHER, 0); }
     public void testMpeg2Other0Perf1280x0720() throws Exception { perf(MPEG2, 1280, 720, OTHER, 0); }
     public void testMpeg2Other1Qual1280x0720() throws Exception { qual(MPEG2, 1280, 720, OTHER, 1); }
@@ -372,9 +417,12 @@
     public void testMpeg2Other2Perf1280x0720() throws Exception { perf(MPEG2, 1280, 720, OTHER, 2); }
     public void testMpeg2Other3Qual1280x0720() throws Exception { qual(MPEG2, 1280, 720, OTHER, 3); }
     public void testMpeg2Other3Perf1280x0720() throws Exception { perf(MPEG2, 1280, 720, OTHER, 3); }
-    public void testMpeg2Count1920x1080() throws Exception { count(MPEG2, 1920, 1080, 1, 4); }
+    public void testMpeg2Count1920x1080() throws Exception { count(MPEG2, 1920, 1080, 2, 4); }
     public void testMpeg2Goog0Qual1920x1080() throws Exception { qual(MPEG2, 1920, 1080, GOOG, 0); }
     public void testMpeg2Goog0Perf1920x1080() throws Exception { perf(MPEG2, 1920, 1080, GOOG, 0); }
+    public void testMpeg2Goog1Qual1920x1080() throws Exception { qual(MPEG2, 1920, 1080, GOOG, 1); }
+    public void testMpeg2Goog1Perf1920x1080() throws Exception { perf(MPEG2, 1920, 1080, GOOG, 1); }
+
     public void testMpeg2Other0Qual1920x1080() throws Exception { qual(MPEG2, 1920, 1080, OTHER, 0); }
     public void testMpeg2Other0Perf1920x1080() throws Exception { perf(MPEG2, 1920, 1080, OTHER, 0); }
     public void testMpeg2Other1Qual1920x1080() throws Exception { qual(MPEG2, 1920, 1080, OTHER, 1); }
@@ -385,9 +433,12 @@
     public void testMpeg2Other3Perf1920x1080() throws Exception { perf(MPEG2, 1920, 1080, OTHER, 3); }
 
     // MPEG4 tests
-    public void testMpeg4Count0176x0144() throws Exception { count(MPEG4, 176, 144, 1, 4); }
+    public void testMpeg4Count0176x0144() throws Exception { count(MPEG4, 176, 144, 2, 4); }
     public void testMpeg4Goog0Qual0176x0144() throws Exception { qual(MPEG4, 176, 144, GOOG, 0); }
     public void testMpeg4Goog0Perf0176x0144() throws Exception { perf(MPEG4, 176, 144, GOOG, 0); }
+    public void testMpeg4Goog1Qual0176x0144() throws Exception { qual(MPEG4, 176, 144, GOOG, 1); }
+    public void testMpeg4Goog1Perf0176x0144() throws Exception { perf(MPEG4, 176, 144, GOOG, 1); }
+
     public void testMpeg4Other0Qual0176x0144() throws Exception { qual(MPEG4, 176, 144, OTHER, 0); }
     public void testMpeg4Other0Perf0176x0144() throws Exception { perf(MPEG4, 176, 144, OTHER, 0); }
     public void testMpeg4Other1Qual0176x0144() throws Exception { qual(MPEG4, 176, 144, OTHER, 1); }
@@ -396,9 +447,12 @@
     public void testMpeg4Other2Perf0176x0144() throws Exception { perf(MPEG4, 176, 144, OTHER, 2); }
     public void testMpeg4Other3Qual0176x0144() throws Exception { qual(MPEG4, 176, 144, OTHER, 3); }
     public void testMpeg4Other3Perf0176x0144() throws Exception { perf(MPEG4, 176, 144, OTHER, 3); }
-    public void testMpeg4Count0352x0288() throws Exception { count(MPEG4, 352, 288, 1, 4); }
+    public void testMpeg4Count0352x0288() throws Exception { count(MPEG4, 352, 288, 2, 4); }
     public void testMpeg4Goog0Qual0352x0288() throws Exception { qual(MPEG4, 352, 288, GOOG, 0); }
     public void testMpeg4Goog0Perf0352x0288() throws Exception { perf(MPEG4, 352, 288, GOOG, 0); }
+    public void testMpeg4Goog1Qual0352x0288() throws Exception { qual(MPEG4, 352, 288, GOOG, 1); }
+    public void testMpeg4Goog1Perf0352x0288() throws Exception { perf(MPEG4, 352, 288, GOOG, 1); }
+
     public void testMpeg4Other0Qual0352x0288() throws Exception { qual(MPEG4, 352, 288, OTHER, 0); }
     public void testMpeg4Other0Perf0352x0288() throws Exception { perf(MPEG4, 352, 288, OTHER, 0); }
     public void testMpeg4Other1Qual0352x0288() throws Exception { qual(MPEG4, 352, 288, OTHER, 1); }
@@ -407,9 +461,12 @@
     public void testMpeg4Other2Perf0352x0288() throws Exception { perf(MPEG4, 352, 288, OTHER, 2); }
     public void testMpeg4Other3Qual0352x0288() throws Exception { qual(MPEG4, 352, 288, OTHER, 3); }
     public void testMpeg4Other3Perf0352x0288() throws Exception { perf(MPEG4, 352, 288, OTHER, 3); }
-    public void testMpeg4Count0640x0480() throws Exception { count(MPEG4, 640, 480, 1, 4); }
+    public void testMpeg4Count0640x0480() throws Exception { count(MPEG4, 640, 480, 2, 4); }
     public void testMpeg4Goog0Qual0640x0480() throws Exception { qual(MPEG4, 640, 480, GOOG, 0); }
     public void testMpeg4Goog0Perf0640x0480() throws Exception { perf(MPEG4, 640, 480, GOOG, 0); }
+    public void testMpeg4Goog1Qual0640x0480() throws Exception { qual(MPEG4, 640, 480, GOOG, 1); }
+    public void testMpeg4Goog1Perf0640x0480() throws Exception { perf(MPEG4, 640, 480, GOOG, 1); }
+
     public void testMpeg4Other0Qual0640x0480() throws Exception { qual(MPEG4, 640, 480, OTHER, 0); }
     public void testMpeg4Other0Perf0640x0480() throws Exception { perf(MPEG4, 640, 480, OTHER, 0); }
     public void testMpeg4Other1Qual0640x0480() throws Exception { qual(MPEG4, 640, 480, OTHER, 1); }
@@ -418,9 +475,12 @@
     public void testMpeg4Other2Perf0640x0480() throws Exception { perf(MPEG4, 640, 480, OTHER, 2); }
     public void testMpeg4Other3Qual0640x0480() throws Exception { qual(MPEG4, 640, 480, OTHER, 3); }
     public void testMpeg4Other3Perf0640x0480() throws Exception { perf(MPEG4, 640, 480, OTHER, 3); }
-    public void testMpeg4Count1280x0720() throws Exception { count(MPEG4, 1280, 720, 1, 4); }
+    public void testMpeg4Count1280x0720() throws Exception { count(MPEG4, 1280, 720, 2, 4); }
     public void testMpeg4Goog0Qual1280x0720() throws Exception { qual(MPEG4, 1280, 720, GOOG, 0); }
     public void testMpeg4Goog0Perf1280x0720() throws Exception { perf(MPEG4, 1280, 720, GOOG, 0); }
+    public void testMpeg4Goog1Qual1280x0720() throws Exception { qual(MPEG4, 1280, 720, GOOG, 1); }
+    public void testMpeg4Goog1Perf1280x0720() throws Exception { perf(MPEG4, 1280, 720, GOOG, 1); }
+
     public void testMpeg4Other0Qual1280x0720() throws Exception { qual(MPEG4, 1280, 720, OTHER, 0); }
     public void testMpeg4Other0Perf1280x0720() throws Exception { perf(MPEG4, 1280, 720, OTHER, 0); }
     public void testMpeg4Other1Qual1280x0720() throws Exception { qual(MPEG4, 1280, 720, OTHER, 1); }
@@ -431,39 +491,54 @@
     public void testMpeg4Other3Perf1280x0720() throws Exception { perf(MPEG4, 1280, 720, OTHER, 3); }
 
     // VP8 tests
-    public void testVp8Count0320x0180() throws Exception { count(VP8, 320, 180, 1, 2); }
+    public void testVp8Count0320x0180() throws Exception { count(VP8, 320, 180, 2, 2); }
     public void testVp8Goog0Qual0320x0180() throws Exception { qual(VP8, 320, 180, GOOG, 0); }
     public void testVp8Goog0Perf0320x0180() throws Exception { perf(VP8, 320, 180, GOOG, 0); }
+    public void testVp8Goog1Qual0320x0180() throws Exception { qual(VP8, 320, 180, GOOG, 1); }
+    public void testVp8Goog1Perf0320x0180() throws Exception { perf(VP8, 320, 180, GOOG, 1); }
+
     public void testVp8Other0Qual0320x0180() throws Exception { qual(VP8, 320, 180, OTHER, 0); }
     public void testVp8Other0Perf0320x0180() throws Exception { perf(VP8, 320, 180, OTHER, 0); }
     public void testVp8Other1Qual0320x0180() throws Exception { qual(VP8, 320, 180, OTHER, 1); }
     public void testVp8Other1Perf0320x0180() throws Exception { perf(VP8, 320, 180, OTHER, 1); }
-    public void testVp8Count0640x0360() throws Exception { count(VP8, 640, 360, 1, 2); }
+    public void testVp8Count0640x0360() throws Exception { count(VP8, 640, 360, 2, 2); }
     public void testVp8Goog0Qual0640x0360() throws Exception { qual(VP8, 640, 360, GOOG, 0); }
     public void testVp8Goog0Perf0640x0360() throws Exception { perf(VP8, 640, 360, GOOG, 0); }
+    public void testVp8Goog1Qual0640x0360() throws Exception { qual(VP8, 640, 360, GOOG, 1); }
+    public void testVp8Goog1Perf0640x0360() throws Exception { perf(VP8, 640, 360, GOOG, 1); }
+
     public void testVp8Other0Qual0640x0360() throws Exception { qual(VP8, 640, 360, OTHER, 0); }
     public void testVp8Other0Perf0640x0360() throws Exception { perf(VP8, 640, 360, OTHER, 0); }
     public void testVp8Other1Qual0640x0360() throws Exception { qual(VP8, 640, 360, OTHER, 1); }
     public void testVp8Other1Perf0640x0360() throws Exception { perf(VP8, 640, 360, OTHER, 1); }
-    public void testVp8Count1280x0720() throws Exception { count(VP8, 1280, 720, 1, 2); }
+    public void testVp8Count1280x0720() throws Exception { count(VP8, 1280, 720, 2, 2); }
     public void testVp8Goog0Qual1280x0720() throws Exception { qual(VP8, 1280, 720, GOOG, 0); }
     public void testVp8Goog0Perf1280x0720() throws Exception { perf(VP8, 1280, 720, GOOG, 0); }
+    public void testVp8Goog1Qual1280x0720() throws Exception { qual(VP8, 1280, 720, GOOG, 1); }
+    public void testVp8Goog1Perf1280x0720() throws Exception { perf(VP8, 1280, 720, GOOG, 1); }
+
     public void testVp8Other0Qual1280x0720() throws Exception { qual(VP8, 1280, 720, OTHER, 0); }
     public void testVp8Other0Perf1280x0720() throws Exception { perf(VP8, 1280, 720, OTHER, 0); }
     public void testVp8Other1Qual1280x0720() throws Exception { qual(VP8, 1280, 720, OTHER, 1); }
     public void testVp8Other1Perf1280x0720() throws Exception { perf(VP8, 1280, 720, OTHER, 1); }
-    public void testVp8Count1920x1080() throws Exception { count(VP8, 1920, 1080, 1, 2); }
+    public void testVp8Count1920x1080() throws Exception { count(VP8, 1920, 1080, 2, 2); }
     public void testVp8Goog0Qual1920x1080() throws Exception { qual(VP8, 1920, 1080, GOOG, 0); }
     public void testVp8Goog0Perf1920x1080() throws Exception { perf(VP8, 1920, 1080, GOOG, 0); }
+    public void testVp8Goog1Qual1920x1080() throws Exception { qual(VP8, 1920, 1080, GOOG, 1); }
+    public void testVp8Goog1Perf1920x1080() throws Exception { perf(VP8, 1920, 1080, GOOG, 1); }
+
     public void testVp8Other0Qual1920x1080() throws Exception { qual(VP8, 1920, 1080, OTHER, 0); }
     public void testVp8Other0Perf1920x1080() throws Exception { perf(VP8, 1920, 1080, OTHER, 0); }
     public void testVp8Other1Qual1920x1080() throws Exception { qual(VP8, 1920, 1080, OTHER, 1); }
     public void testVp8Other1Perf1920x1080() throws Exception { perf(VP8, 1920, 1080, OTHER, 1); }
 
     // VP9 tests
-    public void testVp9Count0320x0180() throws Exception { count(VP9, 320, 180, 1, 4); }
+    public void testVp9Count0320x0180() throws Exception { count(VP9, 320, 180, 2, 4); }
     public void testVp9Goog0Qual0320x0180() throws Exception { qual(VP9, 320, 180, GOOG, 0); }
     public void testVp9Goog0Perf0320x0180() throws Exception { perf(VP9, 320, 180, GOOG, 0); }
+    public void testVp9Goog1Qual0320x0180() throws Exception { qual(VP9, 320, 180, GOOG, 1); }
+    public void testVp9Goog1Perf0320x0180() throws Exception { perf(VP9, 320, 180, GOOG, 1); }
+
     public void testVp9Other0Qual0320x0180() throws Exception { qual(VP9, 320, 180, OTHER, 0); }
     public void testVp9Other0Perf0320x0180() throws Exception { perf(VP9, 320, 180, OTHER, 0); }
     public void testVp9Other1Qual0320x0180() throws Exception { qual(VP9, 320, 180, OTHER, 1); }
@@ -472,9 +547,12 @@
     public void testVp9Other2Perf0320x0180() throws Exception { perf(VP9, 320, 180, OTHER, 2); }
     public void testVp9Other3Qual0320x0180() throws Exception { qual(VP9, 320, 180, OTHER, 3); }
     public void testVp9Other3Perf0320x0180() throws Exception { perf(VP9, 320, 180, OTHER, 3); }
-    public void testVp9Count0640x0360() throws Exception { count(VP9, 640, 360, 1, 4); }
+    public void testVp9Count0640x0360() throws Exception { count(VP9, 640, 360, 2, 4); }
     public void testVp9Goog0Qual0640x0360() throws Exception { qual(VP9, 640, 360, GOOG, 0); }
     public void testVp9Goog0Perf0640x0360() throws Exception { perf(VP9, 640, 360, GOOG, 0); }
+    public void testVp9Goog1Qual0640x0360() throws Exception { qual(VP9, 640, 360, GOOG, 1); }
+    public void testVp9Goog1Perf0640x0360() throws Exception { perf(VP9, 640, 360, GOOG, 1); }
+
     public void testVp9Other0Qual0640x0360() throws Exception { qual(VP9, 640, 360, OTHER, 0); }
     public void testVp9Other0Perf0640x0360() throws Exception { perf(VP9, 640, 360, OTHER, 0); }
     public void testVp9Other1Qual0640x0360() throws Exception { qual(VP9, 640, 360, OTHER, 1); }
@@ -483,9 +561,12 @@
     public void testVp9Other2Perf0640x0360() throws Exception { perf(VP9, 640, 360, OTHER, 2); }
     public void testVp9Other3Qual0640x0360() throws Exception { qual(VP9, 640, 360, OTHER, 3); }
     public void testVp9Other3Perf0640x0360() throws Exception { perf(VP9, 640, 360, OTHER, 3); }
-    public void testVp9Count1280x0720() throws Exception { count(VP9, 1280, 720, 1, 4); }
+    public void testVp9Count1280x0720() throws Exception { count(VP9, 1280, 720, 2, 4); }
     public void testVp9Goog0Qual1280x0720() throws Exception { qual(VP9, 1280, 720, GOOG, 0); }
     public void testVp9Goog0Perf1280x0720() throws Exception { perf(VP9, 1280, 720, GOOG, 0); }
+    public void testVp9Goog1Qual1280x0720() throws Exception { qual(VP9, 1280, 720, GOOG, 1); }
+    public void testVp9Goog1Perf1280x0720() throws Exception { perf(VP9, 1280, 720, GOOG, 1); }
+
     public void testVp9Other0Qual1280x0720() throws Exception { qual(VP9, 1280, 720, OTHER, 0); }
     public void testVp9Other0Perf1280x0720() throws Exception { perf(VP9, 1280, 720, OTHER, 0); }
     public void testVp9Other1Qual1280x0720() throws Exception { qual(VP9, 1280, 720, OTHER, 1); }
@@ -494,9 +575,12 @@
     public void testVp9Other2Perf1280x0720() throws Exception { perf(VP9, 1280, 720, OTHER, 2); }
     public void testVp9Other3Qual1280x0720() throws Exception { qual(VP9, 1280, 720, OTHER, 3); }
     public void testVp9Other3Perf1280x0720() throws Exception { perf(VP9, 1280, 720, OTHER, 3); }
-    public void testVp9Count1920x1080() throws Exception { count(VP9, 1920, 1080, 1, 4); }
+    public void testVp9Count1920x1080() throws Exception { count(VP9, 1920, 1080, 2, 4); }
     public void testVp9Goog0Qual1920x1080() throws Exception { qual(VP9, 1920, 1080, GOOG, 0); }
     public void testVp9Goog0Perf1920x1080() throws Exception { perf(VP9, 1920, 1080, GOOG, 0); }
+    public void testVp9Goog1Qual1920x1080() throws Exception { qual(VP9, 1920, 1080, GOOG, 1); }
+    public void testVp9Goog1Perf1920x1080() throws Exception { perf(VP9, 1920, 1080, GOOG, 1); }
+
     public void testVp9Other0Qual1920x1080() throws Exception { qual(VP9, 1920, 1080, OTHER, 0); }
     public void testVp9Other0Perf1920x1080() throws Exception { perf(VP9, 1920, 1080, OTHER, 0); }
     public void testVp9Other1Qual1920x1080() throws Exception { qual(VP9, 1920, 1080, OTHER, 1); }
@@ -505,9 +589,12 @@
     public void testVp9Other2Perf1920x1080() throws Exception { perf(VP9, 1920, 1080, OTHER, 2); }
     public void testVp9Other3Qual1920x1080() throws Exception { qual(VP9, 1920, 1080, OTHER, 3); }
     public void testVp9Other3Perf1920x1080() throws Exception { perf(VP9, 1920, 1080, OTHER, 3); }
-    public void testVp9Count3840x2160() throws Exception { count(VP9, 3840, 2160, 1, 4); }
+    public void testVp9Count3840x2160() throws Exception { count(VP9, 3840, 2160, 2, 4); }
     public void testVp9Goog0Qual3840x2160() throws Exception { qual(VP9, 3840, 2160, GOOG, 0); }
     public void testVp9Goog0Perf3840x2160() throws Exception { perf(VP9, 3840, 2160, GOOG, 0); }
+    public void testVp9Goog1Qual3840x2160() throws Exception { qual(VP9, 3840, 2160, GOOG, 1); }
+    public void testVp9Goog1Perf3840x2160() throws Exception { perf(VP9, 3840, 2160, GOOG, 1); }
+
     public void testVp9Other0Qual3840x2160() throws Exception { qual(VP9, 3840, 2160, OTHER, 0); }
     public void testVp9Other0Perf3840x2160() throws Exception { perf(VP9, 3840, 2160, OTHER, 0); }
     public void testVp9Other1Qual3840x2160() throws Exception { qual(VP9, 3840, 2160, OTHER, 1); }
diff --git a/tools/cts-preconditions/Android.mk b/tools/cts-preconditions/Android.mk
index 5f00c36..9c8cbf2 100644
--- a/tools/cts-preconditions/Android.mk
+++ b/tools/cts-preconditions/Android.mk
@@ -38,6 +38,6 @@
 
 LOCAL_PACKAGE_NAME := CtsPreconditions
 
-LOCAL_SDK_VERSION := current
+LOCAL_SDK_VERSION := 26
 
 include $(BUILD_PACKAGE)