Merge "CTS: fix VulkanPreTransformTest on HiKey960"
diff --git a/CtsCoverage.mk b/CtsCoverage.mk
index 8a0eef8..3f54cb3 100644
--- a/CtsCoverage.mk
+++ b/CtsCoverage.mk
@@ -94,7 +94,7 @@
 .PHONY: cts-combined-xml-coverage
 cts-combined-xml-coverage : $(cts-combined-xml-coverage-report)
 
-.PHONY: cts-api-coverage
+.PHONY: cts-coverage-report-all cts-api-coverage
 cts-coverage-report-all: cts-test-coverage cts-verifier-coverage cts-combined-coverage cts-combined-xml-coverage
 
 # Put the test coverage report in the dist dir if "cts-api-coverage" is among the build goals.
diff --git a/apps/CameraITS/tests/scene4/test_aspect_ratio_and_crop.py b/apps/CameraITS/tests/scene4/test_aspect_ratio_and_crop.py
index cf30457..75a95d2 100644
--- a/apps/CameraITS/tests/scene4/test_aspect_ratio_and_crop.py
+++ b/apps/CameraITS/tests/scene4/test_aspect_ratio_and_crop.py
@@ -63,23 +63,50 @@
         if np.isclose(sensor_ar, convert_ar_to_float(ar_string), atol=FMT_ATOL):
             match_ar = ar_string
     if not match_ar:
-        print "Error: no aspect ratio match with sensor parameters!"
+        print "Warning! RAW aspect ratio not in:", AR_CHECKED
     return match_ar
 
 
-def aspect_ratio_scale_factors(camera_ar_string):
+def aspect_ratio_scale_factors(ref_ar_string, props):
     """Determine scale factors for each aspect ratio to correct cropping.
 
     Args:
-        camera_ar_string:   camera aspect ratio that is the baseline
+        ref_ar_string:      camera aspect ratio that is the reference
+        props:              camera properties
     Returns:
         dict of correction ratios with AR_CHECKED values as keys
     """
-    ar_scaling = {}
-    camera_ar = convert_ar_to_float(camera_ar_string)
+    ref_ar = convert_ar_to_float(ref_ar_string)
+
+    # find sensor area
+    height_max = 0
+    width_max = 0
     for ar_string in AR_CHECKED:
-        ar = convert_ar_to_float(ar_string)
-        ar_scaling[ar_string] = ar / camera_ar
+        match_ar = [float(x) for x in ar_string.split(":")]
+        f = its.objects.get_largest_yuv_format(props, match_ar=match_ar)
+        if f["height"] > height_max:
+            height_max = f["height"]
+        if f["width"] > width_max:
+            width_max = f["width"]
+    sensor_ar = float(width_max) / height_max
+
+    # apply scaling
+    ar_scaling = {}
+    for ar_string in AR_CHECKED:
+        target_ar = convert_ar_to_float(ar_string)
+        # scale down to sensor with greater (or equal) dims
+        if ref_ar >= sensor_ar:
+            scaling = sensor_ar / ref_ar
+        else:
+            scaling = ref_ar / sensor_ar
+
+        # scale up due to cropping to other format
+        if target_ar >= sensor_ar:
+            scaling = scaling * target_ar / sensor_ar
+        else:
+            scaling = scaling * sensor_ar / target_ar
+
+        ar_scaling[ar_string] = scaling
     return ar_scaling
 
 
@@ -95,10 +122,20 @@
         ref_fov:    dict with [fmt, % coverage, w, h]
     """
     ref_fov = {}
-    ar = determine_sensor_aspect_ratio(props)
-    match_ar = [float(x) for x in ar.split(":")]
-    fmt = its.objects.get_largest_yuv_format(props, match_ar=match_ar)
-    cap = cam.do_capture(req, fmt)
+    pixels = []
+    fmt_list = []
+    # find number of pixels in different formats
+    for ar in AR_CHECKED:
+        match_ar = [float(x) for x in ar.split(":")]
+        f = its.objects.get_largest_yuv_format(props, match_ar=match_ar)
+        pixels.append(f["height"] * f["width"])
+        fmt_list.append(f)
+
+    # use image with largest coverage as reference
+    ar_max_pixels = np.argmax(pixels)
+
+    # capture and determine circle area in image
+    cap = cam.do_capture(req, fmt_list[ar_max_pixels])
     w = cap["width"]
     h = cap["height"]
     img = its.image.convert_capture_to_rgb_image(cap, props=props)
@@ -106,7 +143,7 @@
     img_name = "%s_%s_w%d_h%d.png" % (NAME, "yuv", w, h)
     _, _, circle_size = measure_aspect_ratio(img, False, img_name, True)
     fov_percent = calc_circle_image_ratio(circle_size[1], circle_size[0], w, h)
-    ref_fov["fmt"] = ar
+    ref_fov["fmt"] = AR_CHECKED[ar_max_pixels]
     ref_fov["percent"] = fov_percent
     ref_fov["w"] = w
     ref_fov["h"] = h
@@ -259,16 +296,20 @@
             factor_cp_thres = (min(size_raw[0:1])/4.0) / max(circle_size_raw)
             thres_l_cp_test = THRESH_L_CP * factor_cp_thres
             thres_xs_cp_test = THRESH_XS_CP * factor_cp_thres
+            # If RAW in AR_CHECKED, use it as reference
             ref_fov["fmt"] = determine_sensor_aspect_ratio(props)
-            ref_fov["percent"] = raw_fov_percent
-            ref_fov["w"] = w_raw
-            ref_fov["h"] = h_raw
-            print "Using RAW reference:", ref_fov
+            if ref_fov["fmt"]:
+                ref_fov["percent"] = raw_fov_percent
+                ref_fov["w"] = w_raw
+                ref_fov["h"] = h_raw
+                print "Using RAW reference:", ref_fov
+            else:
+                ref_fov = find_yuv_fov_reference(cam, req, props)
         else:
             ref_fov = find_yuv_fov_reference(cam, req, props)
 
         # Determine scaling factors for AR calculations
-        ar_scaling = aspect_ratio_scale_factors(ref_fov["fmt"])
+        ar_scaling = aspect_ratio_scale_factors(ref_fov["fmt"], props)
 
         # Take pictures of each settings with all the image sizes available.
         for fmt in format_list:
diff --git a/apps/CameraITS/tests/scene4/test_multi_camera_alignment.py b/apps/CameraITS/tests/scene4/test_multi_camera_alignment.py
index 572f4ea..4c3c4d9 100644
--- a/apps/CameraITS/tests/scene4/test_multi_camera_alignment.py
+++ b/apps/CameraITS/tests/scene4/test_multi_camera_alignment.py
@@ -25,14 +25,58 @@
 
 import numpy as np
 
-ALIGN_TOL_PERCENT = 1
+ALIGN_TOL_MM = 4.0E-3  # mm
+ALIGN_TOL = 0.01  # multiplied by sensor diagonal to convert to pixels
 CHART_DISTANCE_CM = 22  # cm
-CIRCLE_TOL_PERCENT = 10
+CIRCLE_RTOL = 0.1
 GYRO_REFERENCE = 1
 NAME = os.path.basename(__file__).split('.')[0]
 TRANS_REF_MATRIX = np.array([0, 0, 0])
 
 
+def convert_to_world_coordinates(x, y, r, t, k, z_w):
+    """Convert x,y coordinates to world coordinates.
+
+    Conversion equation is:
+    A = [[x*r[2][0] - dot(k_row0, r_col0), x*r_[2][1] - dot(k_row0, r_col1)],
+         [y*r[2][0] - dot(k_row1, r_col0), y*r_[2][1] - dot(k_row1, r_col1)]]
+    b = [[z_w*dot(k_row0, r_col2) + dot(k_row0, t) - x*(r[2][2]*z_w + t[2])],
+         [z_w*dot(k_row1, r_col2) + dot(k_row1, t) - y*(r[2][2]*z_w + t[2])]]
+
+    [[x_w], [y_w]] = inv(A) * b
+
+    Args:
+        x:      x location in pixel space
+        y:      y location in pixel space
+        r:      rotation matrix
+        t:      translation matrix
+        k:      intrinsic matrix
+        z_w:    z distance in world space
+
+    Returns:
+        x_w:    x in meters in world space
+        y_w:    y in meters in world space
+    """
+    c_1 = r[2, 2] * z_w + t[2]
+    k_x1 = np.dot(k[0, :], r[:, 0])
+    k_x2 = np.dot(k[0, :], r[:, 1])
+    k_x3 = z_w * np.dot(k[0, :], r[:, 2]) + np.dot(k[0, :], t)
+    k_y1 = np.dot(k[1, :], r[:, 0])
+    k_y2 = np.dot(k[1, :], r[:, 1])
+    k_y3 = z_w * np.dot(k[1, :], r[:, 2]) + np.dot(k[1, :], t)
+
+    a = np.array([[x*r[2][0]-k_x1, x*r[2][1]-k_x2],
+                  [y*r[2][0]-k_y1, y*r[2][1]-k_y2]])
+    b = np.array([[k_x3-x*c_1], [k_y3-y*c_1]])
+    return np.dot(np.linalg.inv(a), b)
+
+
+def convert_to_image_coordinates(p_w, r, t, k):
+    p_c = np.dot(r, p_w) + t
+    p_h = np.dot(k, p_c)
+    return p_h[0] / p_h[2], p_h[1] / p_h[2]
+
+
 def rotation_matrix(rotation):
     """Convert the rotation parameters to 3-axis data.
 
@@ -50,29 +94,119 @@
                      [2*x*z-2*y*w, 2*y*z+2*x*w, 1-2*x**2-2*y**2]])
 
 
+# TODO: merge find_circle() & test_aspect_ratio_and_crop.measure_aspect_ratio()
+# for a unified circle script that is and in pymodules/image.py
 def find_circle(gray, name):
-    """Find the circle in the image.
+    """Find the black circle in the image.
 
     Args:
-        gray:           gray scale image array [0,255]
-        name:           string of file name
+        gray:           numpy grayscale array with pixel values in [0,255].
+        name:           string of file name.
     Returns:
         circle:         (circle_center_x, circle_center_y, radius)
     """
+    size = gray.shape
+    # otsu threshold to binarize the image
+    _, img_bw = cv2.threshold(np.uint8(gray), 0, 255,
+                              cv2.THRESH_BINARY + cv2.THRESH_OTSU)
 
+    # connected component
     cv2_version = cv2.__version__
-    try:
-        if cv2_version.startswith('2.4.'):
-            circle = cv2.HoughCircles(gray, cv2.cv.CV_HOUGH_GRADIENT,
-                                      1, 20)[0][0]
-        elif cv2_version.startswith('3.2.'):
-            circle = cv2.HoughCircles(gray, cv2.HOUGH_GRADIENT,
-                                      1, 20)[0][0]
-    except TypeError:
-        circle = None
-        its.image.write_image(gray[..., np.newaxis]/255.0, name)
-    assert circle is not None, 'No circle found!'
-    return circle
+    if cv2_version.startswith('2.4.'):
+        contours, hierarchy = cv2.findContours(255-img_bw, cv2.RETR_TREE,
+                                               cv2.CHAIN_APPROX_SIMPLE)
+    elif cv2_version.startswith('3.2.'):
+        _, contours, hierarchy = cv2.findContours(255-img_bw, cv2.RETR_TREE,
+                                                  cv2.CHAIN_APPROX_SIMPLE)
+
+    # Check each component and find the black circle
+    min_cmpt = size[0] * size[1] * 0.005
+    max_cmpt = size[0] * size[1] * 0.35
+    num_circle = 0
+    for ct, hrch in zip(contours, hierarchy[0]):
+        # The radius of the circle is 1/3 of the length of the square, meaning
+        # around 1/3 of the area of the square
+        # Parental component should exist and the area is acceptable.
+        # The contour of a circle should have at least 5 points
+        child_area = cv2.contourArea(ct)
+        if (hrch[3] == -1 or child_area < min_cmpt or child_area > max_cmpt
+                    or len(ct) < 15):
+            continue
+        # Check the shapes of current component and its parent
+        child_shape = component_shape(ct)
+        parent = hrch[3]
+        prt_shape = component_shape(contours[parent])
+        prt_area = cv2.contourArea(contours[parent])
+        dist_x = abs(child_shape['ctx']-prt_shape['ctx'])
+        dist_y = abs(child_shape['cty']-prt_shape['cty'])
+        # 1. 0.56*Parent's width < Child's width < 0.76*Parent's width.
+        # 2. 0.56*Parent's height < Child's height < 0.76*Parent's height.
+        # 3. Child's width > 0.1*Image width
+        # 4. Child's height > 0.1*Image height
+        # 5. 0.25*Parent's area < Child's area < 0.45*Parent's area
+        # 6. Child is a black, and Parent is white
+        # 7. Center of Child and center of parent should overlap
+        if (prt_shape['width'] * 0.56 < child_shape['width']
+                    < prt_shape['width'] * 0.76
+                    and prt_shape['height'] * 0.56 < child_shape['height']
+                    < prt_shape['height'] * 0.76
+                    and child_shape['width'] > 0.1 * size[1]
+                    and child_shape['height'] > 0.1 * size[0]
+                    and 0.30 * prt_area < child_area < 0.50 * prt_area
+                    and img_bw[child_shape['cty']][child_shape['ctx']] == 0
+                    and img_bw[child_shape['top']][child_shape['left']] == 255
+                    and dist_x < 0.1 * child_shape['width']
+                    and dist_y < 0.1 * child_shape['height']):
+            # Calculate circle center and size
+            circle_ctx = float(child_shape['ctx'])
+            circle_cty = float(child_shape['cty'])
+            circle_w = float(child_shape['width'])
+            circle_h = float(child_shape['height'])
+            num_circle += 1
+            # If more than one circle found, break
+            if num_circle == 2:
+                break
+    its.image.write_image(gray[..., np.newaxis]/255.0, name)
+
+    if num_circle == 0:
+        print 'No black circle was detected. Please take pictures according',
+        print 'to instruction carefully!\n'
+        assert num_circle == 1
+
+    if num_circle > 1:
+        print 'More than one black circle was detected. Background of scene',
+        print 'may be too complex.\n'
+        assert num_circle == 1
+    return (circle_ctx, circle_cty, (circle_w+circle_h)/4.0)
+
+
+def component_shape(contour):
+    """Measure the shape of a connected component.
+
+    Args:
+        contour: return from cv2.findContours. A list of pixel coordinates of
+        the contour.
+
+    Returns:
+        The most left, right, top, bottom pixel location, height, width, and
+        the center pixel location of the contour.
+    """
+    shape = {'left': np.inf, 'right': 0, 'top': np.inf, 'bottom': 0,
+             'width': 0, 'height': 0, 'ctx': 0, 'cty': 0}
+    for pt in contour:
+        if pt[0][0] < shape['left']:
+            shape['left'] = pt[0][0]
+        if pt[0][0] > shape['right']:
+            shape['right'] = pt[0][0]
+        if pt[0][1] < shape['top']:
+            shape['top'] = pt[0][1]
+        if pt[0][1] > shape['bottom']:
+            shape['bottom'] = pt[0][1]
+    shape['width'] = shape['right'] - shape['left'] + 1
+    shape['height'] = shape['bottom'] - shape['top'] + 1
+    shape['ctx'] = (shape['left']+shape['right'])/2
+    shape['cty'] = (shape['top']+shape['bottom'])/2
+    return shape
 
 
 def define_reference_camera(pose_reference, cam_reference):
@@ -98,12 +232,34 @@
 
 
 def main():
-    """Test the multi camera system parameters related to camera spacing."""
+    """Test the multi camera system parameters related to camera spacing.
+
+    Using the multi-camera physical cameras, take a picture of scene4
+    (a black circle and surrounding square on a white background) with
+    one of the physical cameras. Then find the circle center. Using the
+    parameters:
+        android.lens.poseReference
+        android.lens.poseTranslation
+        android.lens.poseRotation
+        android.lens.instrinsicCalibration
+        android.lens.distortion (if available)
+    project the circle center to the world coordinates for each camera.
+    Compare the difference between the two cameras' circle centers in
+    world coordinates.
+
+    Reproject the world coordinates back to pixel coordinates and compare
+    against originals as a sanity check.
+
+    Compare the circle sizes if the focal lengths of the cameras are
+    different using
+        android.lens.availableFocalLengths.
+    """
     chart_distance = CHART_DISTANCE_CM
     for s in sys.argv[1:]:
         if s[:5] == 'dist=' and len(s) > 5:
             chart_distance = float(re.sub('cm', '', s[5:]))
             print 'Using chart distance: %.1fcm' % chart_distance
+    chart_distance *= 1.0E-2
 
     with its.device.ItsSession() as cam:
         props = cam.get_camera_properties()
@@ -123,6 +279,7 @@
         # Do 3A and get the values
         s, e, _, _, fd = cam.do_3a(get_results=True,
                                    lock_ae=True, lock_awb=True)
+        e *= 2  # brighten RAW images
         req = its.objects.manual_capture_request(s, e, fd, True, props)
 
         # get physical camera properties
@@ -141,14 +298,13 @@
     size_raw = {}
     k = {}
     cam_reference = {}
-    rotation = {}
-    trans = {}
+    r = {}
+    t = {}
     circle = {}
     fl = {}
     sensor_diag = {}
-    point = {}
     for i in ids:
-        print 'Starting camera %s' % i
+        print 'Camera %s' % i
         # process image
         img_raw = its.image.convert_capture_to_rgb_image(
                 cap_raw[i], props=props)
@@ -172,92 +328,122 @@
                          [0, 0, 1]])
         print ' k:', k[i]
 
-        rotation[i] = np.array(props_physical[i]['android.lens.poseRotation'])
-        print ' rotation:', rotation[i]
-        assert len(rotation[i]) == 4, 'poseRotation has wrong # of params.'
-        trans[i] = np.array(
-                props_physical[i]['android.lens.poseTranslation'])
-        print ' translation:', trans[i]
-        assert len(trans[i]) == 3, 'poseTranslation has wrong # of params.'
-        if (trans[i] == TRANS_REF_MATRIX).all():
+        rotation = np.array(props_physical[i]['android.lens.poseRotation'])
+        print ' rotation:', rotation
+        assert len(rotation) == 4, 'poseRotation has wrong # of params.'
+        r[i] = rotation_matrix(rotation)
+
+        t[i] = np.array(props_physical[i]['android.lens.poseTranslation'])
+        print ' translation:', t[i]
+        assert len(t[i]) == 3, 'poseTranslation has wrong # of params.'
+        if (t[i] == TRANS_REF_MATRIX).all():
             cam_reference[i] = True
         else:
             cam_reference[i] = False
 
+        # API spec defines poseTranslation as the world coordinate p_w_cam of
+        # optics center. When applying [R|t] to go from world coordinates to
+        # camera coordinates, we need -R*p_w_cam of the coordinate reported in
+        # metadata.
+        # ie. for a camera with optical center at world coordinate (5, 4, 3)
+        # and identity rotation, to convert a world coordinate into the
+        # camera's coordinate, we need a translation vector of [-5, -4, -3]
+        # so that: [I|[-5, -4, -3]^T] * [5, 4, 3]^T = [0,0,0]^T
+        t[i] = -1.0 * np.dot(r[i], t[i])
+        if debug:
+            print 't:', t[i]
+            print 'r:', r[i]
+
+        # Do operation on distorted image
+        print 'Detecting pre-correction circle'
+        circle_distorted = find_circle(cv2.cvtColor(img, cv2.COLOR_BGR2GRAY),
+                                       '%s_gray_precorr_cam_%s.jpg' % (NAME, i))
+        print 'camera %s circle pre-distortion correction: x, y: %.2f, %.2f' % (
+                i, circle_distorted[0], circle_distorted[1])
+
         # Apply correction to image (if available)
         if its.caps.distortion_correction(props):
             distort = np.array(props_physical[i]['android.lens.distortion'])
-            assert len(distort) == 5, 'radialDistortion has wrong # of params.'
+            assert len(distort) == 5, 'distortion has wrong # of params.'
             cv2_distort = np.array([distort[0], distort[1],
                                     distort[3], distort[4],
                                     distort[2]])
+            print ' cv2 distortion params:', cv2_distort
+            its.image.write_image(img/255.0, '%s_raw_%s.jpg' % (
+                    NAME, i))
             img = cv2.undistort(img, k[i], cv2_distort)
             its.image.write_image(img/255.0, '%s_correct_%s.jpg' % (
                     NAME, i))
 
         # Find the circles in grayscale image
         circle[i] = find_circle(cv2.cvtColor(img, cv2.COLOR_BGR2GRAY),
-                                '%s_gray%s.jpg' % (NAME, i))
+                                '%s_gray_%s.jpg' % (NAME, i))
 
         # Find focal length & sensor size
         fl[i] = props_physical[i]['android.lens.info.availableFocalLengths'][0]
         sensor_diag[i] = math.sqrt(size_raw[i][0] ** 2 + size_raw[i][1] ** 2)
 
-        # Find 3D location of circle centers
-        point[i] = np.dot(np.linalg.inv(k[i]),
-                          np.array([circle[i][0],
-                                    circle[i][1], 1])) * chart_distance * 1.0E-2
-
     i_ref, i_2nd = define_reference_camera(pose_reference, cam_reference)
     print 'reference camera: %s, secondary camera: %s' % (i_ref, i_2nd)
 
-    # TODO(b/90772945): convert to world coordinates for more general purpose
-    r = rotation_matrix(rotation[i_2nd].astype(np.float32))
-    if debug:
-        print 'r:', r
-    t = trans[i_2nd] * -1.0
-    print 't:', t
+    # Convert circle centers to real world coordinates
+    x_w = {}
+    y_w = {}
+    if props['android.lens.facing']:
+        print 'lens facing BACK'
+        chart_distance *= -1  # API spec defines +z i pointing out from screen
+    for i in [i_ref, i_2nd]:
+        x_w[i], y_w[i] = convert_to_world_coordinates(
+                circle[i][0], circle[i][1], r[i], t[i], k[i], chart_distance)
 
-    # Estimate ids[0] circle center from ids[1] & params
-    estimated_0 = cv2.projectPoints(point[ids[1]].reshape(1, 3),
-                                    r, t, k[ids[0]], None)[0][0][0]
-    err_0 = np.linalg.norm(estimated_0 - circle[ids[0]][:2])
-    print 'Circle centers [%s]' % ids[0]
-    print 'Measured:      %.1f, %.1f' % (circle[ids[0]][1], circle[ids[0]][0])
-    print 'Calculated:    %.1f, %.1f' % (estimated_0[1],
-                                         estimated_0[0])
-    print 'Error(pixels): %.1f' % err_0
+    # Back convert to image coordinates for sanity check
+    x_p = {}
+    y_p = {}
+    x_p[i_2nd], y_p[i_2nd] = convert_to_image_coordinates(
+            [x_w[i_ref], y_w[i_ref], chart_distance],
+            r[i_2nd], t[i_2nd], k[i_2nd])
+    x_p[i_ref], y_p[i_ref] = convert_to_image_coordinates(
+            [x_w[i_2nd], y_w[i_2nd], chart_distance],
+            r[i_ref], t[i_ref], k[i_ref])
 
-    # Estimate ids[0] circle center from ids[1] & params
-    estimated_1 = cv2.projectPoints(point[ids[0]].reshape(1, 3),
-                                    r.T, -np.dot(r, t), k[ids[1]],
-                                    None)[0][0][0]
-    err_1 = np.linalg.norm(estimated_1 - circle[ids[1]][:2])
-    print 'Circle centers [%s]' % ids[1]
-    print 'Measured:      %.1f, %.1f' % (circle[ids[1]][1], circle[ids[1]][0])
-    print 'Calculated:    %.1f, %.1f' % (estimated_1[1], estimated_1[0])
-    print 'Error(pixels): %.1f' % err_1
+    # Summarize results
+    for i in [i_ref, i_2nd]:
+        print ' Camera: %s' % i
+        print ' x, y (pixels): %.1f, %.1f' % (circle[i][0], circle[i][1])
+        print ' x_w, y_w (mm): %.2f, %.2f' % (x_w[i]*1.0E3, y_w[i]*1.0E3)
+        print ' x_p, y_p (pixels): %.1f, %.1f' % (x_p[i], y_p[i])
 
-    err_0 /= math.sqrt(size_raw[ids[0]][0]**2 + size_raw[ids[0]][1]**2)
-    err_1 /= math.sqrt(size_raw[ids[1]][0]**2 + size_raw[ids[1]][1]**2)
-    msg = '%s -> %s center error too large! val=%.1f%%, THRESH=%.f%%' % (
-            ids[1], ids[0], err_0*100, ALIGN_TOL_PERCENT)
-    assert err_0*100 < ALIGN_TOL_PERCENT, msg
-    msg = '%s -> %s center error too large! val=%.1f%%, THRESH=%.f%%' % (
-            ids[0], ids[1], err_1*100, ALIGN_TOL_PERCENT)
-    assert err_1*100 < ALIGN_TOL_PERCENT, msg
+    # Check center locations
+    err = np.linalg.norm(np.array([x_w[i_ref], y_w[i_ref]]) -
+                         np.array([x_w[i_2nd], y_w[i_2nd]]))
+    print '\nCenter location err (mm): %.2f' % (err*1E3)
+    msg = 'Center locations %s <-> %s too different!' % (i_ref, i_2nd)
+    msg += ' val=%.2fmm, THRESH=%.fmm' % (err*1E3, ALIGN_TOL_MM*1E3)
+    assert err < ALIGN_TOL, msg
+
+    # Check projections back into pixel space
+    for i in [i_ref, i_2nd]:
+        err = np.linalg.norm(np.array([circle[i][0], circle[i][1]]) -
+                             np.array([x_p[i], y_p[i]]))
+        print 'Camera %s projection error (pixels): %.1f' % (i, err)
+        tol = ALIGN_TOL * sensor_diag[i]
+        msg = 'Camera %s project locations too different!' % i
+        msg += ' diff=%.2f, TOL=%.2f' % (err, tol)
+        assert err < tol, msg
 
     # Check focal length and circle size if more than 1 focal length
     if len(avail_fls) > 1:
-        print 'circle_0: %.2f, circle_1: %.2f' % (
-                circle[ids[0]][2], circle[ids[1]][2])
-        print 'fl_0: %.2f, fl_1: %.2f' % (fl[ids[0]], fl[ids[1]])
-        print 'diag_0: %.2f, diag_1: %.2f' % (
-                sensor_diag[ids[0]], sensor_diag[ids[1]])
-        msg = 'Circle size does not scale properly.'
-        assert np.isclose(circle[ids[0]][2]/fl[ids[0]]*sensor_diag[ids[0]],
-                          circle[ids[1]][2]/fl[ids[1]]*sensor_diag[ids[1]],
-                          rtol=CIRCLE_TOL_PERCENT/100.0), msg
+        print 'Circle radii (pixels); ref: %.1f, 2nd: %.1f' % (
+                circle[i_ref][2], circle[i_2nd][2])
+        print 'Focal lengths (diopters); ref: %.2f, 2nd: %.2f' % (
+                fl[i_ref], fl[i_2nd])
+        print 'Sensor diagonals (pixels); ref: %.2f, 2nd: %.2f' % (
+                sensor_diag[i_ref], sensor_diag[i_2nd])
+        msg = 'Circle size scales improperly! RTOL=%.1f' % CIRCLE_RTOL
+        msg += '\nMetric: radius/focal_length*sensor_diag should be equal.'
+        assert np.isclose(circle[i_ref][2]/fl[i_ref]*sensor_diag[i_ref],
+                          circle[i_2nd][2]/fl[i_2nd]*sensor_diag[i_2nd],
+                          rtol=CIRCLE_RTOL), msg
 
 
 if __name__ == '__main__':
diff --git a/apps/CameraITS/tools/run_all_tests.py b/apps/CameraITS/tools/run_all_tests.py
index c8d2bac..a6e0402 100644
--- a/apps/CameraITS/tools/run_all_tests.py
+++ b/apps/CameraITS/tools/run_all_tests.py
@@ -67,9 +67,7 @@
                 "test_lens_movement_reporting",
                 "test_lens_position"
         ],
-        "scene4": [
-                "test_multi_camera_alignment"
-        ],
+        "scene4": [],
         "scene5": [],
         "sensor_fusion": []
 }
@@ -338,7 +336,7 @@
             # Extract chart from scene for scene3 once up front
             chart_loc_arg = ''
             if scene == 'scene3':
-                if float(camera_fov) < 90 and np.isclose(chart_distance, 20,
+                if float(camera_fov) < 90 and np.isclose(chart_distance, 22,
                                                          rtol=0.1):
                     chart_height *= 0.67
                 chart = its.cv2image.Chart(SCENE3_FILE, chart_height,
diff --git a/apps/CtsVerifier/res/values/strings.xml b/apps/CtsVerifier/res/values/strings.xml
index c666226..d7a688c 100755
--- a/apps/CtsVerifier/res/values/strings.xml
+++ b/apps/CtsVerifier/res/values/strings.xml
@@ -1086,7 +1086,7 @@
         1. Connect device via usb to computer.\n
         2. Click \"Show overlay\" button.  Settings may appear if the CTS Verifier app doesn\'t have display over apps permission.  Enable this permission and then click back to navigate back to the app.\n
         3. Trigger USB debugging dialog (from computer terminal): \"adb shell am start -e fingerprints placeholder -e key placeholder com.android.systemui/.UsbDebuggingActivityAlias\"\n
-        4. USB debugging dialog should appear with the overlay on top saying \"This message covers the USB debugging RSA prompt\" to appear.\n
+        4. USB debugging dialog should appear.  If the overlay cannot be seen above the USB debugging dialog, PASS this test (no need to proceed to Step 5).  Else, if the overlay does appear on top saying \"This message covers the USB debugging RSA prompt\", continue to Step 5.\n
         5. Try clicking OK. \n
         Test pass if you cannot click OK when the text quoted above is on top of the USB debugging dialog.  Toast should appear saying there is an overlay so Settings cannot verify your response. \n
         Note: Fake message overlay may remain on screen until you leave the test. This is working as intended. \n
@@ -4002,6 +4002,10 @@
     <string name="uapButtonsBtnDLbl">Button D - voice assist</string>
     <string name="uapButtonsRecognized">Recognized</string>
     <string name="uapButtonsNotRecognized">Not Recognized</string>
+    <string name="uapButtonsDisableAssistantTitle">Disable Google Assistant</string>
+    <string name="uapButtonsDisableAssistant">For this test to succeed it may be necessary
+        to disable the Google Assistant (Settings / Google / Search / Google Assistant Settings /
+        Devices / &lt;device name&gt; / Google Assistant)</string>
 
     <!--  Pro Audio Tests -->
     <string name="pro_audio_latency_test">Pro Audio Test</string>
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/audio/USBAudioPeripheralButtonsActivity.java b/apps/CtsVerifier/src/com/android/cts/verifier/audio/USBAudioPeripheralButtonsActivity.java
index 87b2149..7ee340a 100644
--- a/apps/CtsVerifier/src/com/android/cts/verifier/audio/USBAudioPeripheralButtonsActivity.java
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/audio/USBAudioPeripheralButtonsActivity.java
@@ -16,6 +16,8 @@
 
 package com.android.cts.verifier.audio;
 
+import android.app.AlertDialog;
+import android.content.DialogInterface;
 import android.content.res.Resources;
 import android.graphics.Color;
 import android.os.Bundle;
@@ -45,6 +47,19 @@
     private TextView mBtnBStatusTxt;
     private TextView mBtnCStatusTxt;
 
+    private void showDisableAssistantDialog() {
+        AlertDialog.Builder builder =
+                new AlertDialog.Builder(this, android.R.style.Theme_Material_Dialog_Alert);
+        builder.setTitle(getResources().getString(R.string.uapButtonsDisableAssistantTitle));
+        builder.setMessage(getResources().getString(R.string.uapButtonsDisableAssistant));
+        builder.setPositiveButton(android.R.string.yes,
+            new DialogInterface.OnClickListener() {
+                public void onClick(DialogInterface dialog, int which) {}
+         });
+        builder.setIcon(android.R.drawable.ic_dialog_alert);
+        builder.show();
+    }
+
     @Override
     protected void onCreate(Bundle savedInstanceState) {
         super.onCreate(savedInstanceState);
@@ -62,6 +77,8 @@
 
         setPassFailButtonClickListeners();
         setInfoResources(R.string.usbaudio_buttons_test, R.string.usbaudio_buttons_info, -1);
+
+        showDisableAssistantDialog();
     }
 
     private void showButtonsState() {
diff --git a/error_prone_rules.mk b/error_prone_rules.mk
index 33382dd..7e900e6 100644
--- a/error_prone_rules.mk
+++ b/error_prone_rules.mk
@@ -13,23 +13,23 @@
 # limitations under the License.
 
 # Set of error prone rules to ensure code quality
-LOCAL_ERROR_PRONE_FLAGS:= -Xep:ArrayToString:ERROR \
-                          -Xep:BoxedPrimitiveConstructor:ERROR \
-                          -Xep:ConstantField:ERROR \
-                          -Xep:EqualsIncompatibleType:ERROR \
-                          -Xep:FormatString:ERROR \
-                          -Xep:GetClassOnClass:ERROR \
-                          -Xep:IdentityBinaryExpression:ERROR \
-                          -Xep:JUnit3TestNotRun:ERROR \
-                          -Xep:JUnit4ClassUsedInJUnit3:ERROR \
-                          -Xep:JUnitAmbiguousTestClass:ERROR \
-                          -Xep:MissingFail:ERROR \
-                          -Xep:MissingOverride:ERROR \
-                          -Xep:Overrides:ERROR \
-                          -Xep:ReferenceEquality:ERROR \
-                          -Xep:RemoveUnusedImports:ERROR \
-                          -Xep:ReturnValueIgnored:ERROR \
-                          -Xep:SelfEquals:ERROR \
-                          -Xep:SizeGreaterThanOrEqualsZero:ERROR \
-                          -Xep:TryFailThrowable:ERROR
+LOCAL_ERROR_PRONE_FLAGS += -Xep:ArrayToString:ERROR \
+                           -Xep:BoxedPrimitiveConstructor:ERROR \
+                           -Xep:ConstantField:ERROR \
+                           -Xep:EqualsIncompatibleType:ERROR \
+                           -Xep:FormatString:ERROR \
+                           -Xep:GetClassOnClass:ERROR \
+                           -Xep:IdentityBinaryExpression:ERROR \
+                           -Xep:JUnit3TestNotRun:ERROR \
+                           -Xep:JUnit4ClassUsedInJUnit3:ERROR \
+                           -Xep:JUnitAmbiguousTestClass:ERROR \
+                           -Xep:MissingFail:ERROR \
+                           -Xep:MissingOverride:ERROR \
+                           -Xep:Overrides:ERROR \
+                           -Xep:ReferenceEquality:ERROR \
+                           -Xep:RemoveUnusedImports:ERROR \
+                           -Xep:ReturnValueIgnored:ERROR \
+                           -Xep:SelfEquals:ERROR \
+                           -Xep:SizeGreaterThanOrEqualsZero:ERROR \
+                           -Xep:TryFailThrowable:ERROR \
 
diff --git a/error_prone_rules_tests.mk b/error_prone_rules_tests.mk
index a8d88b0..92c8966 100644
--- a/error_prone_rules_tests.mk
+++ b/error_prone_rules_tests.mk
@@ -15,16 +15,16 @@
 # Set of error prone rules to ensure code quality of tests
 
 # Goal is to eventually merge with error_prone_rules.mk
-LOCAL_ERROR_PRONE_FLAGS:= -Xep:ArrayToString:ERROR \
-                          -Xep:CollectionIncompatibleType:ERROR \
-                          -Xep:EqualsIncompatibleType:ERROR \
-                          -Xep:EqualsNaN:ERROR \
-                          -Xep:FormatString:ERROR \
-                          -Xep:IdentityBinaryExpression:ERROR \
-                          -Xep:JUnit3TestNotRun:ERROR \
-                          -Xep:JUnit4ClassUsedInJUnit3:ERROR \
-                          -Xep:JUnitAmbiguousTestClass:ERROR \
-                          -Xep:MissingFail:ERROR \
-                          -Xep:SizeGreaterThanOrEqualsZero:ERROR \
-                          -Xep:TryFailThrowable:ERROR
+LOCAL_ERROR_PRONE_FLAGS += -Xep:ArrayToString:ERROR \
+                           -Xep:CollectionIncompatibleType:ERROR \
+                           -Xep:EqualsIncompatibleType:ERROR \
+                           -Xep:EqualsNaN:ERROR \
+                           -Xep:FormatString:ERROR \
+                           -Xep:IdentityBinaryExpression:ERROR \
+                           -Xep:JUnit3TestNotRun:ERROR \
+                           -Xep:JUnit4ClassUsedInJUnit3:ERROR \
+                           -Xep:JUnitAmbiguousTestClass:ERROR \
+                           -Xep:MissingFail:ERROR \
+                           -Xep:SizeGreaterThanOrEqualsZero:ERROR \
+                           -Xep:TryFailThrowable:ERROR \
 
diff --git a/hostsidetests/appsecurity/test-apps/DocumentClient/src/com/android/cts/documentclient/DocumentsClientTestCase.java b/hostsidetests/appsecurity/test-apps/DocumentClient/src/com/android/cts/documentclient/DocumentsClientTestCase.java
index 7038685..d2eea34 100644
--- a/hostsidetests/appsecurity/test-apps/DocumentClient/src/com/android/cts/documentclient/DocumentsClientTestCase.java
+++ b/hostsidetests/appsecurity/test-apps/DocumentClient/src/com/android/cts/documentclient/DocumentsClientTestCase.java
@@ -152,6 +152,11 @@
         return true;
     }
 
+    protected boolean isTelevision() {
+        final PackageManager pm = getInstrumentation().getContext().getPackageManager();
+        return pm.hasSystemFeature("android.hardware.type.television");
+    }
+
     protected void assertActivityFailed() {
         final Result result = mActivity.getResult();
         assertEquals(REQUEST_CODE, result.requestCode);
diff --git a/hostsidetests/appsecurity/test-apps/DocumentClient/src/com/android/cts/documentclient/ScopedDirectoryAccessClientTest.java b/hostsidetests/appsecurity/test-apps/DocumentClient/src/com/android/cts/documentclient/ScopedDirectoryAccessClientTest.java
index 466dabf..dc44bafb 100644
--- a/hostsidetests/appsecurity/test-apps/DocumentClient/src/com/android/cts/documentclient/ScopedDirectoryAccessClientTest.java
+++ b/hostsidetests/appsecurity/test-apps/DocumentClient/src/com/android/cts/documentclient/ScopedDirectoryAccessClientTest.java
@@ -32,6 +32,7 @@
 import android.content.ContentResolver;
 import android.content.Context;
 import android.content.Intent;
+import android.content.pm.PackageManager;
 import android.net.Uri;
 import android.os.storage.StorageManager;
 import android.os.storage.StorageVolume;
@@ -361,8 +362,10 @@
 
         // Close app screen.
         mDevice.pressBack();
-        // Close main screen.
-        mDevice.pressBack();
+        if (!isTelevision()) {
+            // Close main screen.
+            mDevice.pressBack();
+        }
 
         // Finally, make sure it's reset by requesting it again.
         sendOpenExternalDirectoryIntent(volume, dir);
@@ -401,8 +404,10 @@
 
         // Close app screen.
         mDevice.pressBack();
-        // Close main screen.
-        mDevice.pressBack();
+        if (!isTelevision()) {
+            // Close main screen.
+            mDevice.pressBack();
+        }
 
         // Then tries again - should be denied.
         sendOpenExternalDirectoryIntent(volume, dir);
diff --git a/hostsidetests/devicepolicy/app/CorpOwnedManagedProfile/src/com/android/cts/comp/AdminReceiver.java b/hostsidetests/devicepolicy/app/CorpOwnedManagedProfile/src/com/android/cts/comp/AdminReceiver.java
index bf18ebb..ef07632 100644
--- a/hostsidetests/devicepolicy/app/CorpOwnedManagedProfile/src/com/android/cts/comp/AdminReceiver.java
+++ b/hostsidetests/devicepolicy/app/CorpOwnedManagedProfile/src/com/android/cts/comp/AdminReceiver.java
@@ -37,7 +37,7 @@
         super.onProfileProvisioningComplete(context, intent);
         Log.i(TAG, "onProfileProvisioningComplete");
         // Enabled profile
-        getManager(context).setProfileEnabled(getComponentName(context));
-        getManager(context).setProfileName(getComponentName(context), "Corp owned Managed Profile");
+        getManager(context).setProfileEnabled(getWho(context));
+        getManager(context).setProfileName(getWho(context), "Corp owned Managed Profile");
     }
 }
diff --git a/hostsidetests/devicepolicy/app/DeviceAndProfileOwner/api23/Android.mk b/hostsidetests/devicepolicy/app/DeviceAndProfileOwner/api23/Android.mk
index 1599d60..35cfe5b 100644
--- a/hostsidetests/devicepolicy/app/DeviceAndProfileOwner/api23/Android.mk
+++ b/hostsidetests/devicepolicy/app/DeviceAndProfileOwner/api23/Android.mk
@@ -35,7 +35,8 @@
     compatibility-device-util \
     ctstestrunner \
     ub-uiautomator \
-    cts-security-test-support-library
+    cts-security-test-support-library \
+    truth-prebuilt
 
 LOCAL_STATIC_ANDROID_LIBRARIES := \
     androidx.legacy_legacy-support-v4
diff --git a/hostsidetests/devicepolicy/app/DeviceAndProfileOwner/api25/Android.mk b/hostsidetests/devicepolicy/app/DeviceAndProfileOwner/api25/Android.mk
index 481f821..3f797ce 100644
--- a/hostsidetests/devicepolicy/app/DeviceAndProfileOwner/api25/Android.mk
+++ b/hostsidetests/devicepolicy/app/DeviceAndProfileOwner/api25/Android.mk
@@ -35,7 +35,8 @@
     compatibility-device-util \
     ctstestrunner \
     ub-uiautomator \
-    cts-security-test-support-library
+    cts-security-test-support-library \
+    truth-prebuilt
 
 LOCAL_STATIC_ANDROID_LIBRARIES := \
     androidx.legacy_legacy-support-v4
diff --git a/hostsidetests/devicepolicy/app/DeviceAndProfileOwner/latest/Android.mk b/hostsidetests/devicepolicy/app/DeviceAndProfileOwner/latest/Android.mk
index 8c6d3fd..2c97495 100644
--- a/hostsidetests/devicepolicy/app/DeviceAndProfileOwner/latest/Android.mk
+++ b/hostsidetests/devicepolicy/app/DeviceAndProfileOwner/latest/Android.mk
@@ -35,7 +35,8 @@
     compatibility-device-util \
     ctstestrunner \
     ub-uiautomator \
-    cts-security-test-support-library
+    cts-security-test-support-library \
+    truth-prebuilt
 
 LOCAL_STATIC_ANDROID_LIBRARIES := \
     androidx.legacy_legacy-support-v4
diff --git a/hostsidetests/devicepolicy/app/DeviceAndProfileOwner/src/com/android/cts/deviceandprofileowner/AccessibilityServicesTest.java b/hostsidetests/devicepolicy/app/DeviceAndProfileOwner/src/com/android/cts/deviceandprofileowner/AccessibilityServicesTest.java
new file mode 100644
index 0000000..5647f78
--- /dev/null
+++ b/hostsidetests/devicepolicy/app/DeviceAndProfileOwner/src/com/android/cts/deviceandprofileowner/AccessibilityServicesTest.java
@@ -0,0 +1,64 @@
+/*
+ * 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.deviceandprofileowner;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import android.content.ComponentName;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+public class AccessibilityServicesTest extends BaseDeviceAdminTest {
+    private final ComponentName badAdmin = new ComponentName("com.foo.bar", ".BazQuxReceiver");
+
+    public void testPermittedAccessibilityServices() {
+        // All accessibility services are allowed.
+        mDevicePolicyManager.setPermittedAccessibilityServices(ADMIN_RECEIVER_COMPONENT, null);
+        assertThat(mDevicePolicyManager.
+                getPermittedAccessibilityServices(ADMIN_RECEIVER_COMPONENT))
+                .isNull();
+
+        // Only system accessibility services are allowed.
+        mDevicePolicyManager.setPermittedAccessibilityServices(ADMIN_RECEIVER_COMPONENT,
+                new ArrayList<>());
+        assertThat(mDevicePolicyManager.
+                getPermittedAccessibilityServices(ADMIN_RECEIVER_COMPONENT))
+                .isEmpty();
+
+        // Some random services.
+        final List<String> packages = Arrays.asList("com.google.pkg.one", "com.google.pkg.two");
+        mDevicePolicyManager.setPermittedAccessibilityServices(ADMIN_RECEIVER_COMPONENT, packages);
+        assertThat(mDevicePolicyManager.
+                getPermittedAccessibilityServices(ADMIN_RECEIVER_COMPONENT))
+                .containsExactlyElementsIn(packages);
+    }
+
+    public void testPermittedAccessibilityServicesThrowsIfWrongAdmin() {
+        try {
+            mDevicePolicyManager.setPermittedAccessibilityServices(badAdmin, null);
+            fail("setPermittedAccessibilityServices didn't throw when passed invalid admin");
+        } catch (SecurityException expected) {
+        }
+        try {
+            mDevicePolicyManager.getPermittedAccessibilityServices(badAdmin);
+            fail("getPermittedAccessibilityServices didn't throw when passed invalid admin");
+        } catch (SecurityException expected) {
+        }
+    }
+}
diff --git a/hostsidetests/devicepolicy/app/DeviceAndProfileOwner/src/com/android/cts/deviceandprofileowner/InputMethodsTest.java b/hostsidetests/devicepolicy/app/DeviceAndProfileOwner/src/com/android/cts/deviceandprofileowner/InputMethodsTest.java
new file mode 100644
index 0000000..ed5047c
--- /dev/null
+++ b/hostsidetests/devicepolicy/app/DeviceAndProfileOwner/src/com/android/cts/deviceandprofileowner/InputMethodsTest.java
@@ -0,0 +1,61 @@
+/*
+ * 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.deviceandprofileowner;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import android.content.ComponentName;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+public class InputMethodsTest extends BaseDeviceAdminTest {
+    private final ComponentName badAdmin = new ComponentName("com.foo.bar", ".BazQuxReceiver");
+
+    public void testPermittedInputMethods() {
+        // All input methods are allowed.
+        mDevicePolicyManager.setPermittedInputMethods(ADMIN_RECEIVER_COMPONENT, null);
+        assertThat(
+                mDevicePolicyManager.getPermittedInputMethods(ADMIN_RECEIVER_COMPONENT)).isNull();
+
+        // Only system input methods are allowed.
+        mDevicePolicyManager.setPermittedInputMethods(ADMIN_RECEIVER_COMPONENT, new ArrayList<>());
+        assertThat(
+                mDevicePolicyManager.getPermittedInputMethods(ADMIN_RECEIVER_COMPONENT)).isEmpty();
+
+        // Some random methods.
+        final List<String> packages = Arrays.asList("com.google.pkg.one", "com.google.pkg.two");
+        mDevicePolicyManager.setPermittedInputMethods(ADMIN_RECEIVER_COMPONENT, packages);
+        assertThat(
+                mDevicePolicyManager.getPermittedInputMethods(ADMIN_RECEIVER_COMPONENT))
+                .containsExactlyElementsIn(packages);
+    }
+
+    public void testPermittedInputMethodsThrowsIfWrongAdmin() {
+        try {
+            mDevicePolicyManager.setPermittedInputMethods(badAdmin, null);
+            fail("setPermittedInputMethods didn't throw when passed invalid admin");
+        } catch (SecurityException expected) {
+        }
+        try {
+            mDevicePolicyManager.getPermittedInputMethods(badAdmin);
+            fail("getPermittedInputMethods didn't throw when passed invalid admin");
+        } catch (SecurityException expected) {
+        }
+    }
+}
diff --git a/hostsidetests/devicepolicy/app/DeviceOwner/Android.mk b/hostsidetests/devicepolicy/app/DeviceOwner/Android.mk
index c3f6d12..c1e6579 100644
--- a/hostsidetests/devicepolicy/app/DeviceOwner/Android.mk
+++ b/hostsidetests/devicepolicy/app/DeviceOwner/Android.mk
@@ -41,7 +41,8 @@
     compatibility-device-util \
     android-support-test \
     cts-security-test-support-library \
-    testng
+    testng \
+    truth-prebuilt
 
 LOCAL_STATIC_ANDROID_LIBRARIES := \
     androidx.legacy_legacy-support-v4
diff --git a/hostsidetests/devicepolicy/app/DeviceOwner/src/com/android/cts/deviceowner/NetworkLoggingTest.java b/hostsidetests/devicepolicy/app/DeviceOwner/src/com/android/cts/deviceowner/NetworkLoggingTest.java
index e727d56..a4c8f21 100644
--- a/hostsidetests/devicepolicy/app/DeviceOwner/src/com/android/cts/deviceowner/NetworkLoggingTest.java
+++ b/hostsidetests/devicepolicy/app/DeviceOwner/src/com/android/cts/deviceowner/NetworkLoggingTest.java
@@ -15,6 +15,8 @@
  */
 package com.android.cts.deviceowner;
 
+import static com.google.common.truth.Truth.assertThat;
+
 import android.app.admin.ConnectEvent;
 import android.app.admin.DnsEvent;
 import android.app.admin.NetworkEvent;
@@ -22,8 +24,8 @@
 import android.content.Context;
 import android.content.Intent;
 import android.content.IntentFilter;
+import android.os.Parcel;
 import android.support.test.InstrumentationRegistry;
-import androidx.localbroadcastmanager.content.LocalBroadcastManager;
 import android.util.Log;
 
 import java.io.BufferedReader;
@@ -38,10 +40,13 @@
 import java.net.Socket;
 import java.net.URL;
 import java.util.ArrayList;
+import java.util.HashSet;
 import java.util.List;
 import java.util.concurrent.CountDownLatch;
 import java.util.concurrent.TimeUnit;
 
+import androidx.localbroadcastmanager.content.LocalBroadcastManager;
+
 public class NetworkLoggingTest extends BaseDeviceOwnerTest {
 
     private static final String TAG = "NetworkLoggingTest";
@@ -193,6 +198,80 @@
         verifyNetworkLogs(mNetworkEvents, eventsExpected);
     }
 
+    private void verifyDnsEvent(DnsEvent dnsEvent) {
+        // Verify that we didn't log a hostname lookup when network logging was disabled.
+        if (dnsEvent.getHostname().contains(NOT_LOGGED_URLS_LIST[0])
+                || dnsEvent.getHostname().contains(NOT_LOGGED_URLS_LIST[1])) {
+            fail("A hostname that was looked-up when network logging was disabled"
+                    + " was logged.");
+        }
+
+        // Verify that as many IP addresses were logged as were reported (max 10).
+        final List<InetAddress> ips = dnsEvent.getInetAddresses();
+        assertThat(ips.size()).isAtMost(MAX_IP_ADDRESSES_LOGGED);
+        final int expectedAddressCount = Math.min(MAX_IP_ADDRESSES_LOGGED,
+                dnsEvent.getTotalResolvedAddressCount());
+        assertThat(expectedAddressCount).isEqualTo(ips.size());
+
+        // Verify the IP addresses are valid IPv4 or IPv6 addresses.
+        for (final InetAddress ipAddress : ips) {
+            assertTrue(isIpv4OrIpv6Address(ipAddress));
+        }
+
+        //Verify writeToParcel.
+        Parcel parcel = Parcel.obtain();
+        try {
+            dnsEvent.writeToParcel(parcel, 0);
+            parcel.setDataPosition(0);
+            final DnsEvent dnsEventOut = DnsEvent.CREATOR.createFromParcel(parcel);
+            assertThat(dnsEventOut).isNotNull();
+            verifyDnsEventsEqual(dnsEvent, dnsEventOut);
+        } finally {
+            parcel.recycle();
+        }
+    }
+
+    private void verifyDnsEventsEqual(DnsEvent event1, DnsEvent event2) {
+        assertThat(event1.getHostname()).isEqualTo(event2.getHostname());
+        assertThat(new HashSet<InetAddress>(event1.getInetAddresses())).isEqualTo(
+                        new HashSet<InetAddress>(event2.getInetAddresses()));
+        assertThat(event1.getTotalResolvedAddressCount()).isEqualTo(
+                event2.getTotalResolvedAddressCount());
+        assertThat(event1.getPackageName()).isEqualTo(event2.getPackageName());
+        assertThat(event1.getTimestamp()).isEqualTo(event2.getTimestamp());
+        assertThat(event1.getId()).isEqualTo(event2.getId());
+    }
+
+    private void verifyConnectEvent(ConnectEvent connectEvent) {
+        // Verify the IP address is a valid IPv4 or IPv6 address.
+        final InetAddress ip = connectEvent.getInetAddress();
+        assertThat(isIpv4OrIpv6Address(ip)).isTrue();
+
+        // Verify that the port is a valid port.
+        assertThat(connectEvent.getPort()).isAtLeast(0);
+        assertThat(connectEvent.getPort()).isAtMost(65535);
+
+        // Verify writeToParcel.
+        Parcel parcel = Parcel.obtain();
+        try {
+            connectEvent.writeToParcel(parcel, 0);
+            parcel.setDataPosition(0);
+            final ConnectEvent connectEventOut = ConnectEvent.CREATOR.createFromParcel(parcel);
+            assertThat(connectEventOut).isNotNull();
+            verifyConnectEventsEqual(connectEvent, connectEventOut);
+        } finally {
+             parcel.recycle();
+        }
+    }
+
+    private void verifyConnectEventsEqual(ConnectEvent event1, ConnectEvent event2) {
+        assertThat(event1.getInetAddress()).isEqualTo(event2.getInetAddress());
+        assertThat(event1.getPort()).isEqualTo(event2.getPort());
+        assertThat(event1.getPackageName()).isEqualTo(event2.getPackageName());
+        assertThat(event1.getTimestamp()).isEqualTo(event2.getTimestamp());
+        assertThat(event1.getId()).isEqualTo(event2.getId());
+    }
+
     private void verifyNetworkLogs(List<NetworkEvent> networkEvents, int eventsExpected) {
         // allow a batch to be slightly smaller or larger.
         assertTrue(Math.abs(eventsExpected - networkEvents.size()) <= 50);
@@ -216,35 +295,18 @@
                 ctsPackageNameCounter++;
                 if (currentEvent instanceof DnsEvent) {
                     final DnsEvent dnsEvent = (DnsEvent) currentEvent;
-                    // verify that we didn't log a hostname lookup when network logging was disabled
-                    if (dnsEvent.getHostname().contains(NOT_LOGGED_URLS_LIST[0])
-                            || dnsEvent.getHostname().contains(NOT_LOGGED_URLS_LIST[1])) {
-                        fail("A hostname that was looked-up when network logging was disabled"
-                                + " was logged.");
-                    }
-                    // count the frequencies of LOGGED_URLS_LIST's hostnames that were looked up
+                    // Mark which addresses from LOGGED_URLS_LIST were visited.
                     for (int j = 0; j < LOGGED_URLS_LIST.length; j++) {
                         if (dnsEvent.getHostname().contains(LOGGED_URLS_LIST[j])) {
                             visited[j] = true;
                             break;
                         }
                     }
-                    // verify that as many IP addresses were logged as were reported (max 10)
-                    final List<InetAddress> ips = dnsEvent.getInetAddresses();
-                    assertTrue(ips.size() <= MAX_IP_ADDRESSES_LOGGED);
-                    final int expectedAddressCount = Math.min(MAX_IP_ADDRESSES_LOGGED,
-                            dnsEvent.getTotalResolvedAddressCount());
-                    assertEquals(expectedAddressCount, ips.size());
-                    // verify the IP addresses are valid IPv4 or IPv6 addresses
-                    for (final InetAddress ipAddress : ips) {
-                        assertTrue(isIpv4OrIpv6Address(ipAddress));
-                    }
+
+                    verifyDnsEvent(dnsEvent);
                 } else if (currentEvent instanceof ConnectEvent) {
                     final ConnectEvent connectEvent = (ConnectEvent) currentEvent;
-                    // verify the IP address is a valid IPv4 or IPv6 address
-                    assertTrue(isIpv4OrIpv6Address(connectEvent.getInetAddress()));
-                    // verify that the port is a valid port
-                    assertTrue(connectEvent.getPort() >= 0 && connectEvent.getPort() <= 65535);
+                    verifyConnectEvent(connectEvent);
                 } else {
                     fail("An unknown NetworkEvent type logged: "
                             + currentEvent.getClass().getName());
diff --git a/hostsidetests/devicepolicy/app/DeviceOwner/src/com/android/cts/deviceowner/SystemUpdatePolicyTest.java b/hostsidetests/devicepolicy/app/DeviceOwner/src/com/android/cts/deviceowner/SystemUpdatePolicyTest.java
index 4fa6235..1b9739a 100644
--- a/hostsidetests/devicepolicy/app/DeviceOwner/src/com/android/cts/deviceowner/SystemUpdatePolicyTest.java
+++ b/hostsidetests/devicepolicy/app/DeviceOwner/src/com/android/cts/deviceowner/SystemUpdatePolicyTest.java
@@ -16,6 +16,8 @@
 package com.android.cts.deviceowner;
 
 
+import static com.google.common.truth.Truth.assertThat;
+
 import android.app.admin.DevicePolicyManager;
 import android.app.admin.FreezePeriod;
 import android.app.admin.SystemUpdatePolicy;
@@ -25,14 +27,15 @@
 import android.content.Intent;
 import android.content.IntentFilter;
 import android.icu.util.Calendar;
+import android.os.Parcel;
 import android.provider.Settings;
 import android.provider.Settings.Global;
-import android.util.Pair;
 
 import java.time.LocalDate;
 import java.time.MonthDay;
 import java.util.ArrayList;
 import java.util.List;
+import java.util.Objects;
 import java.util.concurrent.Semaphore;
 import java.util.concurrent.TimeUnit;
 
@@ -235,6 +238,89 @@
         }
     }
 
+    public void testWriteSystemUpdatePolicyToParcel() {
+        final Parcel parcel1 = Parcel.obtain();
+        try {
+            final SystemUpdatePolicy policy1 = SystemUpdatePolicy.createAutomaticInstallPolicy();
+            policy1.writeToParcel(parcel1, 0);
+            parcel1.setDataPosition(0);
+            final SystemUpdatePolicy copy1 = SystemUpdatePolicy.CREATOR.createFromParcel(parcel1);
+            assertThat(copy1).isNotNull();
+            assertSystemUpdatePoliciesEqual(policy1, copy1);
+        } finally {
+            parcel1.recycle();
+        }
+
+        final Parcel parcel2 = Parcel.obtain();
+        try {
+            final SystemUpdatePolicy policy2 = SystemUpdatePolicy
+                .createWindowedInstallPolicy(0, 720);
+            policy2.writeToParcel(parcel2, 0);
+            parcel2.setDataPosition(0);
+            final SystemUpdatePolicy copy2 = SystemUpdatePolicy.CREATOR.createFromParcel(parcel2);
+            assertThat(copy2).isNotNull();
+            assertSystemUpdatePoliciesEqual(policy2, copy2);
+        } finally {
+            parcel2.recycle();
+        }
+
+        final Parcel parcel3 = Parcel.obtain();
+        try {
+            final SystemUpdatePolicy policy3 = SystemUpdatePolicy.createPostponeInstallPolicy();
+            policy3.writeToParcel(parcel3, 0);
+            parcel3.setDataPosition(0);
+            final SystemUpdatePolicy copy3 = SystemUpdatePolicy.CREATOR.createFromParcel(parcel3);
+            assertThat(copy3).isNotNull();
+            assertSystemUpdatePoliciesEqual(policy3, copy3);
+        } finally {
+            parcel3.recycle();
+        }
+    }
+
+    private void assertSystemUpdatePoliciesEqual(SystemUpdatePolicy policy,
+            SystemUpdatePolicy copy) {
+        assertThat(policy.getInstallWindowStart()).isEqualTo(copy.getInstallWindowStart());
+        assertThat(policy.getInstallWindowEnd()).isEqualTo(copy.getInstallWindowEnd());
+        assertFreezePeriodListsEqual(policy.getFreezePeriods(), copy.getFreezePeriods());
+        assertThat(policy.getPolicyType()).isEqualTo(copy.getPolicyType());
+    }
+
+    private void assertFreezePeriodListsEqual(List<FreezePeriod> original,
+            List<FreezePeriod> copy) {
+        assertThat(original).isNotNull();
+        assertThat(copy).isNotNull();
+        assertThat(original.size()).isEqualTo(copy.size());
+        for (FreezePeriod period1 : original) {
+            assertThat(period1).isNotNull();
+            assertFreezePeriodListContains(copy, period1);
+        }
+        for (FreezePeriod period1 : copy) {
+            assertThat(period1).isNotNull();
+            assertFreezePeriodListContains(original, period1);
+        }
+    }
+
+    private void assertFreezePeriodListContains(List<FreezePeriod> list, FreezePeriod period) {
+        for (FreezePeriod other : list) {
+            assertThat(other).isNotNull();
+            if (areFreezePeriodsEqual(period, other)) {
+                return;
+            }
+        }
+        final List<String> printablePeriods = new ArrayList<>();
+        for (FreezePeriod printablePeriod : list) {
+            printablePeriods.add(printablePeriod.toString());
+        }
+        fail(String.format("FreezePeriod list [%s] does not contain the specified period %s.",
+            String.join(", ", printablePeriods), period));
+    }
+
+    private boolean areFreezePeriodsEqual(FreezePeriod period1, FreezePeriod period2) {
+        return period1 != null && period2 != null
+            && Objects.equals(period1.getStart(), period2.getStart())
+            && Objects.equals(period1.getEnd(), period2.getEnd());
+    }
+
     private void testPolicy(SystemUpdatePolicy policy) {
         mDevicePolicyManager.setSystemUpdatePolicy(getWho(), policy);
         waitForPolicyChangedBroadcast();
diff --git a/hostsidetests/devicepolicy/app/ManagedProfile/AndroidManifest.xml b/hostsidetests/devicepolicy/app/ManagedProfile/AndroidManifest.xml
index 3cb0bce..58e232b 100644
--- a/hostsidetests/devicepolicy/app/ManagedProfile/AndroidManifest.xml
+++ b/hostsidetests/devicepolicy/app/ManagedProfile/AndroidManifest.xml
@@ -191,6 +191,13 @@
           </intent-filter>
         </receiver>
 
+        <receiver android:name=".WipeDataReceiver">
+            <intent-filter>
+                <action android:name="com.android.cts.managedprofile.WIPE_DATA" />
+                <action android:name="com.android.cts.managedprofile.WIPE_DATA_WITH_REASON" />
+            </intent-filter>
+        </receiver>
+
     </application>
 
     <instrumentation android:name="android.support.test.runner.AndroidJUnitRunner"
diff --git a/hostsidetests/devicepolicy/app/ManagedProfile/src/com/android/cts/managedprofile/WipeDataReceiver.java b/hostsidetests/devicepolicy/app/ManagedProfile/src/com/android/cts/managedprofile/WipeDataReceiver.java
new file mode 100644
index 0000000..0abea7d
--- /dev/null
+++ b/hostsidetests/devicepolicy/app/ManagedProfile/src/com/android/cts/managedprofile/WipeDataReceiver.java
@@ -0,0 +1,46 @@
+/*
+ * 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.managedprofile;
+
+import android.app.admin.DevicePolicyManager;
+import android.content.BroadcastReceiver;
+import android.content.Context;
+import android.content.Intent;
+
+/**
+ * Invoke wipeData(), optionally including a reason. This is used by host side tests to destroy the
+ * work profile. The call is triggered via a broadcast instead of run as a normal test case, since
+ * the test process will be killed after calling wipeData() which will result in a test failure if
+ * this were run as a test case.
+ */
+public class WipeDataReceiver extends BroadcastReceiver {
+
+    private static final String ACTION_WIPE_DATA = "com.android.cts.managedprofile.WIPE_DATA";
+    private static final String ACTION_WIPE_DATA_WITH_REASON =
+            "com.android.cts.managedprofile.WIPE_DATA_WITH_REASON";
+    private static final String TEST_WIPE_DATA_REASON = "cts test for WipeDataWithReason";
+
+    @Override
+    public void onReceive(Context context, Intent intent) {
+        final DevicePolicyManager dpm = context.getSystemService(DevicePolicyManager.class);
+        if (ACTION_WIPE_DATA.equals(intent.getAction())) {
+            dpm.wipeData(0);
+        } else if (ACTION_WIPE_DATA_WITH_REASON.equals(intent.getAction())) {
+            dpm.wipeData(0, TEST_WIPE_DATA_REASON);
+        }
+    }
+}
diff --git a/hostsidetests/devicepolicy/app/TransferOwnerIncomingApp/AndroidManifest.xml b/hostsidetests/devicepolicy/app/TransferOwnerIncomingApp/AndroidManifest.xml
index b721292..06ebcbc 100644
--- a/hostsidetests/devicepolicy/app/TransferOwnerIncomingApp/AndroidManifest.xml
+++ b/hostsidetests/devicepolicy/app/TransferOwnerIncomingApp/AndroidManifest.xml
@@ -43,6 +43,15 @@
                 <action android:name="android.app.action.DEVICE_ADMIN_ENABLED"/>
             </intent-filter>
         </receiver>
+
+        <service
+            android:name="com.android.cts.transferowner.DeviceAndProfileOwnerTransferIncomingTest$BasicAdminService"
+            android:exported="true"
+            android:permission="android.permission.BIND_DEVICE_ADMIN">
+            <intent-filter>
+                <action android:name="android.app.action.DEVICE_ADMIN_SERVICE" />
+            </intent-filter>
+        </service>
     </application>
 
     <instrumentation android:name="android.support.test.runner.AndroidJUnitRunner"
diff --git a/hostsidetests/devicepolicy/app/TransferOwnerIncomingApp/src/com/android/cts/transferowner/DeviceAndProfileOwnerTransferIncomingTest.java b/hostsidetests/devicepolicy/app/TransferOwnerIncomingApp/src/com/android/cts/transferowner/DeviceAndProfileOwnerTransferIncomingTest.java
index 7a598d9..5d255e0e 100644
--- a/hostsidetests/devicepolicy/app/TransferOwnerIncomingApp/src/com/android/cts/transferowner/DeviceAndProfileOwnerTransferIncomingTest.java
+++ b/hostsidetests/devicepolicy/app/TransferOwnerIncomingApp/src/com/android/cts/transferowner/DeviceAndProfileOwnerTransferIncomingTest.java
@@ -19,11 +19,14 @@
 import static junit.framework.Assert.assertNotNull;
 import static junit.framework.Assert.assertTrue;
 
+import android.app.Service;
 import android.app.admin.DeviceAdminReceiver;
 import android.app.admin.DevicePolicyManager;
 import android.content.ComponentName;
 import android.content.Context;
+import android.content.Intent;
 import android.content.SharedPreferences;
+import android.os.IBinder;
 import android.os.PersistableBundle;
 import android.support.test.InstrumentationRegistry;
 import android.support.test.filters.SmallTest;
@@ -44,12 +47,27 @@
         }
     }
 
+    public static class BasicAdminService extends Service {
+        @Override
+        public void onCreate() {
+            super.onCreate();
+            putBooleanPref(getApplicationContext(), KEY_TRANSFER_ADMIN_SERVICE_BOUND, true);
+        }
+
+        @Override
+        public IBinder onBind(Intent intent) {
+            return null;
+        }
+    }
+
     public static class BasicAdminReceiverNoMetadata extends DeviceAdminReceiver {
         public BasicAdminReceiverNoMetadata() {}
     }
 
     private final static String SHARED_PREFERENCE_NAME = "shared-preference-name";
     private final static String KEY_TRANSFER_COMPLETED_CALLED = "key-transfer-completed-called";
+    private final static String KEY_TRANSFER_ADMIN_SERVICE_BOUND =
+        "key-transfer-admin-service-bound";
     private final static String ARE_PARAMETERS_SAVED = "ARE_PARAMETERS_SAVED";
 
     protected Context mContext;
@@ -97,6 +115,11 @@
         assertTrue(bundle.isEmpty());
     }
 
+    @Test
+    public void testAdminServiceIsBound() {
+        assertTrue(getBooleanPref(mContext, KEY_TRANSFER_ADMIN_SERVICE_BOUND));
+    }
+
     private static SharedPreferences getPrefs(Context context) {
         return context.getSharedPreferences(SHARED_PREFERENCE_NAME, Context.MODE_PRIVATE);
     }
diff --git a/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/DeviceAndProfileOwnerHostSideTransferTest.java b/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/DeviceAndProfileOwnerHostSideTransferTest.java
index a18c772..997b831 100644
--- a/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/DeviceAndProfileOwnerHostSideTransferTest.java
+++ b/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/DeviceAndProfileOwnerHostSideTransferTest.java
@@ -3,6 +3,7 @@
 import com.android.tradefed.device.DeviceNotAvailableException;
 
 public abstract class DeviceAndProfileOwnerHostSideTransferTest extends BaseDevicePolicyTest {
+
     protected static final String TRANSFER_OWNER_OUTGOING_PKG =
             "com.android.cts.transferowneroutgoing";
     protected static final String TRANSFER_OWNER_OUTGOING_APK = "CtsTransferOwnerOutgoingApp.apk";
@@ -14,6 +15,10 @@
             "com.android.cts.transferownerincoming";
     protected static final String TRANSFER_OWNER_INCOMING_APK = "CtsTransferOwnerIncomingApp.apk";
     protected static final String INVALID_TARGET_APK = "CtsIntentReceiverApp.apk";
+    protected static final String TRANSFER_PROFILE_OWNER_OUTGOING_TEST =
+        "com.android.cts.transferowner.TransferProfileOwnerOutgoingTest";
+    protected static final String TRANSFER_PROFILE_OWNER_INCOMING_TEST =
+        "com.android.cts.transferowner.TransferProfileOwnerIncomingTest";
 
     protected int mUserId;
     protected String mOutgoingTestClassName;
@@ -191,9 +196,40 @@
                 mPrimaryUserId);
     }
 
+    public void testTargetDeviceAdminServiceBound() throws Exception {
+        if (!mHasFeature) {
+            return;
+        }
+        runDeviceTestsAsUser(TRANSFER_OWNER_OUTGOING_PKG,
+            mOutgoingTestClassName,
+            "testTransferOwnership", mUserId);
+        runDeviceTestsAsUser(TRANSFER_OWNER_INCOMING_PKG,
+            mIncomingTestClassName,
+            "testAdminServiceIsBound", mUserId);
+    }
+
+    protected void setSameAffiliationId(int profileUserId, String testClassName)
+        throws Exception {
+        runDeviceTestsAsUser(TRANSFER_OWNER_OUTGOING_PKG,
+            testClassName,
+            "testSetAffiliationId1", mPrimaryUserId);
+        runDeviceTestsAsUser(TRANSFER_OWNER_OUTGOING_PKG,
+            testClassName,
+            "testSetAffiliationId1", profileUserId);
+    }
+
+    protected void assertAffiliationIdsAreIntact(int profileUserId,
+        String testClassName) throws Exception {
+        runDeviceTestsAsUser(TRANSFER_OWNER_INCOMING_PKG,
+            testClassName,
+            "testIsAffiliationId1", mPrimaryUserId);
+        runDeviceTestsAsUser(TRANSFER_OWNER_INCOMING_PKG,
+            testClassName,
+            "testIsAffiliationId1", profileUserId);
+    }
+
     /* TODO: Add tests for:
-    * 1. startServiceForOwner
-    * 2. passwordOwner
+    * 1. passwordOwner
     *
     * */
 }
diff --git a/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/DeviceAndProfileOwnerTest.java b/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/DeviceAndProfileOwnerTest.java
index fbe75d2..c2f8ada 100644
--- a/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/DeviceAndProfileOwnerTest.java
+++ b/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/DeviceAndProfileOwnerTest.java
@@ -28,7 +28,6 @@
 import java.util.Arrays;
 import java.util.Collections;
 import java.util.List;
-import java.util.Map;
 
 /**
  * Set of tests for use cases that apply to profile and device owner.
@@ -915,6 +914,22 @@
         }
     }
 
+    public void testPermittedAccessibilityServices() throws Exception {
+        if (!mHasFeature) {
+            return;
+        }
+
+        executeDeviceTestClass(".AccessibilityServicesTest");
+    }
+
+    public void testPermittedInputMethods() throws Exception {
+        if (!mHasFeature) {
+            return;
+        }
+
+        executeDeviceTestClass(".InputMethodsTest");
+    }
+
     /**
      * 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/DevicePlusProfileOwnerHostSideTransferTest.java b/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/DevicePlusProfileOwnerHostSideTransferTest.java
new file mode 100644
index 0000000..960fbb2
--- /dev/null
+++ b/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/DevicePlusProfileOwnerHostSideTransferTest.java
@@ -0,0 +1,45 @@
+package com.android.cts.devicepolicy;
+
+import android.util.Log;
+
+/**
+ * Tests the DPC transfer functionality for COMP mode - managed profile on top of a device owner.
+ * Testing is done by having two dummy DPCs, CtsTransferOwnerOutgoingApp and
+ * CtsTransferOwnerIncomingApp. The former is the current DPC and the latter will be the new DPC
+ * after transfer. In order to run the tests from the correct process, first we setup some
+ * policies in the client side in CtsTransferOwnerOutgoingApp and then we verify the policies are
+ * still there in CtsTransferOwnerIncomingApp. Note that these tests are run on the profile owner
+ * user.
+ */
+public class DevicePlusProfileOwnerHostSideTransferTest
+    extends DeviceAndProfileOwnerHostSideTransferTest {
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+        // We need managed users to be supported in order to create a profile of the user owner.
+        mHasFeature &= hasDeviceFeature("android.software.managed_users");
+        if (mHasFeature) {
+            installAppAsUser(TRANSFER_OWNER_OUTGOING_APK, mPrimaryUserId);
+            // First set up the device owner.
+            if (setDeviceOwner(TRANSFER_OWNER_OUTGOING_TEST_RECEIVER, mPrimaryUserId,
+                false)) {
+                mOutgoingTestClassName = TRANSFER_PROFILE_OWNER_OUTGOING_TEST;
+                mIncomingTestClassName = TRANSFER_PROFILE_OWNER_INCOMING_TEST;
+
+                // And then set up the managed profile on top of it.
+                final int profileUserId = setupManagedProfileOnDeviceOwner(
+                    TRANSFER_OWNER_OUTGOING_APK, TRANSFER_OWNER_OUTGOING_TEST_RECEIVER);
+                setSameAffiliationId(profileUserId, TRANSFER_PROFILE_OWNER_OUTGOING_TEST);
+
+                installAppAsUser(TRANSFER_OWNER_INCOMING_APK, mPrimaryUserId);
+                installAppAsUser(TRANSFER_OWNER_INCOMING_APK, profileUserId);
+                mUserId = profileUserId;
+            } else {
+                removeAdmin(TRANSFER_OWNER_OUTGOING_TEST_RECEIVER, mUserId);
+                getDevice().uninstallPackage(TRANSFER_OWNER_OUTGOING_PKG);
+                fail("Failed to set device owner");
+            }
+        }
+    }
+}
diff --git a/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/ManagedProfileTest.java b/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/ManagedProfileTest.java
index 1548d7f..c111b35 100644
--- a/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/ManagedProfileTest.java
+++ b/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/ManagedProfileTest.java
@@ -160,11 +160,7 @@
             return;
         }
         assertTrue(listUsers().contains(mProfileUserId));
-        runDeviceTestsAsUser(
-                MANAGED_PROFILE_PKG,
-                ".WipeDataTest",
-                "testWipeDataWithReason",
-                mProfileUserId);
+        sendWipeProfileBroadcast("com.android.cts.managedprofile.WIPE_DATA_WITH_REASON");
         // Note: the managed profile is removed by this test, which will make removeUserCommand in
         // tearDown() to complain, but that should be OK since its result is not asserted.
         assertUserGetsRemoved(mProfileUserId);
@@ -186,14 +182,19 @@
             return;
         }
         assertTrue(listUsers().contains(mProfileUserId));
-        runDeviceTestsAsUser(
-                MANAGED_PROFILE_PKG, ".WipeDataTest",
-                "testWipeData", mProfileUserId);
+        sendWipeProfileBroadcast("com.android.cts.managedprofile.WIPE_DATA");
         // Note: the managed profile is removed by this test, which will make removeUserCommand in
         // tearDown() to complain, but that should be OK since its result is not asserted.
         assertUserGetsRemoved(mProfileUserId);
     }
 
+    private void sendWipeProfileBroadcast(String action) throws Exception {
+        final String cmd = "am broadcast --receiver-foreground --user " + mProfileUserId
+            + " -a " + action
+            + " com.android.cts.managedprofile/.WipeDataReceiver";
+        getDevice().executeShellCommand(cmd);
+    }
+
     public void testLockNowWithKeyEviction() throws Exception {
         if (!mHasFeature || !mSupportsFbe) {
             return;
diff --git a/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/MixedDeviceOwnerHostSideTransferTest.java b/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/MixedDeviceOwnerHostSideTransferTest.java
index 7aefc33..fa0e60b 100644
--- a/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/MixedDeviceOwnerHostSideTransferTest.java
+++ b/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/MixedDeviceOwnerHostSideTransferTest.java
@@ -100,24 +100,4 @@
                 "testTransferAffiliatedProfileOwnershipCompleteCallbackIsCalled",
                 mUserId);
     }
-
-    private void assertAffiliationIdsAreIntact(int profileUserId,
-            String testClassName) throws Exception {
-        runDeviceTestsAsUser(TRANSFER_OWNER_INCOMING_PKG,
-                testClassName,
-                "testIsAffiliationId1", mPrimaryUserId);
-        runDeviceTestsAsUser(TRANSFER_OWNER_INCOMING_PKG,
-                testClassName,
-                "testIsAffiliationId1", profileUserId);
-    }
-
-    private void setSameAffiliationId(int profileUserId, String testClassName)
-            throws Exception {
-        runDeviceTestsAsUser(TRANSFER_OWNER_OUTGOING_PKG,
-                testClassName,
-                "testSetAffiliationId1", mPrimaryUserId);
-        runDeviceTestsAsUser(TRANSFER_OWNER_OUTGOING_PKG,
-                testClassName,
-                "testSetAffiliationId1", profileUserId);
-    }
 }
diff --git a/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/MixedDeviceOwnerTest.java b/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/MixedDeviceOwnerTest.java
index 01e55fe..5317ecb 100644
--- a/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/MixedDeviceOwnerTest.java
+++ b/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/MixedDeviceOwnerTest.java
@@ -16,14 +16,6 @@
 
 package com.android.cts.devicepolicy;
 
-import android.platform.test.annotations.RequiresDevice;
-
-import com.android.ddmlib.Log.LogLevel;
-import com.android.tradefed.device.DeviceNotAvailableException;
-import com.android.tradefed.log.LogUtil.CLog;
-
-import junit.framework.AssertionFailedError;
-
 /**
  * Set of tests for device owner use cases that also apply to profile owners.
  * Tests that should be run identically in both cases are added in DeviceAndProfileOwnerTest.
diff --git a/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/MixedManagedProfileOwnerTest.java b/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/MixedManagedProfileOwnerTest.java
index b39e1ad..ba30f25 100644
--- a/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/MixedManagedProfileOwnerTest.java
+++ b/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/MixedManagedProfileOwnerTest.java
@@ -22,7 +22,7 @@
  */
 public class MixedManagedProfileOwnerTest extends DeviceAndProfileOwnerTest {
 
-    protected static final String CLEAR_PROFILE_OWNER_NEGATIVE_TEST_CLASS =
+    private static final String CLEAR_PROFILE_OWNER_NEGATIVE_TEST_CLASS =
             DEVICE_ADMIN_PKG + ".ClearProfileOwnerNegativeTest";
 
     private int mParentUserId = -1;
@@ -170,4 +170,11 @@
     public void testSetSystemSetting() {
         // Managed profile owner cannot set currently whitelisted system settings.
     }
+
+    public void testCannotClearProfileOwner() throws Exception {
+        if (!mHasFeature) {
+            return;
+        }
+        runDeviceTestsAsUser(DEVICE_ADMIN_PKG, CLEAR_PROFILE_OWNER_NEGATIVE_TEST_CLASS, mUserId);
+    }
 }
diff --git a/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/MixedProfileOwnerHostSideTransferTest.java b/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/MixedProfileOwnerHostSideTransferTest.java
index 5143fb1..ca081fc 100644
--- a/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/MixedProfileOwnerHostSideTransferTest.java
+++ b/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/MixedProfileOwnerHostSideTransferTest.java
@@ -24,10 +24,6 @@
  */
 public class MixedProfileOwnerHostSideTransferTest extends
         DeviceAndProfileOwnerHostSideTransferTest {
-    private static final String TRANSFER_PROFILE_OWNER_OUTGOING_TEST =
-            "com.android.cts.transferowner.TransferProfileOwnerOutgoingTest";
-    private static final String TRANSFER_PROFILE_OWNER_INCOMING_TEST =
-            "com.android.cts.transferowner.TransferProfileOwnerIncomingTest";
 
     @Override
     protected void setUp() throws Exception {
diff --git a/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/MixedProfileOwnerTest.java b/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/MixedProfileOwnerTest.java
index 803cf36..e1d50bd 100644
--- a/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/MixedProfileOwnerTest.java
+++ b/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/MixedProfileOwnerTest.java
@@ -16,8 +16,6 @@
 
 package com.android.cts.devicepolicy;
 
-import android.platform.test.annotations.RequiresDevice;
-
 /**
  * Set of tests for pure (non-managed) profile owner use cases that also apply to device owners.
  * Tests that should be run identically in both cases are added in DeviceAndProfileOwnerTest.
diff --git a/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/MixedProfileOwnerTestApi25.java b/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/MixedProfileOwnerTestApi25.java
index b044441..0dcb82a 100644
--- a/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/MixedProfileOwnerTestApi25.java
+++ b/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/MixedProfileOwnerTestApi25.java
@@ -16,8 +16,6 @@
 
 package com.android.cts.devicepolicy;
 
-import android.platform.test.annotations.RequiresDevice;
-
 /**
  * Set of tests for pure (non-managed) profile owner use cases that also apply to device owners.
  * Tests that should be run identically in both cases are added in DeviceAndProfileOwnerTestApi25.
diff --git a/hostsidetests/incident/src/com/android/server/cts/FingerprintIncidentTest.java b/hostsidetests/incident/src/com/android/server/cts/FingerprintIncidentTest.java
index 7f77466..05699c7 100644
--- a/hostsidetests/incident/src/com/android/server/cts/FingerprintIncidentTest.java
+++ b/hostsidetests/incident/src/com/android/server/cts/FingerprintIncidentTest.java
@@ -16,9 +16,9 @@
 
 package com.android.server.cts;
 
-import com.android.server.fingerprint.FingerprintServiceDumpProto;
-import com.android.server.fingerprint.FingerprintUserStatsProto;
-import com.android.server.fingerprint.PerformanceStatsProto;
+import com.android.server.biometrics.fingerprint.FingerprintServiceDumpProto;
+import com.android.server.biometrics.fingerprint.FingerprintUserStatsProto;
+import com.android.server.biometrics.fingerprint.PerformanceStatsProto;
 
 import com.android.tradefed.device.DeviceNotAvailableException;
 import com.android.tradefed.device.ITestDevice;
diff --git a/hostsidetests/security/AndroidTest.xml b/hostsidetests/security/AndroidTest.xml
index 78aa311..6645dd5 100755
--- a/hostsidetests/security/AndroidTest.xml
+++ b/hostsidetests/security/AndroidTest.xml
@@ -49,6 +49,11 @@
         <!-- Please add tests solely from this bulletin below to avoid merge conflict -->
         <option name="push" value="CVE-2016-2460->/data/local/tmp/CVE-2016-2460" />
 
+        <!--__________________-->
+        <!-- Bulletin 2016-07 -->
+        <!-- Please add tests solely from this bulletin below to avoid merge conflict -->
+        <option name="push" value="CVE-2016-3818->/data/local/tmp/CVE-2016-3818" />
+
         <!-- Bulletin 2016-09 -->
         <!-- Please add tests solely from this bulletin below to avoid merge conflict -->
         <option name="push" value="CVE-2016-2471->/data/local/tmp/CVE-2016-2471" />
diff --git a/hostsidetests/security/securityPatch/CVE-2016-3818/Android.mk b/hostsidetests/security/securityPatch/CVE-2016-3818/Android.mk
new file mode 100755
index 0000000..0fe16b7
--- /dev/null
+++ b/hostsidetests/security/securityPatch/CVE-2016-3818/Android.mk
@@ -0,0 +1,32 @@
+# Copyright (C) 2018 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+LOCAL_PATH := $(call my-dir)
+
+include $(CLEAR_VARS)
+LOCAL_MODULE := CVE-2016-3818
+LOCAL_SRC_FILES := poc.c
+LOCAL_MULTILIB := both
+LOCAL_MODULE_STEM_32 := $(LOCAL_MODULE)32
+LOCAL_MODULE_STEM_64 := $(LOCAL_MODULE)64
+
+# Tag this module as a cts test artifact
+LOCAL_COMPATIBILITY_SUITE := cts vts sts
+LOCAL_CTS_TEST_PACKAGE := android.security.cts
+
+LOCAL_ARM_MODE := arm
+LOCAL_CFLAGS += -Wall -Werror
+LOCAL_LDFLAGS += -fPIE -pie
+LOCAL_LDFLAGS += -rdynamic
+include $(BUILD_CTS_EXECUTABLE)
diff --git a/hostsidetests/security/securityPatch/CVE-2016-3818/poc.c b/hostsidetests/security/securityPatch/CVE-2016-3818/poc.c
new file mode 100644
index 0000000..4a204fc
--- /dev/null
+++ b/hostsidetests/security/securityPatch/CVE-2016-3818/poc.c
@@ -0,0 +1,55 @@
+/**
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#define _GNU_SOURCE
+#include <sys/types.h>
+#include <sys/wait.h>
+
+#include <errno.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <sys/resource.h>
+#include <sys/time.h>
+#include <unistd.h>
+
+int main(void) {
+  struct rlimit rlim;
+  size_t i;
+
+  int result = getrlimit(RLIMIT_AS, &rlim);
+  printf("%lu\n", rlim.rlim_cur);
+  printf("%lu\n", rlim.rlim_max);
+
+  rlim.rlim_cur = 384 * 1024 * 1024;
+  result = setrlimit(RLIMIT_AS, &rlim);
+
+  /*
+   * Issue exists only in kitkat. It passes in
+   * android M onwards. In failure scenario, device reboots.
+   */
+  size_t to_alloc = 1.6 * 1024 * 1024 * 1024;
+  char *mem = (char *)malloc(to_alloc);
+
+  printf("%p\n", mem);
+  if (mem) {
+    for (i = 0; i < to_alloc; i++) {
+      mem[i] = 0;
+    }
+    printf("filled\n");
+  }
+
+  free(mem);
+  return 0;
+}
diff --git a/hostsidetests/security/src/android/security/cts/Poc16_07.java b/hostsidetests/security/src/android/security/cts/Poc16_07.java
new file mode 100644
index 0000000..2601d43
--- /dev/null
+++ b/hostsidetests/security/src/android/security/cts/Poc16_07.java
@@ -0,0 +1,29 @@
+/**
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package android.security.cts;
+
+import android.platform.test.annotations.SecurityTest;
+
+@SecurityTest
+public class Poc16_07 extends SecurityTestCase {
+    /**
+     *  b/28740702
+     */
+    @SecurityTest
+    public void testPocCVE_2016_3818() throws Exception {
+        AdbUtils.runPoc("CVE-2016-3818", getDevice(), 60);
+    }
+}
diff --git a/hostsidetests/theme/src/android/theme/cts/ComparisonTask.java b/hostsidetests/theme/src/android/theme/cts/ComparisonTask.java
index 371e1a9..6344143 100755
--- a/hostsidetests/theme/src/android/theme/cts/ComparisonTask.java
+++ b/hostsidetests/theme/src/android/theme/cts/ComparisonTask.java
@@ -41,7 +41,7 @@
     private static final int GRAY = 0xFF808080;
 
     /** Maximum allowable number of consecutive failed pixels. */
-    private static final int MAX_CONSECUTIVE_FAILURES = 1;
+    private static final int MAX_CONSECUTIVE_FAILURES = 2;
 
     private final String mName;
     private final File mExpected;
@@ -87,6 +87,35 @@
         return (color & 0xFF000000) >>> 24;
     }
 
+    private static boolean checkNeighbors(int x, int y, BufferedImage reference,
+            BufferedImage generated, int threshold) {
+        final int w = generated.getWidth();
+        final int h = generated.getHeight();
+        for (int i = x - MAX_CONSECUTIVE_FAILURES; i <= x + MAX_CONSECUTIVE_FAILURES; i++) {
+            if (i >= 0 && i != x && i < w) {
+                for (int j = y - MAX_CONSECUTIVE_FAILURES; j <= y + MAX_CONSECUTIVE_FAILURES; j++) {
+                    if (j >= 0 && j != y && j < h) {
+                        final int p1 = reference.getRGB(i, j);
+                        final int p2 = generated.getRGB(i, j);
+
+                        final int dr = getAlphaScaledRed(p1) - getAlphaScaledRed(p2);
+                        final int dg = getAlphaScaledGreen(p1) - getAlphaScaledGreen(p2);
+                        final int db = getAlphaScaledBlue(p1) - getAlphaScaledBlue(p2);
+
+                        if (Math.abs(db) <= threshold &&
+                            Math.abs(dg) <= threshold &&
+                            Math.abs(dr) <= threshold) {
+                            // If we find at least one matching neighbor, we assume the difference
+                            // is in antialiasing.
+                            return true;
+                        }
+                    }
+                }
+            }
+        }
+        return false;
+    }
+
 
     /**
      * Verifies that the pixels of reference and generated images are similar
@@ -107,7 +136,6 @@
 
         double maxDist = 0;
         for (int i = 0; i < w; i++) {
-            int consecutive = 0;
 
             for (int j = 0; j < h; j++) {
                 final int p1 = reference.getRGB(i, j);
@@ -121,15 +149,10 @@
                     Math.abs(dg) > threshold ||
                     Math.abs(dr) > threshold) {
                     System.err.println("fail dr=" + dr+ " dg=" + dg+ " db=" + db);
-
-                    consecutive++;
-
-                    if (consecutive > MAX_CONSECUTIVE_FAILURES) {
+                    if (!checkNeighbors(i, j, reference, generated, threshold)) {
                         System.err.println("consecutive fail");
                         return false;
                     }
-                } else {
-                    consecutive = 0;
                 }
             }
         }
diff --git a/tests/accessibilityservice/src/android/accessibilityservice/cts/AccessibilityTextTraversalTest.java b/tests/accessibilityservice/src/android/accessibilityservice/cts/AccessibilityTextTraversalTest.java
index d0bab51..5888273 100644
--- a/tests/accessibilityservice/src/android/accessibilityservice/cts/AccessibilityTextTraversalTest.java
+++ b/tests/accessibilityservice/src/android/accessibilityservice/cts/AccessibilityTextTraversalTest.java
@@ -2970,162 +2970,6 @@
     }
 
     @MediumTest
-    public void testActionNextAndPreviousAtGranularityPageOverText() throws Exception {
-        final EditText editText = (EditText) getActivity().findViewById(R.id.edit);
-
-        getInstrumentation().runOnMainSync(new Runnable() {
-            @Override
-            public void run() {
-                editText.setVisibility(View.VISIBLE);
-                editText.setText(getString(R.string.android_wiki));
-                Selection.removeSelection(editText.getText());
-            }
-        });
-
-        final AccessibilityNodeInfo text = getInstrumentation().getUiAutomation()
-               .getRootInActiveWindow().findAccessibilityNodeInfosByText(getString(
-                       R.string.android_wiki)).get(0);
-
-        final int granularities = text.getMovementGranularities();
-        assertEquals(granularities, AccessibilityNodeInfo.MOVEMENT_GRANULARITY_CHARACTER
-                | AccessibilityNodeInfo.MOVEMENT_GRANULARITY_WORD
-                | AccessibilityNodeInfo.MOVEMENT_GRANULARITY_LINE
-                | AccessibilityNodeInfo.MOVEMENT_GRANULARITY_PARAGRAPH
-                | AccessibilityNodeInfo.MOVEMENT_GRANULARITY_PAGE);
-
-        final Bundle arguments = new Bundle();
-        arguments.putInt(AccessibilityNodeInfo.ACTION_ARGUMENT_MOVEMENT_GRANULARITY_INT,
-                AccessibilityNodeInfo.MOVEMENT_GRANULARITY_PAGE);
-
-        // Move forward a few pages
-        for (int i = 0; i < CHARACTER_INDICES_OF_PAGE_START.length - 1; i++) {
-            AccessibilityEvent event = performMovementActionAndGetEvent(
-                    text,
-                    AccessibilityNodeInfo.ACTION_NEXT_AT_MOVEMENT_GRANULARITY,
-                    AccessibilityNodeInfo.MOVEMENT_GRANULARITY_PAGE,
-                    false);
-            assertEquals(event.getClassName(), EditText.class.getName());
-            assertTrue("Event should contain text", event.getText().size() > 0);
-            assertTrue("Event text doesn't match. Expected: " + getString(R.string.android_wiki)
-                    + ". Received:" + event.getText().get(0),
-                    TextUtils.equals(event.getText().get(0), getString(R.string.android_wiki)));
-            assertEquals("Event from should be start of text skipped.",
-                    CHARACTER_INDICES_OF_PAGE_START[i], event.getFromIndex());
-            assertEquals("Event to should be end of text skipped.",
-                    CHARACTER_INDICES_OF_PAGE_START[i + 1], event.getToIndex());
-            // Verify the selection position has changed.
-            assertEquals("Event selection start should match position it moved to.",
-                    CHARACTER_INDICES_OF_PAGE_START[i + 1],
-                    Selection.getSelectionStart(editText.getText()));
-            assertEquals("Event selection end should match position it moved to.",
-                    CHARACTER_INDICES_OF_PAGE_START[i + 1],
-                    Selection.getSelectionEnd(editText.getText()));
-        }
-
-        // Move back to the beginning
-        for (int i = CHARACTER_INDICES_OF_PAGE_START.length - 2; i >= 0; i--) {
-            AccessibilityEvent event = performMovementActionAndGetEvent(
-                    text,
-                    AccessibilityNodeInfo.ACTION_PREVIOUS_AT_MOVEMENT_GRANULARITY,
-                    AccessibilityNodeInfo.MOVEMENT_GRANULARITY_PAGE,
-                    false);
-            assertEquals(event.getClassName(), EditText.class.getName());
-            assertTrue("Event should contain text", event.getText().size() > 0);
-            assertTrue("Event text doesn't match. Expected: " + getString(R.string.android_wiki)
-                            + ". Received:" + event.getText().get(0),
-                    TextUtils.equals(event.getText().get(0), getString(R.string.android_wiki)));
-            assertEquals("Event from should be start of text skipped.",
-                    CHARACTER_INDICES_OF_PAGE_START[i], event.getFromIndex());
-            assertEquals("Event to should be end of text skipped.",
-                    CHARACTER_INDICES_OF_PAGE_START[i + 1], event.getToIndex());
-            // Verify the selection position has changed.
-            assertEquals("Event selection start should match position it moved to.",
-                    CHARACTER_INDICES_OF_PAGE_START[i],
-                    Selection.getSelectionStart(editText.getText()));
-            assertEquals("Event selection end should match position it moved to.",
-                    CHARACTER_INDICES_OF_PAGE_START[i],
-                    Selection.getSelectionEnd(editText.getText()));
-        }
-    }
-
-    @MediumTest
-    public void testActionNextAndPreviousAtGranularityPageOverTextExtend() throws Exception {
-        final EditText editText = (EditText) getActivity().findViewById(R.id.edit);
-
-        getInstrumentation().runOnMainSync(new Runnable() {
-            @Override
-            public void run() {
-                editText.setVisibility(View.VISIBLE);
-                editText.setText(getString(R.string.android_wiki));
-                Selection.removeSelection(editText.getText());
-            }
-        });
-
-        final AccessibilityNodeInfo text = getInstrumentation().getUiAutomation()
-               .getRootInActiveWindow().findAccessibilityNodeInfosByText(getString(
-                       R.string.android_wiki)).get(0);
-
-        final int granularities = text.getMovementGranularities();
-        assertEquals(granularities, AccessibilityNodeInfo.MOVEMENT_GRANULARITY_CHARACTER
-                | AccessibilityNodeInfo.MOVEMENT_GRANULARITY_WORD
-                | AccessibilityNodeInfo.MOVEMENT_GRANULARITY_LINE
-                | AccessibilityNodeInfo.MOVEMENT_GRANULARITY_PARAGRAPH
-                | AccessibilityNodeInfo.MOVEMENT_GRANULARITY_PAGE);
-
-        final Bundle arguments = new Bundle();
-        arguments.putInt(AccessibilityNodeInfo.ACTION_ARGUMENT_MOVEMENT_GRANULARITY_INT,
-                AccessibilityNodeInfo.MOVEMENT_GRANULARITY_PAGE);
-
-        // Move forward a few pages
-        for (int i = 0; i < CHARACTER_INDICES_OF_PAGE_START.length - 1; i++) {
-            AccessibilityEvent event = performMovementActionAndGetEvent(
-                    text,
-                    AccessibilityNodeInfo.ACTION_NEXT_AT_MOVEMENT_GRANULARITY,
-                    AccessibilityNodeInfo.MOVEMENT_GRANULARITY_PAGE,
-                    true);
-            assertEquals(event.getClassName(), EditText.class.getName());
-            assertTrue("Event should contain text", event.getText().size() > 0);
-            assertTrue("Event text doesn't match. Expected: " + getString(R.string.android_wiki)
-                            + ". Received:" + event.getText().get(0),
-                    TextUtils.equals(event.getText().get(0), getString(R.string.android_wiki)));
-            assertEquals("Event from should be start of text skipped",
-                    CHARACTER_INDICES_OF_PAGE_START[i], event.getFromIndex());
-            assertEquals("Event to should be end of text skipped",
-                    CHARACTER_INDICES_OF_PAGE_START[i + 1], event.getToIndex());
-            // Verify the selection position has changed.
-            assertEquals("Event selection start should stay at beginning",
-                    0, Selection.getSelectionStart(editText.getText()));
-            assertEquals("Event selection end should match current position",
-                    CHARACTER_INDICES_OF_PAGE_START[i + 1],
-                    Selection.getSelectionEnd(editText.getText()));
-        }
-
-        // Move back to the beginning
-        for (int i = CHARACTER_INDICES_OF_PAGE_START.length - 2; i >= 0; i--) {
-            AccessibilityEvent event = performMovementActionAndGetEvent(
-                    text,
-                    AccessibilityNodeInfo.ACTION_PREVIOUS_AT_MOVEMENT_GRANULARITY,
-                    AccessibilityNodeInfo.MOVEMENT_GRANULARITY_PAGE,
-                    true);
-            assertEquals(event.getClassName(), EditText.class.getName());
-            assertTrue("Event should contain text", event.getText().size() > 0);
-            assertTrue("Event text doesn't match. Expected: " + getString(R.string.android_wiki)
-                            + ". Received:" + event.getText().get(0),
-                    TextUtils.equals(event.getText().get(0), getString(R.string.android_wiki)));
-            assertEquals("Event from should be start of text skipped",
-                    CHARACTER_INDICES_OF_PAGE_START[i], event.getFromIndex());
-            assertEquals("Event to should be end of text skipped",
-                    CHARACTER_INDICES_OF_PAGE_START[i + 1], event.getToIndex());
-            // Verify the selection position has changed.
-            assertEquals("Event selection start should stay at beginning",
-                    0, Selection.getSelectionStart(editText.getText()));
-            assertEquals("Event selection end should match current position",
-                    CHARACTER_INDICES_OF_PAGE_START[i],
-                    Selection.getSelectionEnd(editText.getText()));
-        }
-    }
-
-    @MediumTest
     public void testActionNextAndPreviousAtGranularityParagraphOverText() throws Exception {
         final TextView textView = (TextView) getActivity().findViewById(R.id.edit);
 
diff --git a/tests/autofillservice/assets/login.html b/tests/autofillservice/assets/login.html
index 60e7cf7..4d8effc 100644
--- a/tests/autofillservice/assets/login.html
+++ b/tests/autofillservice/assets/login.html
@@ -17,8 +17,8 @@
 <html>
 <body>
 <form action="login.html" name="FORM AM I">
-    Username: <input type="text" name="username" autocomplete="username" placeholder="There's no place like a holder"/><br/>
-    Password: <input type="password" name="password" autocomplete="current-password" placeholder="Holder it like it cannnot passer a word"/><br/>
+    Username: <input type="text" name="username" autocomplete="username" placeholder="There's no place like a holder" oninput="javascript:JsHandler.onUsernameChanged(this.value)"/><br/>
+    Password: <input type="password" name="password" autocomplete="current-password" placeholder="Holder it like it cannnot passer a word" oninput="javascript:JsHandler.onPasswordChanged(this.value)"/><br/>
     <br/>
     <input type="submit" value="Login"/>
 </form>
diff --git a/tests/autofillservice/src/android/autofillservice/cts/MyWebView.java b/tests/autofillservice/src/android/autofillservice/cts/MyWebView.java
index 754d5e9..486cf7f 100644
--- a/tests/autofillservice/src/android/autofillservice/cts/MyWebView.java
+++ b/tests/autofillservice/src/android/autofillservice/cts/MyWebView.java
@@ -21,8 +21,8 @@
 
 import android.content.Context;
 import android.util.AttributeSet;
-import android.util.SparseArray;
-import android.view.autofill.AutofillValue;
+import android.util.Log;
+import android.webkit.JavascriptInterface;
 import android.webkit.WebView;
 
 import java.util.concurrent.CountDownLatch;
@@ -33,14 +33,18 @@
  */
 public class MyWebView extends WebView {
 
+    private static final String TAG = "MyWebView";
+
     private FillExpectation mExpectation;
 
     public MyWebView(Context context) {
         super(context);
+        setJsHandler();
     }
 
     public MyWebView(Context context, AttributeSet attrs) {
         super(context, attrs);
+        setJsHandler();
     }
 
     public void expectAutofill(String username, String password) {
@@ -49,63 +53,73 @@
 
     public void assertAutofilled() throws Exception {
         assertWithMessage("expectAutofill() not called").that(mExpectation).isNotNull();
-        final boolean set = mExpectation.mLatch.await(FILL_TIMEOUT.ms(), TimeUnit.MILLISECONDS);
-        if (mExpectation.mException != null) {
-            throw mExpectation.mException;
-        }
-        assertWithMessage("Timeout (%s ms) expecting autofill()", FILL_TIMEOUT.ms())
-                .that(set).isTrue();
-        assertWithMessage("Wrong value for username").that(mExpectation.mActualUsername)
-                .isEqualTo(mExpectation.mExpectedUsername);
-        assertWithMessage("Wrong value for password").that(mExpectation.mActualPassword)
-                .isEqualTo(mExpectation.mExpectedPassword);
+        mExpectation.assertUsernameCalled();
+        mExpectation.assertPasswordCalled();
     }
 
-    @Override
-    public void autofill(SparseArray<AutofillValue> values) {
-        super.autofill(values);
-
-        if (mExpectation == null) return;
-
-        try {
-            if (values == null || values.size() != 2) {
-                mExpectation.mException =
-                        new IllegalArgumentException("Invalid values on autofill(): " + values);
-            } else {
-                try {
-                    // We don't know the order of the values in the array. As we're just expecting
-                    // 2, it's easy to just check them individually; if we had more, than we would
-                    // need to override onProvideAutofillVirtualStructure() to keep track of the
-                    // nodes added by WebView so we could save their AutofillIds and reuse here.
-                    final String value1 = values.valueAt(0).getTextValue().toString();
-                    final String value2 = values.valueAt(1).getTextValue().toString();
-                    if (mExpectation.mExpectedUsername.equals(value1)) {
-                        mExpectation.mActualUsername = value1;
-                        mExpectation.mActualPassword = value2;
-                    } else {
-                        mExpectation.mActualUsername = value2;
-                        mExpectation.mActualPassword = value1;
-                    }
-                } catch (Exception e) {
-                    mExpectation.mException = e;
-                }
-            }
-        } finally {
-            mExpectation.mLatch.countDown();
-        }
+    private void setJsHandler() {
+        getSettings().setJavaScriptEnabled(true);
+        addJavascriptInterface(new JavascriptHandler(), "JsHandler");
     }
 
     private class FillExpectation {
-        private final CountDownLatch mLatch = new CountDownLatch(1);
+        private final CountDownLatch mUsernameLatch = new CountDownLatch(1);
+        private final CountDownLatch mPasswordLatch = new CountDownLatch(1);
         private final String mExpectedUsername;
         private final String mExpectedPassword;
         private String mActualUsername;
         private String mActualPassword;
-        private Exception mException;
 
         FillExpectation(String username, String password) {
             this.mExpectedUsername = username;
             this.mExpectedPassword = password;
         }
+
+        void setUsername(String username) {
+            mActualUsername = username;
+            mUsernameLatch.countDown();
+        }
+
+        void setPassword(String password) {
+            mActualPassword = password;
+            mPasswordLatch.countDown();
+        }
+
+        void assertUsernameCalled() throws Exception {
+            assertCalled(mUsernameLatch, "username");
+            assertWithMessage("Wrong value for username").that(mExpectation.mActualUsername)
+                .isEqualTo(mExpectation.mExpectedUsername);
+        }
+
+        void assertPasswordCalled() throws Exception {
+            assertCalled(mPasswordLatch, "password");
+            assertWithMessage("Wrong value for password").that(mExpectation.mActualPassword)
+                    .isEqualTo(mExpectation.mExpectedPassword);
+        }
+
+        private void assertCalled(CountDownLatch latch, String field) throws Exception {
+            if (!latch.await(FILL_TIMEOUT.ms(), TimeUnit.MILLISECONDS)) {
+                throw new RetryableException(FILL_TIMEOUT, "%s not called", field);
+            }
+        }
+    }
+
+    private class JavascriptHandler {
+
+        @JavascriptInterface
+        public void onUsernameChanged(String username) {
+            Log.d(TAG, "onUsernameChanged():" + username);
+            if (mExpectation != null) {
+                mExpectation.setUsername(username);
+            }
+        }
+
+        @JavascriptInterface
+        public void onPasswordChanged(String password) {
+            Log.d(TAG, "onPasswordChanged():" + password);
+            if (mExpectation != null) {
+                mExpectation.setPassword(password);
+            }
+        }
     }
 }
diff --git a/tests/autofillservice/src/android/autofillservice/cts/WebViewActivityTest.java b/tests/autofillservice/src/android/autofillservice/cts/WebViewActivityTest.java
index 8b8b40e..e1f4f1e 100644
--- a/tests/autofillservice/src/android/autofillservice/cts/WebViewActivityTest.java
+++ b/tests/autofillservice/src/android/autofillservice/cts/WebViewActivityTest.java
@@ -138,14 +138,6 @@
         mUiBot.assertNoDatasets();
         callback.assertUiHiddenEvent(myWebView, passwordChildId);
 
-        // Make sure screen was autofilled.
-        assertThat(mActivity.getUsernameInput(mUiBot).getText()).isEqualTo("dude");
-        // TODO: proper way to verify text (which is ..... because it's a password) - ideally it
-        // should call passwordInput.isPassword(), but that's not exposed
-        final String password = mActivity.getPasswordInput(mUiBot).getText();
-        assertThat(password).isNotEqualTo("sweet");
-        assertThat(password).hasLength(5);
-
         // Assert structure passed to service.
         try {
             final ViewNode webViewNode =
@@ -275,14 +267,6 @@
         myWebView.assertAutofilled();
         callback.assertUiHiddenEvent(myWebView, usernameChildId);
 
-        // Make sure screen was autofilled.
-        assertThat(mActivity.getUsernameInput(mUiBot).getText()).isEqualTo("dude");
-        // TODO: proper way to verify text (which is ..... because it's a password) - ideally it
-        // should call passwordInput.isPassword(), but that's not exposed
-        final String password = mActivity.getPasswordInput(mUiBot).getText();
-        assertThat(password).isNotEqualTo("sweet");
-        assertThat(password).hasLength(5);
-
         // Now trigger save.
         if (INJECT_EVENTS) {
             mActivity.getUsernameInput(mUiBot).click();
diff --git a/tests/camera/src/android/hardware/camera2/cts/CameraDeviceTest.java b/tests/camera/src/android/hardware/camera2/cts/CameraDeviceTest.java
index 9a4e42c..98fa7af 100644
--- a/tests/camera/src/android/hardware/camera2/cts/CameraDeviceTest.java
+++ b/tests/camera/src/android/hardware/camera2/cts/CameraDeviceTest.java
@@ -2476,6 +2476,12 @@
                 // Skip unknown templates here
         }
 
+        // Check distortion correction mode
+        if (mStaticInfo.isDistortionCorrectionSupported()) {
+            mCollector.expectKeyValueNotEquals(request, DISTORTION_CORRECTION_MODE,
+                    CaptureRequest.DISTORTION_CORRECTION_MODE_OFF);
+        }
+
         // TODO: use the list of keys from CameraCharacteristics to avoid expecting
         //       keys which are not available by this CameraDevice.
     }
diff --git a/tests/camera/src/android/hardware/camera2/cts/CaptureResultTest.java b/tests/camera/src/android/hardware/camera2/cts/CaptureResultTest.java
index c4174ca..4146333 100644
--- a/tests/camera/src/android/hardware/camera2/cts/CaptureResultTest.java
+++ b/tests/camera/src/android/hardware/camera2/cts/CaptureResultTest.java
@@ -26,6 +26,7 @@
 import android.hardware.camera2.TotalCaptureResult;
 import android.media.Image;
 import android.media.ImageReader;
+import android.os.Build;
 import android.os.SystemClock;
 import android.platform.test.annotations.AppModeFull;
 import android.util.Pair;
@@ -473,6 +474,10 @@
                         errorCollector.expectEquals(msg,
                                 requestBuilder.get(CaptureRequest.STATISTICS_OIS_DATA_MODE),
                                 result.get(CaptureResult.STATISTICS_OIS_DATA_MODE));
+                    } else if (key.equals(CaptureResult.DISTORTION_CORRECTION_MODE)) {
+                         errorCollector.expectEquals(msg,
+                                requestBuilder.get(CaptureRequest.DISTORTION_CORRECTION_MODE),
+                                result.get(CaptureResult.DISTORTION_CORRECTION_MODE));
                     } else {
                         // Only do non-null check for the rest of keys.
                         errorCollector.expectKeyValueNotNull(failMsg, result, key);
@@ -552,23 +557,9 @@
         }
 
         //Keys for lens distortion correction
-        boolean distortionCorrectionSupported = false;
-        int[] distortionModes = staticInfo.getCharacteristics().get(
-                CameraCharacteristics.DISTORTION_CORRECTION_AVAILABLE_MODES);
-        if (distortionModes == null) {
+        boolean distortionCorrectionSupported = staticInfo.isDistortionCorrectionSupported();
+        if (!distortionCorrectionSupported) {
             waiverKeys.add(CaptureResult.DISTORTION_CORRECTION_MODE);
-        } else {
-            boolean gotNonOff = false;
-            for (int mode : distortionModes) {
-                if (mode != CaptureRequest.DISTORTION_CORRECTION_MODE_OFF) {
-                    gotNonOff = true;
-                    distortionCorrectionSupported = true;
-                    break;
-                }
-            }
-            if (!gotNonOff) {
-                waiverKeys.add(CaptureResult.DISTORTION_CORRECTION_MODE);
-            }
         }
 
         // These keys must present on either DEPTH or distortion correction devices
@@ -578,9 +569,16 @@
             waiverKeys.add(CaptureResult.LENS_INTRINSIC_CALIBRATION);
             waiverKeys.add(CaptureResult.LENS_RADIAL_DISTORTION);
             waiverKeys.add(CaptureResult.LENS_DISTORTION);
+        } else {
+            // Radial distortion doesn't need to be present for new devices, or old devices that
+            // opt in the new lens distortion tag.
+            CameraCharacteristics c = staticInfo.getCharacteristics();
+            if (Build.VERSION.FIRST_SDK_INT > Build.VERSION_CODES.O_MR1 ||
+                    c.get(CameraCharacteristics.LENS_DISTORTION) != null) {
+                waiverKeys.add(CaptureResult.LENS_RADIAL_DISTORTION);
+            }
         }
 
-
         // Waived if RAW output is not supported
         int[] outputFormats = staticInfo.getAvailableFormats(
                 StaticMetadata.StreamDirection.Output);
diff --git a/tests/camera/src/android/hardware/camera2/cts/ExtendedCameraCharacteristicsTest.java b/tests/camera/src/android/hardware/camera2/cts/ExtendedCameraCharacteristicsTest.java
index 22851e6..7476747 100644
--- a/tests/camera/src/android/hardware/camera2/cts/ExtendedCameraCharacteristicsTest.java
+++ b/tests/camera/src/android/hardware/camera2/cts/ExtendedCameraCharacteristicsTest.java
@@ -885,8 +885,34 @@
             Integer poseReference = c.get(CameraCharacteristics.LENS_POSE_REFERENCE);
             float[] cameraIntrinsics = c.get(CameraCharacteristics.LENS_INTRINSIC_CALIBRATION);
             float[] distortion = getLensDistortion(c);
+            Size pixelArraySize = c.get(CameraCharacteristics.SENSOR_INFO_PIXEL_ARRAY_SIZE);
             Rect precorrectionArray = c.get(
                 CameraCharacteristics.SENSOR_INFO_PRE_CORRECTION_ACTIVE_ARRAY_SIZE);
+            Rect activeArray = c.get(
+                CameraCharacteristics.SENSOR_INFO_ACTIVE_ARRAY_SIZE);
+
+            // Verify pre-correction array encloses active array
+            mCollector.expectTrue("preCorrectionArray [" + precorrectionArray.left + ", " +
+                    precorrectionArray.top + ", " + precorrectionArray.right + ", " +
+                    precorrectionArray.bottom + "] does not enclose activeArray[" +
+                    activeArray.left + ", " + activeArray.top + ", " + activeArray.right +
+                    ", " + activeArray.bottom,
+                    precorrectionArray.contains(activeArray.left, activeArray.top) &&
+                    precorrectionArray.contains(activeArray.right-1, activeArray.bottom-1));
+
+            // Verify pixel array encloses pre-correction array
+            mCollector.expectTrue("preCorrectionArray [" + precorrectionArray.left + ", " +
+                    precorrectionArray.top + ", " + precorrectionArray.right + ", " +
+                    precorrectionArray.bottom + "] isn't enclosed by pixelArray[" +
+                    pixelArraySize.getWidth() + ", " + pixelArraySize.getHeight() + "]",
+                    precorrectionArray.left >= 0 &&
+                    precorrectionArray.left < pixelArraySize.getWidth() &&
+                    precorrectionArray.right > 0 &&
+                    precorrectionArray.right <= pixelArraySize.getWidth() &&
+                    precorrectionArray.top >= 0 &&
+                    precorrectionArray.top < pixelArraySize.getHeight() &&
+                    precorrectionArray.bottom > 0 &&
+                    precorrectionArray.bottom <= pixelArraySize.getHeight());
 
             if (supportDepth) {
                 mCollector.expectTrue("Supports DEPTH_OUTPUT but does not support DEPTH16",
diff --git a/tests/camera/src/android/hardware/cts/CameraTest.java b/tests/camera/src/android/hardware/cts/CameraTest.java
index 9efccf1..81b42ef 100644
--- a/tests/camera/src/android/hardware/cts/CameraTest.java
+++ b/tests/camera/src/android/hardware/cts/CameraTest.java
@@ -194,6 +194,13 @@
      * Terminates the message looper thread.
      */
     private void terminateMessageLooper() throws Exception {
+        terminateMessageLooper(false);
+    }
+
+    /*
+     * Terminates the message looper thread, optionally allowing evict error
+     */
+    private void terminateMessageLooper(boolean allowEvict) throws Exception {
         mLooper.quit();
         // Looper.quit() is asynchronous. The looper may still has some
         // preview callbacks in the queue after quit is called. The preview
@@ -203,7 +210,13 @@
         mLooper.getThread().join();
         mCamera.release();
         mCamera = null;
-        assertEquals("Got camera error callback.", NO_ERROR, mCameraErrorCode);
+        if (allowEvict) {
+            assertTrue("Got unexpected camera error callback.",
+                    (NO_ERROR == mCameraErrorCode ||
+                    Camera.CAMERA_ERROR_EVICTED == mCameraErrorCode));
+        } else {
+            assertEquals("Got camera error callback.", NO_ERROR, mCameraErrorCode);
+        }
     }
 
     // Align 'x' to 'to', which should be a power of 2
@@ -2501,7 +2514,7 @@
         mCamera.stopPreview();
 
         firstLooper.quit();
-        terminateMessageLooper();
+        terminateMessageLooper(true/*allowEvict*/);
     }
 
     // This callback just signals on the condition variable, making it useful for checking that
diff --git a/tests/camera/utils/src/android/hardware/camera2/cts/helpers/StaticMetadata.java b/tests/camera/utils/src/android/hardware/camera2/cts/helpers/StaticMetadata.java
index 0d0e592..646dfe7 100644
--- a/tests/camera/utils/src/android/hardware/camera2/cts/helpers/StaticMetadata.java
+++ b/tests/camera/utils/src/android/hardware/camera2/cts/helpers/StaticMetadata.java
@@ -2357,6 +2357,26 @@
     }
 
     /**
+     * Check if distortion correction is supported.
+     */
+    public boolean isDistortionCorrectionSupported() {
+        boolean distortionCorrectionSupported = false;
+        int[] distortionModes = mCharacteristics.get(
+                CameraCharacteristics.DISTORTION_CORRECTION_AVAILABLE_MODES);
+        if (distortionModes == null) {
+            return false;
+        }
+
+        for (int mode : distortionModes) {
+            if (mode != CaptureRequest.DISTORTION_CORRECTION_MODE_OFF) {
+                return true;
+            }
+        }
+
+        return false;
+    }
+
+    /**
      * Get the value in index for a fixed-size array from a given key.
      *
      * <p>If the camera device is incorrectly reporting values, log a warning and return
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 09037bb..9e68a41 100644
--- a/tests/framework/base/activitymanager/src/android/server/am/ActivityManagerActivityVisibilityTests.java
+++ b/tests/framework/base/activitymanager/src/android/server/am/ActivityManagerActivityVisibilityTests.java
@@ -57,6 +57,7 @@
 import static org.junit.Assume.assumeTrue;
 
 import android.platform.test.annotations.Presubmit;
+import android.support.test.filters.FlakyTest;
 
 import org.junit.Rule;
 import org.junit.Test;
@@ -77,6 +78,7 @@
 
     @Presubmit
     @Test
+    @FlakyTest(bugId = 110276714)
     public void testTranslucentActivityOnTopOfPinnedStack() throws Exception {
         if (!supportsPip()) {
             return;
@@ -180,6 +182,7 @@
 
     @Presubmit
     @Test
+    @FlakyTest(bugId = 110276714)
     public void testTurnScreenOnActivity() throws Exception {
         try (final LockScreenSession lockScreenSession = new LockScreenSession()) {
             lockScreenSession.sleepDevice();
@@ -192,6 +195,7 @@
 
     @Presubmit
     @Test
+    @FlakyTest(bugId = 110276714)
     public void testFinishActivityInNonFocusedStack() throws Exception {
         if (!supportsSplitScreenMultiWindow()) {
             // Skipping test: no multi-window support
diff --git a/tests/framework/base/activitymanager/src/android/server/am/ActivityManagerAppConfigurationTests.java b/tests/framework/base/activitymanager/src/android/server/am/ActivityManagerAppConfigurationTests.java
index a00d3eb..6e01997 100644
--- a/tests/framework/base/activitymanager/src/android/server/am/ActivityManagerAppConfigurationTests.java
+++ b/tests/framework/base/activitymanager/src/android/server/am/ActivityManagerAppConfigurationTests.java
@@ -321,6 +321,7 @@
      */
     @Presubmit
     @Test
+    @FlakyTest(bugId = 110276714)
     public void testDialogWhenLargeSplitSmall() {
         assumeTrue("Skipping test: no multi-window support", supportsSplitScreenMultiWindow());
 
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 4f84f0e..9cdeb5e 100644
--- a/tests/framework/base/activitymanager/src/android/server/am/ActivityManagerSplitScreenTests.java
+++ b/tests/framework/base/activitymanager/src/android/server/am/ActivityManagerSplitScreenTests.java
@@ -547,6 +547,7 @@
 
     @Test
     @Presubmit
+    @FlakyTest(bugId = 110276714)
     public void testResizeDockedStack() throws Exception {
         launchActivitiesInSplitScreen(
                 getLaunchActivityBuilder().setTargetActivity(DOCKED_ACTIVITY),
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 67a773d..574747a 100644
--- a/tests/framework/base/activitymanager/src/android/server/am/KeyguardTests.java
+++ b/tests/framework/base/activitymanager/src/android/server/am/KeyguardTests.java
@@ -48,6 +48,7 @@
 
 import android.platform.test.annotations.Presubmit;
 import android.server.am.WindowManagerState.WindowState;
+import android.support.test.filters.FlakyTest;
 
 import org.junit.Before;
 import org.junit.Test;
@@ -94,6 +95,7 @@
     }
 
     @Test
+    @FlakyTest(bugId = 110276714)
     public void testShowWhenLockedActivity() throws Exception {
         try (final LockScreenSession lockScreenSession = new LockScreenSession()) {
             launchActivity(SHOW_WHEN_LOCKED_ACTIVITY);
diff --git a/tests/netlegacy22.permission/src/android/net/cts/legacy/api22/permission/QtaguidPermissionTest.java b/tests/netlegacy22.permission/src/android/net/cts/legacy/api22/permission/QtaguidPermissionTest.java
index 08fd753..60d2a2a 100644
--- a/tests/netlegacy22.permission/src/android/net/cts/legacy/api22/permission/QtaguidPermissionTest.java
+++ b/tests/netlegacy22.permission/src/android/net/cts/legacy/api22/permission/QtaguidPermissionTest.java
@@ -19,8 +19,6 @@
 import java.io.InputStream;
 import java.io.OutputStream;
 
-
-
 public class QtaguidPermissionTest extends AndroidTestCase {
 
     private static final String QTAGUID_STATS_FILE = "/proc/net/xt_qtaguid/stats";
@@ -56,19 +54,20 @@
         }
     }
 
-    private void accessOwnTrafficStats() throws IOException {
+    private void accessOwnTrafficStats(long expectedTxBytes) throws IOException {
 
         final int ownAppUid = getContext().getApplicationInfo().uid;
 
-        boolean foundOwnDetailedStats = false;
+        long totalTxBytes = 0;
         try {
             BufferedReader qtaguidReader = new BufferedReader(new FileReader(QTAGUID_STATS_FILE));
             String line;
             while ((line = qtaguidReader.readLine()) != null) {
                 String tokens[] = line.split(" ");
                 if (tokens.length > 3 && tokens[3].equals(String.valueOf(ownAppUid))) {
-                    if (!tokens[2].equals("0x0")) {
-                      foundOwnDetailedStats = true;
+                    // Check the total stats of this uid is larger then 1MB
+                    if (tokens[2].equals("0x0")) {
+                        totalTxBytes += Integer.parseInt(tokens[7]);
                     }
                 }
             }
@@ -76,7 +75,8 @@
         } catch (FileNotFoundException e) {
             fail("Was not able to access qtaguid/stats: " + e);
         }
-        assertTrue("Was expecting to find own traffic stats", foundOwnDetailedStats);
+        assertTrue(totalTxBytes + " expected to be greater than or equal to"
+            + expectedTxBytes + "bytes", totalTxBytes >= expectedTxBytes);
     }
 
     public void testAccessOwnQtaguidTrafficStats() throws IOException {
@@ -124,6 +124,6 @@
             server.close();
         }
 
-        accessOwnTrafficStats();
+        accessOwnTrafficStats(byteCount * packetCount);
     }
 }
diff --git a/tests/tests/content/src/android/content/cts/AvailableIntentsTest.java b/tests/tests/content/src/android/content/cts/AvailableIntentsTest.java
index c812e91..f82e43f 100644
--- a/tests/tests/content/src/android/content/cts/AvailableIntentsTest.java
+++ b/tests/tests/content/src/android/content/cts/AvailableIntentsTest.java
@@ -379,4 +379,8 @@
             assertCanBeHandled(new Intent(Settings.ACTION_NFC_PAYMENT_SETTINGS));
         }
     }
+
+    public void testPowerUsageSummarySettings() {
+        assertCanBeHandled(new Intent(Intent.ACTION_POWER_USAGE_SUMMARY));
+    }
 }
diff --git a/tests/tests/jni/libjnitest/android_jni_cts_LinkerNamespacesTest.cpp b/tests/tests/jni/libjnitest/android_jni_cts_LinkerNamespacesTest.cpp
index de0d441..643fd75 100644
--- a/tests/tests/jni/libjnitest/android_jni_cts_LinkerNamespacesTest.cpp
+++ b/tests/tests/jni/libjnitest/android_jni_cts_LinkerNamespacesTest.cpp
@@ -48,6 +48,8 @@
 static const std::string kProductLibraryPath = "/product/lib";
 #endif
 
+static const std::string kWebViewPlatSupportLib = "libwebviewchromium_plat_support.so";
+
 // This is not the complete list - just a small subset
 // of the libraries that should reside in /system/lib
 // for app-compatibility reasons.
@@ -117,6 +119,12 @@
     error = dlerror();
   }
 
+  if (android::base::EndsWith(path, '/' + kWebViewPlatSupportLib)) {
+    // Don't try to load this library from Java. Otherwise, the lib is initialized via
+    // JNI_OnLoad and it fails since WebView is not loaded in this test process.
+    return error;
+  }
+
   // try to load the same lib using System.load() in Java to see if it gives consistent
   // result with dlopen.
   static jmethodID load_library = env->GetStaticMethodID(clazz, "loadSharedLibrary",
diff --git a/tests/tests/jni/src/android/jni/cts/LinkerNamespacesHelper.java b/tests/tests/jni/src/android/jni/cts/LinkerNamespacesHelper.java
index 31d9844..3b3c972 100644
--- a/tests/tests/jni/src/android/jni/cts/LinkerNamespacesHelper.java
+++ b/tests/tests/jni/src/android/jni/cts/LinkerNamespacesHelper.java
@@ -225,11 +225,6 @@
 
     private static boolean loadSharedLibrary(String libFilePath) {
         String baseName = new File(libFilePath).getName();
-        if (baseName.equals(WEBVIEW_PLAT_SUPPORT_LIB)) {
-          // Don't try to load this library from Java. Otherwise, the lib is initialized via
-          // JNI_OnLoad and it fails since WebView is not loaded in this test process.
-          return true;
-        }
         try {
             System.load(libFilePath);
             // Also ensure that the lib is also accessible via its libname.
diff --git a/tests/tests/location/src/android/location/cts/GnssMeasurementValuesTest.java b/tests/tests/location/src/android/location/cts/GnssMeasurementValuesTest.java
index 1cb02d4..216989f 100644
--- a/tests/tests/location/src/android/location/cts/GnssMeasurementValuesTest.java
+++ b/tests/tests/location/src/android/location/cts/GnssMeasurementValuesTest.java
@@ -20,7 +20,9 @@
 import android.location.GnssMeasurementsEvent;
 import android.util.Log;
 
+import java.util.HashSet;
 import java.util.List;
+import java.util.Set;
 
 /**
  * Test the {@link GnssMeasurement} values.
@@ -31,8 +33,8 @@
  * 3. Wait for {@link #LOCATION_TO_COLLECT_COUNT} locations.
  *          3.1 Confirm locations have been found.
  * 4. Check {@link GnssMeasurementsEvent} status: if the status is not
- *    {@link GnssMeasurementsEvent#STATUS_READY}, the test will be skipped because one of the
- *    following reasons:
+ *    {@link GnssMeasurementsEvent.Callback#STATUS_READY}, the test will be skipped because
+ *    one of the following reasons:
  *          4.1 the device does not support the GPS feature,
  *          4.2 GPS Location is disabled in the device and this is CTS (non-verifier)
  *  5. Verify {@link GnssMeasurement}s (all mandatory fields), the test will fail if any of the
@@ -42,15 +44,19 @@
 
     private static final String TAG = "GnssMeasValuesTest";
     private static final int LOCATION_TO_COLLECT_COUNT = 5;
+    private static final int YEAR_2017 = 2017;
 
     private TestGnssMeasurementListener mMeasurementListener;
     private TestLocationListener mLocationListener;
+    // Store list of Satellites including Gnss Band, constellation & SvId
+    private Set<String> mGnssMeasSvStringIds;
 
     @Override
     protected void setUp() throws Exception {
         super.setUp();
 
         mTestLocationManager = new TestLocationManager(getContext());
+        mGnssMeasSvStringIds = new HashSet<>();
     }
 
     @Override
@@ -73,7 +79,7 @@
     public void testListenForGnssMeasurements() throws Exception {
         // Checks if GPS hardware feature is present, skips test (pass) if not,
         // and hard asserts that Location/GPS (Provider) is turned on if is Cts Verifier.
-       if (!TestMeasurementUtil.canTestRunOnCurrentDevice(mTestLocationManager,
+        if (!TestMeasurementUtil.canTestRunOnCurrentDevice(mTestLocationManager,
                 TAG, MIN_HARDWARE_YEAR_MEASUREMENTS_REQUIRED, isCtsVerifierTest())) {
             return;
         }
@@ -84,12 +90,19 @@
         mMeasurementListener = new TestGnssMeasurementListener(TAG);
         mTestLocationManager.registerGnssMeasurementCallback(mMeasurementListener);
 
+        // Register a status callback to enable checking Svs across status & measurements.
+        // Count in status callback is not important as this test is pass/fail based on
+        // measurement count, not status count.
+        TestGnssStatusCallback gnssStatusCallback = new TestGnssStatusCallback(TAG, 0);
+        mTestLocationManager.registerGnssStatusCallback(gnssStatusCallback);
+
         boolean success = mLocationListener.await();
         SoftAssert.failOrWarning(isMeasurementTestStrict(),
                 "Time elapsed without getting enough location fixes."
                         + " Possibly, the test has been run deep indoors."
                         + " Consider retrying test outdoors.",
                 success);
+        mTestLocationManager.unregisterGnssStatusCallback(gnssStatusCallback);
 
         Log.i(TAG, "Location status received = " + mLocationListener.isLocationReceived());
 
@@ -123,12 +136,34 @@
                         measurement, softAssert, timeInNs);
                 carrierPhaseQualityPrrFound |=
                         TestMeasurementUtil.gnssMeasurementHasCarrierPhasePrr(measurement);
+                if (measurement.hasCarrierFrequencyHz()) {
+                    mGnssMeasSvStringIds.add(
+                        TestMeasurementUtil.getUniqueSvStringId(measurement.getConstellationType(),
+                            measurement.getSvid(), measurement.getCarrierFrequencyHz()));
+                } else {
+                    mGnssMeasSvStringIds.add(
+                        TestMeasurementUtil.getUniqueSvStringId(measurement.getConstellationType(),
+                            measurement.getSvid()));
+                }
             }
         }
         softAssert.assertOrWarnTrue(isMeasurementTestStrict(),
                 "GNSS Measurements PRRs with Carrier Phase "
                         + "level uncertainties.  If failed, retry near window or outdoors?",
                 carrierPhaseQualityPrrFound);
+        Log.i(TAG, "Meas received for:" + mGnssMeasSvStringIds);
+        Log.i(TAG, "Status Received for:" + gnssStatusCallback.getGnssUsedSvStringIds());
+        if (mTestLocationManager.getLocationManager().getGnssYearOfHardware() >= YEAR_2017) {
+            // Get all SVs marked as USED in GnssStatus. Remove any SV for which measurement
+            // is received. The resulting list should ideally be empty (How can you use a SV
+            // with no measurement). To allow for race condition where the last GNSS Status
+            // has 1 SV with used flag set, but the corresponding measurement has not yet been
+            // received, the check is done as <= 1
+            Set<String> svDiff = gnssStatusCallback.getGnssUsedSvStringIds();
+            svDiff.removeAll(mGnssMeasSvStringIds);
+            softAssert.assertTrue("Used Svs with no Meas: " + (svDiff.isEmpty() ? "None" : svDiff),
+                svDiff.size() <= 1);
+        }
         softAssert.assertAll();
     }
 }
diff --git a/tests/tests/location/src/android/location/cts/GnssStatusTest.java b/tests/tests/location/src/android/location/cts/GnssStatusTest.java
index 003d969..1f7ffa4 100644
--- a/tests/tests/location/src/android/location/cts/GnssStatusTest.java
+++ b/tests/tests/location/src/android/location/cts/GnssStatusTest.java
@@ -8,7 +8,6 @@
     private static final String TAG = "GnssStatusTest";
     private static final int LOCATION_TO_COLLECT_COUNT = 1;
     private static final int STATUS_TO_COLLECT_COUNT = 3;
-    private static final int YEAR_2018 = 2018;
 
   @Override
   protected void setUp() throws Exception {
@@ -108,7 +107,7 @@
       TestMeasurementUtil.validateSvidSub(softAssert, null,
           status.getConstellationType(i),status.getSvid(i));
 
-      // For those function with boolean type return, just simplly call the function
+      // For those function with boolean type return, just simply call the function
       // to make sure those function won't crash, also increase the test coverage.
       Log.i(TAG, "hasAlmanacData: " + status.hasAlmanacData(i));
       Log.i(TAG, "hasEphemerisData: " + status.hasEphemerisData(i));
diff --git a/tests/tests/location/src/android/location/cts/GnssTestCase.java b/tests/tests/location/src/android/location/cts/GnssTestCase.java
index 0258244..508e0da 100644
--- a/tests/tests/location/src/android/location/cts/GnssTestCase.java
+++ b/tests/tests/location/src/android/location/cts/GnssTestCase.java
@@ -15,8 +15,11 @@
  */
 package android.location.cts;
 
+import android.content.pm.PackageManager;
 import android.test.AndroidTestCase;
-import android.util.Log;
+
+import com.android.compatibility.common.util.FeatureUtil;
+import com.android.compatibility.common.util.PropertyUtil;
 
 /**
  * Base Test Case class for all Gnss Tests.
@@ -32,14 +35,16 @@
     protected GnssTestCase() {
     }
 
-    // When CTS testing is run in Verifier mode access to GNSS signals is expected
-    // On devices using newer hardware, GNSS measurement support is required.
-    // Hence when both conditions are true, we can verify stricter tests of functionality
-    // availability.
+    // When using newer hardware, GNSS measurement support is required.
     protected boolean isMeasurementTestStrict() {
+        if (FeatureUtil.hasSystemFeature(PackageManager.FEATURE_AUTOMOTIVE)) {
+            return false;
+        }
+        if (PropertyUtil.isFactoryROM()) {
+            return true;
+        }
         return ((mTestLocationManager.getLocationManager().getGnssYearOfHardware() >=
-                 MIN_HARDWARE_YEAR_MEASUREMENTS_REQUIRED) &&
-                isCtsVerifierTest());
+                MIN_HARDWARE_YEAR_MEASUREMENTS_REQUIRED));
     }
 
     public void setTestAsCtsVerifierTest(boolean value) {
@@ -49,4 +54,4 @@
     public boolean isCtsVerifierTest() {
         return mCtsVerifierTest;
     }
-}
\ No newline at end of file
+}
diff --git a/tests/tests/location/src/android/location/cts/TestGnssMeasurementListener.java b/tests/tests/location/src/android/location/cts/TestGnssMeasurementListener.java
index 1b8c3c3..3a64c46 100644
--- a/tests/tests/location/src/android/location/cts/TestGnssMeasurementListener.java
+++ b/tests/tests/location/src/android/location/cts/TestGnssMeasurementListener.java
@@ -25,7 +25,6 @@
 import java.util.HashMap;
 import java.util.List;
 import java.util.concurrent.CountDownLatch;
-import java.util.concurrent.TimeUnit;
 
 /**
  * Used for receiving GPS satellite measurements from the GPS engine.
@@ -39,7 +38,6 @@
     // Timeout in sec for count down latch wait
     private static final int STATUS_TIMEOUT_IN_SEC = 10;
     private static final int MEAS_TIMEOUT_IN_SEC = 60;
-    private static final int TOW_DECODED_MEASUREMENT_STATE_BIT = 3;
     private static final int C_TO_N0_THRESHOLD_DB_HZ = 18;
     private volatile int mStatus = -1;
 
@@ -89,15 +87,15 @@
                 HashMap<Integer, Integer> constellationEventCount = new HashMap<>();
                 GnssClock gnssClock = event.getClock();
                 if (!gnssClock.hasFullBiasNanos()) {
-                    // If devices does not have FullBiasNanos yet, it will be difficult to check the quality, so await 
-                    // this flag as well.
+                    // If devices does not have FullBiasNanos yet, it will be difficult to check
+                    // the quality, so await this flag as well.
                     return;
                 }
                 for (GnssMeasurement gnssMeasurement : event.getMeasurements()){
                     int constellationType = gnssMeasurement.getConstellationType();
                     // if the measurement's signal level is too small ignore
                     if (gnssMeasurement.getCn0DbHz() < C_TO_N0_THRESHOLD_DB_HZ ||
-                        (gnssMeasurement.getState() & (1L << TOW_DECODED_MEASUREMENT_STATE_BIT)) == 0) {
+                        (gnssMeasurement.getState() & GnssMeasurement.STATE_TOW_DECODED) == 0) {
                         continue;
                     }
                     if (constellationEventCount.containsKey(constellationType)) {
diff --git a/tests/tests/location/src/android/location/cts/TestGnssStatusCallback.java b/tests/tests/location/src/android/location/cts/TestGnssStatusCallback.java
index 38b749f..76c94da 100644
--- a/tests/tests/location/src/android/location/cts/TestGnssStatusCallback.java
+++ b/tests/tests/location/src/android/location/cts/TestGnssStatusCallback.java
@@ -19,10 +19,9 @@
 import android.location.GnssStatus;
 
 import android.util.Log;
-import java.util.ArrayList;
-import java.util.List;
+import java.util.HashSet;
+import java.util.Set;
 import java.util.concurrent.CountDownLatch;
-import java.util.concurrent.TimeUnit;
 
 /**
  * Used for receiving notifications when GNSS status has changed.
@@ -30,7 +29,6 @@
 class TestGnssStatusCallback extends GnssStatus.Callback {
 
     private final String mTag;
-    private volatile boolean mGpsStatusReceived;
     private GnssStatus mGnssStatus = null;
     // Timeout in sec for count down latch wait
     private static final int TIMEOUT_IN_SEC = 90;
@@ -39,8 +37,8 @@
     private final CountDownLatch mLatchTtff;
     private final CountDownLatch mLatchStop;
 
-    // Store list of Prn for Satellites.
-    private List<List<Integer>> mGpsSatellitePrns;
+    // Store list of Satellites including Gnss Band, constellation & SvId
+    private Set<String> mGnssUsedSvStringIds;
 
     TestGnssStatusCallback(String tag, int gpsStatusCountToCollect) {
         this.mTag = tag;
@@ -48,7 +46,7 @@
         mLatchStatus = new CountDownLatch(gpsStatusCountToCollect);
         mLatchTtff = new CountDownLatch(1);
         mLatchStop = new CountDownLatch(1);
-        mGpsSatellitePrns = new ArrayList<List<Integer>>();
+        mGnssUsedSvStringIds = new HashSet<>();
     }
 
     @Override
@@ -73,32 +71,36 @@
     public void onSatelliteStatusChanged(GnssStatus status) {
         Log.i(mTag, "Gnss Status Listener Received Status Update");
         mGnssStatus = status;
+        for (int i = 0; i < status.getSatelliteCount(); i++) {
+            if (!status.usedInFix(i)) {
+                continue;
+            }
+            if (status.hasCarrierFrequencyHz(i)) {
+                mGnssUsedSvStringIds.add(
+                    TestMeasurementUtil.getUniqueSvStringId(status.getConstellationType(i),
+                        status.getSvid(i), status.getCarrierFrequencyHz(i)));
+            } else {
+                mGnssUsedSvStringIds.add(
+                    TestMeasurementUtil.getUniqueSvStringId(status.getConstellationType(i),
+                        status.getSvid(i)));
+            }
+        }
         mLatchStatus.countDown();
     }
 
     /**
-     * Returns the list of PRNs (pseudo-random number) for the satellite.
+     * Returns the list of SV String Ids which were used in fix during the collect
      *
-     * @return list of PRNs number
+     * @return mGnssUsedSvStringIds - Set of SV string Ids
      */
-    public List<List<Integer>> getGpsSatellitePrns() {
-        return mGpsSatellitePrns;
+    public Set<String> getGnssUsedSvStringIds() {
+        return mGnssUsedSvStringIds;
     }
 
     /**
-     * Check if GPS Status is received.
+     * Get GNSS Status.
      *
-     * @return {@code true} if the GPS Status is received and {@code false}
-     *         if GPS Status is not received.
-     */
-    public boolean isGpsStatusReceived() {
-        return mGpsStatusReceived;
-    }
-
-    /**
-     * Get GPS Status.
-     *
-     * @return mGpsStatus GPS Status
+     * @return mGnssStatus GNSS Status
      */
     public GnssStatus getGnssStatus() {
         return mGnssStatus;
diff --git a/tests/tests/location/src/android/location/cts/TestMeasurementUtil.java b/tests/tests/location/src/android/location/cts/TestMeasurementUtil.java
index c2541d3..7852361 100644
--- a/tests/tests/location/src/android/location/cts/TestMeasurementUtil.java
+++ b/tests/tests/location/src/android/location/cts/TestMeasurementUtil.java
@@ -57,6 +57,13 @@
     private static final int YEAR_2017 = 2017;
     private static final int YEAR_2018 = 2018;
 
+    private enum GnssBand {
+        GNSS_L1,
+        GNSS_L2,
+        GNSS_L5,
+        GNSS_E6
+    }
+
     // The valid Gnss navigation message type as listed in
     // android/hardware/libhardware/include/hardware/gps.h
     public static final Set<Integer> GNSS_NAVIGATION_MESSAGE_TYPE =
@@ -334,7 +341,6 @@
     private static void verifySvid(GnssMeasurement measurement, SoftAssert softAssert,
         long timeInNs) {
 
-        String svidLogMessageFormat = "svid: Space Vehicle ID. Constellation type = %s";
         int constellationType = measurement.getConstellationType();
         int svid = measurement.getSvid();
         validateSvidSub(softAssert, timeInNs, constellationType, svid);
@@ -637,7 +643,7 @@
         }
     }
 
-    private static String getReceivedSvTimeNsLogMessage(String constellationType, String state) {
+    private static String getReceivedSvTimeNsLogMessage(String state, String constellationType) {
         return "received_sv_time_ns: Received SV Time-of-Week in ns. Constellation type = "
                 + constellationType + ". State = " + state;
     }
@@ -700,6 +706,34 @@
         }
     }
 
+
+    /**
+     * Get a unique string for the SV including the constellation and the default L1 band.
+     *
+     * @param constellationType Gnss Constellation type
+     * @param svId Gnss Sv Identifier
+     */
+    public static String getUniqueSvStringId(int constellationType, int svId) {
+        return getUniqueSvStringId(constellationType, svId, GnssBand.GNSS_L1);
+    }
+
+    /**
+     * Get a unique string for the SV including the constellation and the band.
+     *
+     * @param constellationType Gnss Constellation type
+     * @param svId Gnss Sv Identifier
+     * @param carrierFrequencyHz Carrier Frequency for Sv in Hz
+     */
+    public static String getUniqueSvStringId(int constellationType, int svId,
+        float carrierFrequencyHz) {
+        return getUniqueSvStringId(constellationType, svId,
+            frequencyToGnssBand(carrierFrequencyHz));
+    }
+
+    private static String getUniqueSvStringId(int constellationType, int svId, GnssBand gnssBand) {
+        return gnssBand.toString() + "." + constellationType + "." + svId;
+    }
+
     /**
      * Assert all mandatory fields in Gnss Navigation Message are in expected range.
      * See mandatory fields in {@code gps.h}.
@@ -788,4 +822,25 @@
 
         return typesStr.length() > 2 ? typesStr.substring(0, typesStr.length() - 2) : "";
     }
+
+    /**
+     * The band information is as of 2018, per http://www.navipedia.net/index.php/GNSS_signal
+     * Bands are combined for simplicity as the constellation is also tracked.
+     *
+     * @param frequencyHz Frequency in Hz
+     * @return GnssBand where the frequency lies.
+     */
+    private static GnssBand frequencyToGnssBand(float frequencyHz) {
+        float frequencyMhz = frequencyHz/1e6F;
+        if (frequencyMhz >= 1151 && frequencyMhz <= 1214) {
+            return GnssBand.GNSS_L5;
+        }
+        if (frequencyMhz > 1214 && frequencyMhz <= 1255) {
+            return GnssBand.GNSS_L2;
+        }
+        if (frequencyMhz > 1255 && frequencyMhz <= 1300) {
+            return GnssBand.GNSS_E6;
+        }
+        return GnssBand.GNSS_L1; // default to L1 band
+    }
 }
diff --git a/tests/tests/media/src/android/media/cts/MediaPlayer2Test.java b/tests/tests/media/src/android/media/cts/MediaPlayer2Test.java
index 6217df4..a55588b 100644
--- a/tests/tests/media/src/android/media/cts/MediaPlayer2Test.java
+++ b/tests/tests/media/src/android/media/cts/MediaPlayer2Test.java
@@ -136,7 +136,7 @@
                 .build());
         Monitor onPrepareCalled = new Monitor();
         Monitor onErrorCalled = new Monitor();
-        MediaPlayer2.MediaPlayer2EventCallback ecb = new MediaPlayer2.MediaPlayer2EventCallback() {
+        MediaPlayer2.EventCallback ecb = new MediaPlayer2.EventCallback() {
             @Override
             public void onInfo(MediaPlayer2 mp, DataSourceDesc dsd, int what, int extra) {
                 if (what == MediaPlayer2.MEDIA_INFO_PREPARED) {
@@ -149,11 +149,11 @@
                 onErrorCalled.signal();
             }
         };
-        mp2.setMediaPlayer2EventCallback(mExecutor, ecb);
+        mp2.setEventCallback(mExecutor, ecb);
         mp2.prepare();
         onPrepareCalled.waitForSignal();
         afd2.close();
-        mp2.clearMediaPlayer2EventCallback();
+        mp2.clearEventCallback();
 
         mp2.loopCurrent(true);
         mp2.play();
@@ -165,7 +165,7 @@
                         .setDataSource(afd.getFileDescriptor(), afd.getStartOffset(),
                             afd.getLength())
                         .build());
-                mp.setMediaPlayer2EventCallback(mExecutor, ecb);
+                mp.setEventCallback(mExecutor, ecb);
                 onPrepareCalled.reset();
                 mp.prepare();
                 onErrorCalled.waitForSignal();
@@ -185,7 +185,7 @@
             return;
         }
         Monitor onSetDataSourceCalled = new Monitor();
-        MediaPlayer2.MediaPlayer2EventCallback ecb = new MediaPlayer2.MediaPlayer2EventCallback() {
+        MediaPlayer2.EventCallback ecb = new MediaPlayer2.EventCallback() {
             @Override
             public void onCallCompleted(MediaPlayer2 mp, DataSourceDesc dsd, int what, int status) {
                 if (what == MediaPlayer2.CALL_COMPLETED_SET_DATA_SOURCE) {
@@ -228,7 +228,7 @@
         Monitor onPlayCalled = new Monitor();
         Monitor onSeekToCalled = new Monitor();
         Monitor onLoopCurrentCalled = new Monitor();
-        MediaPlayer2.MediaPlayer2EventCallback ecb = new MediaPlayer2.MediaPlayer2EventCallback() {
+        MediaPlayer2.EventCallback ecb = new MediaPlayer2.EventCallback() {
             @Override
             public void onInfo(MediaPlayer2 mp, DataSourceDesc dsd, int what, int extra) {
                 if (what == MediaPlayer2.MEDIA_INFO_PREPARED) {
@@ -247,7 +247,7 @@
                 }
             }
         };
-        mp.setMediaPlayer2EventCallback(mExecutor, ecb);
+        mp.setEventCallback(mExecutor, ecb);
 
         try {
             AudioAttributes attributes = new AudioAttributes.Builder()
@@ -289,7 +289,7 @@
 
             // test stop and restart
             mp.reset();
-            mp.setMediaPlayer2EventCallback(mExecutor, ecb);
+            mp.setEventCallback(mExecutor, ecb);
             mp.setDataSource(new DataSourceDesc.Builder()
                     .setDataSource(mContext, uri)
                     .build());
@@ -327,7 +327,7 @@
         Monitor onPlayCalled = new Monitor();
         Monitor onSeekToCalled = new Monitor();
         Monitor onLoopCurrentCalled = new Monitor();
-        MediaPlayer2.MediaPlayer2EventCallback ecb = new MediaPlayer2.MediaPlayer2EventCallback() {
+        MediaPlayer2.EventCallback ecb = new MediaPlayer2.EventCallback() {
             @Override
             public void onInfo(MediaPlayer2 mp, DataSourceDesc dsd, int what, int extra) {
                 if (what == MediaPlayer2.MEDIA_INFO_PREPARED) {
@@ -346,7 +346,7 @@
                 }
             }
         };
-        mp.setMediaPlayer2EventCallback(mExecutor, ecb);
+        mp.setEventCallback(mExecutor, ecb);
 
         try {
             AudioAttributes attributes = new AudioAttributes.Builder()
@@ -393,7 +393,7 @@
                     .setDataSource(afd.getFileDescriptor(), afd.getStartOffset(), afd.getLength())
                     .build());
 
-            mp.setMediaPlayer2EventCallback(mExecutor, ecb);
+            mp.setEventCallback(mExecutor, ecb);
             onPrepareCalled.reset();
             mp.prepare();
             onPrepareCalled.waitForSignal();
@@ -428,8 +428,8 @@
             for (MediaPlayer2 mp : mps) {
                 Monitor onPlayCalled = new Monitor();
                 Monitor onLoopCurrentCalled = new Monitor();
-                MediaPlayer2.MediaPlayer2EventCallback ecb =
-                    new MediaPlayer2.MediaPlayer2EventCallback() {
+                MediaPlayer2.EventCallback ecb =
+                    new MediaPlayer2.EventCallback() {
                         @Override
                         public void onCallCompleted(MediaPlayer2 mp, DataSourceDesc dsd,
                                 int what, int status) {
@@ -440,7 +440,7 @@
                             }
                         }
                     };
-                mp.setMediaPlayer2EventCallback(mExecutor, ecb);
+                mp.setEventCallback(mExecutor, ecb);
 
                 AudioAttributes attributes = new AudioAttributes.Builder()
                         .setInternalLegacyStreamType(AudioManager.STREAM_MUSIC)
@@ -492,8 +492,8 @@
             mp.loopCurrent(true);
             Monitor onCompletionCalled = new Monitor();
             Monitor onPlayCalled = new Monitor();
-            MediaPlayer2.MediaPlayer2EventCallback ecb =
-                new MediaPlayer2.MediaPlayer2EventCallback() {
+            MediaPlayer2.EventCallback ecb =
+                new MediaPlayer2.EventCallback() {
                     @Override
                     public void onInfo(MediaPlayer2 mp, DataSourceDesc dsd,
                             int what, int extra) {
@@ -509,7 +509,7 @@
                         }
                     }
                 };
-            mp.setMediaPlayer2EventCallback(mExecutor, ecb);
+            mp.setEventCallback(mExecutor, ecb);
 
             assertFalse(mp.isPlaying());
             onPlayCalled.reset();
@@ -549,8 +549,8 @@
         Monitor onPrepareCalled = new Monitor();
         Monitor onSeekToCalled = new Monitor();
         Monitor onLoopCurrentCalled = new Monitor();
-        MediaPlayer2.MediaPlayer2EventCallback ecb =
-            new MediaPlayer2.MediaPlayer2EventCallback() {
+        MediaPlayer2.EventCallback ecb =
+            new MediaPlayer2.EventCallback() {
                 @Override
                 public void onInfo(MediaPlayer2 mp, DataSourceDesc dsd, int what, int extra) {
                     if (what == MediaPlayer2.MEDIA_INFO_PREPARED) {
@@ -568,7 +568,7 @@
                     }
                 }
             };
-        mp.setMediaPlayer2EventCallback(mExecutor, ecb);
+        mp.setEventCallback(mExecutor, ecb);
 
         try {
             AudioAttributes attributes = new AudioAttributes.Builder()
@@ -602,7 +602,7 @@
                     .setDataSource(afd.getFileDescriptor(), afd.getStartOffset(), afd.getLength())
                     .build());
 
-            mp.setMediaPlayer2EventCallback(mExecutor, ecb);
+            mp.setEventCallback(mExecutor, ecb);
             onPrepareCalled.reset();
             mp.prepare();
             onPrepareCalled.waitForSignal();
@@ -736,7 +736,7 @@
 
         final CountDownLatch seekDone = new CountDownLatch(1);
 
-        MediaPlayer2.MediaPlayer2EventCallback ecb = new MediaPlayer2.MediaPlayer2EventCallback() {
+        MediaPlayer2.EventCallback ecb = new MediaPlayer2.EventCallback() {
             @Override
             public void onCallCompleted(MediaPlayer2 mp, DataSourceDesc dsd, int what, int status) {
                 if (what == MediaPlayer2.CALL_COMPLETED_SEEK_TO) {
@@ -936,7 +936,7 @@
 
         Monitor onCompletion1Called = new Monitor();
         Monitor onCompletion2Called = new Monitor();
-        MediaPlayer2.MediaPlayer2EventCallback ecb = new MediaPlayer2.MediaPlayer2EventCallback() {
+        MediaPlayer2.EventCallback ecb = new MediaPlayer2.EventCallback() {
             @Override
             public void onInfo(MediaPlayer2 mp, DataSourceDesc dsd, int what, int extra) {
                 if (what == MediaPlayer2.MEDIA_INFO_PREPARED) {
@@ -986,7 +986,7 @@
             return; // skip
         }
 
-        MediaPlayer2.MediaPlayer2EventCallback ecb = new MediaPlayer2.MediaPlayer2EventCallback() {
+        MediaPlayer2.EventCallback ecb = new MediaPlayer2.EventCallback() {
             @Override
             public void onInfo(MediaPlayer2 mp, DataSourceDesc dsd, int what, int extra) {
                 if (what == MediaPlayer2.MEDIA_INFO_PREPARED) {
@@ -1057,7 +1057,7 @@
             return; // skip
         }
 
-        MediaPlayer2.MediaPlayer2EventCallback ecb = new MediaPlayer2.MediaPlayer2EventCallback() {
+        MediaPlayer2.EventCallback ecb = new MediaPlayer2.EventCallback() {
             @Override
             public void onInfo(MediaPlayer2 mp, DataSourceDesc dsd, int what, int extra) {
                 if (what == MediaPlayer2.MEDIA_INFO_PREPARED) {
@@ -1116,7 +1116,7 @@
             return; // skip
         }
 
-        MediaPlayer2.MediaPlayer2EventCallback ecb = new MediaPlayer2.MediaPlayer2EventCallback() {
+        MediaPlayer2.EventCallback ecb = new MediaPlayer2.EventCallback() {
             @Override
             public void onInfo(MediaPlayer2 mp, DataSourceDesc dsd, int what, int extra) {
                 if (what == MediaPlayer2.MEDIA_INFO_PREPARED) {
@@ -1212,7 +1212,7 @@
         }
 
         Monitor onPauseCalled = new Monitor();
-        MediaPlayer2.MediaPlayer2EventCallback ecb = new MediaPlayer2.MediaPlayer2EventCallback() {
+        MediaPlayer2.EventCallback ecb = new MediaPlayer2.EventCallback() {
             @Override
             public void onInfo(MediaPlayer2 mp, DataSourceDesc dsd, int what, int extra) {
                 if (what == MediaPlayer2.MEDIA_INFO_PREPARED) {
@@ -1618,7 +1618,7 @@
 
         getInstrumentation().waitForIdleSync();
 
-        MediaPlayer2.MediaPlayer2EventCallback ecb = new MediaPlayer2.MediaPlayer2EventCallback() {
+        MediaPlayer2.EventCallback ecb = new MediaPlayer2.EventCallback() {
             @Override
             public void onInfo(MediaPlayer2 mp, DataSourceDesc dsd, int what, int extra) {
                 if (what == MediaPlayer2.MEDIA_INFO_PREPARED) {
@@ -1713,7 +1713,7 @@
             }
         });
 
-        MediaPlayer2.MediaPlayer2EventCallback ecb = new MediaPlayer2.MediaPlayer2EventCallback() {
+        MediaPlayer2.EventCallback ecb = new MediaPlayer2.EventCallback() {
             @Override
             public void onInfo(MediaPlayer2 mp, DataSourceDesc dsd, int what, int extra) {
                 if (what == MediaPlayer2.MEDIA_INFO_PREPARED) {
@@ -1777,7 +1777,7 @@
 
         getInstrumentation().waitForIdleSync();
 
-        MediaPlayer2.MediaPlayer2EventCallback ecb = new MediaPlayer2.MediaPlayer2EventCallback() {
+        MediaPlayer2.EventCallback ecb = new MediaPlayer2.EventCallback() {
             @Override
             public void onInfo(MediaPlayer2 mp, DataSourceDesc dsd, int what, int extra) {
                 if (what == MediaPlayer2.MEDIA_INFO_PREPARED) {
@@ -1854,7 +1854,7 @@
             return 0; // skip
         }
         mOnCompletionCalled.reset();
-        MediaPlayer2.MediaPlayer2EventCallback ecb = new MediaPlayer2.MediaPlayer2EventCallback() {
+        MediaPlayer2.EventCallback ecb = new MediaPlayer2.EventCallback() {
             @Override
             public void onInfo(MediaPlayer2 mp, DataSourceDesc dsd, int what, int extra) {
                 if (what == MediaPlayer2.MEDIA_INFO_PREPARED) {
@@ -1865,7 +1865,7 @@
                 }
             }
         };
-        mPlayer.setMediaPlayer2EventCallback(mExecutor, ecb);
+        mPlayer.setEventCallback(mExecutor, ecb);
 
         mOnPrepareCalled.reset();
         mPlayer.prepare();
@@ -1912,7 +1912,7 @@
         mPlayer.setAudioAttributes(attributes);
 
         mOnCompletionCalled.reset();
-        MediaPlayer2.MediaPlayer2EventCallback ecb = new MediaPlayer2.MediaPlayer2EventCallback() {
+        MediaPlayer2.EventCallback ecb = new MediaPlayer2.EventCallback() {
             @Override
             public void onInfo(MediaPlayer2 mp, DataSourceDesc dsd, int what, int extra) {
                 if (what == MediaPlayer2.MEDIA_INFO_PREPARED) {
@@ -1929,7 +1929,7 @@
                 }
             }
         };
-        mPlayer.setMediaPlayer2EventCallback(mExecutor, ecb);
+        mPlayer.setEventCallback(mExecutor, ecb);
 
         mOnPrepareCalled.reset();
         mPlayer.prepare();
@@ -1965,7 +1965,7 @@
         mPlayer.setScreenOnWhilePlaying(true);
 
         mOnCompletionCalled.reset();
-        MediaPlayer2.MediaPlayer2EventCallback ecb = new MediaPlayer2.MediaPlayer2EventCallback() {
+        MediaPlayer2.EventCallback ecb = new MediaPlayer2.EventCallback() {
             @Override
             public void onVideoSizeChanged(MediaPlayer2 mp, DataSourceDesc dsd,
                     int width, int height) {
@@ -2131,7 +2131,7 @@
         Thread.sleep(SLEEP_TIME);
         assertFalse(mPlayer.isPlaying());
 
-        MediaPlayer2.MediaPlayer2EventCallback ecb = new MediaPlayer2.MediaPlayer2EventCallback() {
+        MediaPlayer2.EventCallback ecb = new MediaPlayer2.EventCallback() {
             @Override
             public void onInfo(MediaPlayer2 mp, DataSourceDesc dsd, int what, int extra) {
                 if (what == MediaPlayer2.MEDIA_INFO_PREPARED) {
@@ -2146,7 +2146,7 @@
                 }
             }
         };
-        mPlayer.setMediaPlayer2EventCallback(mExecutor, ecb);
+        mPlayer.setEventCallback(mExecutor, ecb);
 
         mOnPlayCalled.reset();
         mPlayer.play();
@@ -2159,7 +2159,7 @@
                 .setDataSource(dataSource)
                 .build());
 
-        mPlayer.setMediaPlayer2EventCallback(mExecutor, ecb);
+        mPlayer.setEventCallback(mExecutor, ecb);
 
         mOnPrepareCalled.reset();
         mPlayer.prepare();
@@ -2182,7 +2182,7 @@
         if (IGNORE_TESTS) {
             return;
         }
-        MediaPlayer2.MediaPlayer2EventCallback ecb = new MediaPlayer2.MediaPlayer2EventCallback() {
+        MediaPlayer2.EventCallback ecb = new MediaPlayer2.EventCallback() {
             @Override
             public void onCallCompleted(MediaPlayer2 mp, DataSourceDesc dsd, int what, int status) {
                 if (what == MediaPlayer2.CALL_COMPLETED_SET_DATA_SOURCE) {
@@ -2191,7 +2191,7 @@
                 }
             }
         };
-        mPlayer.setMediaPlayer2EventCallback(mExecutor, ecb);
+        mPlayer.setEventCallback(mExecutor, ecb);
 
         mCallStatus = MediaPlayer2.CALL_STATUS_NO_ERROR;
         mPlayer.setDataSource((DataSourceDesc)null);
@@ -2203,7 +2203,7 @@
         if (IGNORE_TESTS) {
             return;
         }
-        MediaPlayer2.MediaPlayer2EventCallback ecb = new MediaPlayer2.MediaPlayer2EventCallback() {
+        MediaPlayer2.EventCallback ecb = new MediaPlayer2.EventCallback() {
             @Override
             public void onCallCompleted(MediaPlayer2 mp, DataSourceDesc dsd, int what, int status) {
                 if (what == MediaPlayer2.CALL_COMPLETED_SET_DATA_SOURCE) {
@@ -2212,7 +2212,7 @@
                 }
             }
         };
-        mPlayer.setMediaPlayer2EventCallback(mExecutor, ecb);
+        mPlayer.setEventCallback(mExecutor, ecb);
 
         TestMedia2DataSource dataSource = new TestMedia2DataSource(new byte[0]);
         mPlayer.setDataSource(new DataSourceDesc.Builder()
@@ -2239,7 +2239,7 @@
                 .setDataSource(dataSource)
                 .build());
 
-        MediaPlayer2.MediaPlayer2EventCallback ecb = new MediaPlayer2.MediaPlayer2EventCallback() {
+        MediaPlayer2.EventCallback ecb = new MediaPlayer2.EventCallback() {
             @Override
             public void onInfo(MediaPlayer2 mp, DataSourceDesc dsd, int what, int extra) {
                 if (what == MediaPlayer2.MEDIA_INFO_PREPARED) {
@@ -2276,7 +2276,7 @@
                 .build());
 
         setOnErrorListener();
-        MediaPlayer2.MediaPlayer2EventCallback ecb = new MediaPlayer2.MediaPlayer2EventCallback() {
+        MediaPlayer2.EventCallback ecb = new MediaPlayer2.EventCallback() {
             @Override
             public void onInfo(MediaPlayer2 mp, DataSourceDesc dsd, int what, int extra) {
                 if (what == MediaPlayer2.MEDIA_INFO_PREPARED) {
diff --git a/tests/tests/media/src/android/media/cts/MediaPlayer2TestBase.java b/tests/tests/media/src/android/media/cts/MediaPlayer2TestBase.java
index 2975d47..b9245a0 100644
--- a/tests/tests/media/src/android/media/cts/MediaPlayer2TestBase.java
+++ b/tests/tests/media/src/android/media/cts/MediaPlayer2TestBase.java
@@ -77,11 +77,11 @@
     protected MediaStubActivity mActivity;
 
     protected final Object mEventCbLock = new Object();
-    protected List<MediaPlayer2.MediaPlayer2EventCallback> mEventCallbacks =
-            new ArrayList<MediaPlayer2.MediaPlayer2EventCallback>();
+    protected List<MediaPlayer2.EventCallback> mEventCallbacks =
+            new ArrayList<MediaPlayer2.EventCallback>();
     protected final Object mEventCbLock2 = new Object();
-    protected List<MediaPlayer2.MediaPlayer2EventCallback> mEventCallbacks2 =
-            new ArrayList<MediaPlayer2.MediaPlayer2EventCallback>();
+    protected List<MediaPlayer2.EventCallback> mEventCallbacks2 =
+            new ArrayList<MediaPlayer2.EventCallback>();
 
     // convenience functions to create MediaPlayer2
     protected static MediaPlayer2 createMediaPlayer2(Context context, Uri uri) {
@@ -111,8 +111,8 @@
             }
             Monitor onPrepareCalled = new Monitor();
             ExecutorService executor = Executors.newFixedThreadPool(1);
-            MediaPlayer2.MediaPlayer2EventCallback ecb =
-                new MediaPlayer2.MediaPlayer2EventCallback() {
+            MediaPlayer2.EventCallback ecb =
+                new MediaPlayer2.EventCallback() {
                     @Override
                     public void onInfo(MediaPlayer2 mp, DataSourceDesc dsd, int what, int extra) {
                         if (what == MediaPlayer2.MEDIA_INFO_PREPARED) {
@@ -120,10 +120,10 @@
                         }
                     }
                 };
-            mp.setMediaPlayer2EventCallback(executor, ecb);
+            mp.setEventCallback(executor, ecb);
             mp.prepare();
             onPrepareCalled.waitForSignal();
-            mp.clearMediaPlayer2EventCallback();
+            mp.clearEventCallback();
             executor.shutdown();
             return mp;
         } catch (IllegalArgumentException ex) {
@@ -166,8 +166,8 @@
 
             Monitor onPrepareCalled = new Monitor();
             ExecutorService executor = Executors.newFixedThreadPool(1);
-            MediaPlayer2.MediaPlayer2EventCallback ecb =
-                new MediaPlayer2.MediaPlayer2EventCallback() {
+            MediaPlayer2.EventCallback ecb =
+                new MediaPlayer2.EventCallback() {
                     @Override
                     public void onInfo(MediaPlayer2 mp, DataSourceDesc dsd, int what, int extra) {
                         if (what == MediaPlayer2.MEDIA_INFO_PREPARED) {
@@ -175,10 +175,10 @@
                         }
                     }
                 };
-            mp.setMediaPlayer2EventCallback(executor, ecb);
+            mp.setEventCallback(executor, ecb);
             mp.prepare();
             onPrepareCalled.waitForSignal();
-            mp.clearMediaPlayer2EventCallback();
+            mp.clearEventCallback();
             afd.close();
             executor.shutdown();
             return mp;
@@ -242,12 +242,12 @@
     }
 
     protected void setUpMP2ECb(MediaPlayer2 mp, Object cbLock,
-            List<MediaPlayer2.MediaPlayer2EventCallback> ecbs) {
-        mp.setMediaPlayer2EventCallback(mExecutor, new MediaPlayer2.MediaPlayer2EventCallback() {
+            List<MediaPlayer2.EventCallback> ecbs) {
+        mp.setEventCallback(mExecutor, new MediaPlayer2.EventCallback() {
             @Override
             public void onVideoSizeChanged(MediaPlayer2 mp, DataSourceDesc dsd, int w, int h) {
                 synchronized (cbLock) {
-                    for (MediaPlayer2.MediaPlayer2EventCallback ecb : ecbs) {
+                    for (MediaPlayer2.EventCallback ecb : ecbs) {
                         ecb.onVideoSizeChanged(mp, dsd, w, h);
                     }
                 }
@@ -256,7 +256,7 @@
             @Override
             public void onTimedText(MediaPlayer2 mp, DataSourceDesc dsd, TimedText text) {
                 synchronized (cbLock) {
-                    for (MediaPlayer2.MediaPlayer2EventCallback ecb : ecbs) {
+                    for (MediaPlayer2.EventCallback ecb : ecbs) {
                         ecb.onTimedText(mp, dsd, text);
                     }
                 }
@@ -266,7 +266,7 @@
             public void onTimedMetaDataAvailable(MediaPlayer2 mp, DataSourceDesc dsd,
                     TimedMetaData data) {
                 synchronized (cbLock) {
-                    for (MediaPlayer2.MediaPlayer2EventCallback ecb : ecbs) {
+                    for (MediaPlayer2.EventCallback ecb : ecbs) {
                         ecb.onTimedMetaDataAvailable(mp, dsd, data);
                     }
                 }
@@ -275,7 +275,7 @@
             @Override
             public void onError(MediaPlayer2 mp, DataSourceDesc dsd, int what, int extra) {
                 synchronized (cbLock) {
-                    for (MediaPlayer2.MediaPlayer2EventCallback ecb : ecbs) {
+                    for (MediaPlayer2.EventCallback ecb : ecbs) {
                         ecb.onError(mp, dsd, what, extra);
                     }
                 }
@@ -284,7 +284,7 @@
             @Override
             public void onInfo(MediaPlayer2 mp, DataSourceDesc dsd, int what, int extra) {
                 synchronized (cbLock) {
-                    for (MediaPlayer2.MediaPlayer2EventCallback ecb : ecbs) {
+                    for (MediaPlayer2.EventCallback ecb : ecbs) {
                         ecb.onInfo(mp, dsd, what, extra);
                     }
                 }
@@ -293,7 +293,7 @@
             @Override
             public void onCallCompleted(MediaPlayer2 mp, DataSourceDesc dsd, int what, int status) {
                 synchronized (cbLock) {
-                    for (MediaPlayer2.MediaPlayer2EventCallback ecb : ecbs) {
+                    for (MediaPlayer2.EventCallback ecb : ecbs) {
                         ecb.onCallCompleted(mp, dsd, what, status);
                     }
                 }
@@ -303,7 +303,7 @@
             public void onMediaTimeChanged(MediaPlayer2 mp, DataSourceDesc dsd,
                     MediaTimestamp timestamp) {
                 synchronized (cbLock) {
-                    for (MediaPlayer2.MediaPlayer2EventCallback ecb : ecbs) {
+                    for (MediaPlayer2.EventCallback ecb : ecbs) {
                         ecb.onMediaTimeChanged(mp, dsd, timestamp);
                     }
                 }
@@ -312,7 +312,7 @@
             @Override
             public void onCommandLabelReached(MediaPlayer2 mp, Object label) {
                 synchronized (cbLock) {
-                    for (MediaPlayer2.MediaPlayer2EventCallback ecb : ecbs) {
+                    for (MediaPlayer2.EventCallback ecb : ecbs) {
                         ecb.onCommandLabelReached(mp, label);
                     }
                 }
@@ -462,7 +462,7 @@
         mPlayer.setScreenOnWhilePlaying(true);
 
         synchronized (mEventCbLock) {
-            mEventCallbacks.add(new MediaPlayer2.MediaPlayer2EventCallback() {
+            mEventCallbacks.add(new MediaPlayer2.EventCallback() {
                 @Override
                 public void onVideoSizeChanged(MediaPlayer2 mp, DataSourceDesc dsd, int w, int h) {
                     if (w == 0 && h == 0) {
@@ -585,7 +585,7 @@
 
     protected void setOnErrorListener() {
         synchronized (mEventCbLock) {
-            mEventCallbacks.add(new MediaPlayer2.MediaPlayer2EventCallback() {
+            mEventCallbacks.add(new MediaPlayer2.EventCallback() {
                 @Override
                 public void onError(MediaPlayer2 mp, DataSourceDesc dsd, int what, int extra) {
                     mOnErrorCalled.signal();
diff --git a/tests/tests/media/src/android/media/cts/StreamingMediaPlayer2Test.java b/tests/tests/media/src/android/media/cts/StreamingMediaPlayer2Test.java
index c1769ac..fe48975 100644
--- a/tests/tests/media/src/android/media/cts/StreamingMediaPlayer2Test.java
+++ b/tests/tests/media/src/android/media/cts/StreamingMediaPlayer2Test.java
@@ -364,8 +364,8 @@
             mPlayer.setScreenOnWhilePlaying(true);
 
             mOnBufferingUpdateCalled.reset();
-            MediaPlayer2.MediaPlayer2EventCallback ecb =
-                new MediaPlayer2.MediaPlayer2EventCallback() {
+            MediaPlayer2.EventCallback ecb =
+                new MediaPlayer2.EventCallback() {
                     @Override
                     public void onError(MediaPlayer2 mp, DataSourceDesc dsd, int what, int extra) {
                         fail("Media player had error " + what + " playing " + name);
@@ -380,7 +380,7 @@
                         }
                     }
                 };
-            mPlayer.setMediaPlayer2EventCallback(mExecutor, ecb);
+            mPlayer.setEventCallback(mExecutor, ecb);
 
             assertFalse(mOnBufferingUpdateCalled.isSignalled());
 
@@ -428,8 +428,8 @@
 
             mOnBufferingUpdateCalled.reset();
 
-            MediaPlayer2.MediaPlayer2EventCallback ecb =
-                new MediaPlayer2.MediaPlayer2EventCallback() {
+            MediaPlayer2.EventCallback ecb =
+                new MediaPlayer2.EventCallback() {
                     @Override
                     public void onError(MediaPlayer2 mp, DataSourceDesc dsd, int what, int extra) {
                         mOnErrorCalled.signal();
@@ -444,7 +444,7 @@
                         }
                     }
                 };
-            mPlayer.setMediaPlayer2EventCallback(mExecutor, ecb);
+            mPlayer.setEventCallback(mExecutor, ecb);
 
             assertFalse(mOnBufferingUpdateCalled.isSignalled());
             try {
@@ -471,8 +471,8 @@
             }
 
             Monitor onSetBufferingParamsCalled = new Monitor();
-            MediaPlayer2.MediaPlayer2EventCallback ecb =
-                new MediaPlayer2.MediaPlayer2EventCallback() {
+            MediaPlayer2.EventCallback ecb =
+                new MediaPlayer2.EventCallback() {
                     @Override
                     public void onError(MediaPlayer2 mp, DataSourceDesc dsd, int what, int extra) {
                         fail("Media player had error " + what + " playing " + name);
@@ -492,7 +492,7 @@
                         }
                     }
                 };
-            mPlayer.setMediaPlayer2EventCallback(mExecutor, ecb);
+            mPlayer.setEventCallback(mExecutor, ecb);
 
             // getBufferingParams should be called after setDataSource.
             try {
@@ -602,8 +602,8 @@
             mPlayer.setWakeMode(mContext, PowerManager.PARTIAL_WAKE_LOCK);
 
             final Object completion = new Object();
-            MediaPlayer2.MediaPlayer2EventCallback ecb =
-                new MediaPlayer2.MediaPlayer2EventCallback() {
+            MediaPlayer2.EventCallback ecb =
+                new MediaPlayer2.EventCallback() {
                     int run;
                     @Override
                     public void onInfo(MediaPlayer2 mp, DataSourceDesc dsd, int what, int extra) {
@@ -662,7 +662,7 @@
                     }
                 }
             };
-            mPlayer.setMediaPlayer2EventCallback(mExecutor, ecb);
+            mPlayer.setEventCallback(mExecutor, ecb);
 
             mPlayer.prepare();
             mOnPrepareCalled.waitForSignal();
@@ -757,8 +757,8 @@
                     .setDataSource(mContext, uri)
                     .build());
 
-            MediaPlayer2.MediaPlayer2EventCallback ecb =
-                new MediaPlayer2.MediaPlayer2EventCallback() {
+            MediaPlayer2.EventCallback ecb =
+                new MediaPlayer2.EventCallback() {
                     @Override
                     public void onInfo(MediaPlayer2 mp, DataSourceDesc dsd, int what, int extra) {
                         if (what == MediaPlayer2.MEDIA_INFO_PREPARED) {
@@ -766,7 +766,7 @@
                         }
                     }
                 };
-            mp.setMediaPlayer2EventCallback(mExecutor, ecb);
+            mp.setEventCallback(mExecutor, ecb);
 
             mp.prepare();
             Thread.sleep(1000);
diff --git a/tests/tests/nativehardware/jni/AHardwareBufferGLTest.cpp b/tests/tests/nativehardware/jni/AHardwareBufferGLTest.cpp
index 3ef70d8..29ae91a 100644
--- a/tests/tests/nativehardware/jni/AHardwareBufferGLTest.cpp
+++ b/tests/tests/nativehardware/jni/AHardwareBufferGLTest.cpp
@@ -932,6 +932,10 @@
             glEGLImageTargetTexture2DOES(mTexTarget, static_cast<GLeglImageOES>(mEGLImage));
         }
     }
+    // If the texture does not have mipmaps, set the max level accordingly.
+    if (!(desc.usage & AHARDWAREBUFFER_USAGE_GPU_MIPMAP_COMPLETE)) {
+        glTexParameteri(mTexTarget, GL_TEXTURE_MAX_LEVEL, 0);
+    }
     ASSERT_EQ(GLenum{GL_NO_ERROR}, glGetError());
 }
 
diff --git a/tests/tests/net/src/android/net/wifi/rtt/cts/WifiRttTest.java b/tests/tests/net/src/android/net/wifi/rtt/cts/WifiRttTest.java
index 1171a6b..74a0c3d 100644
--- a/tests/tests/net/src/android/net/wifi/rtt/cts/WifiRttTest.java
+++ b/tests/tests/net/src/android/net/wifi/rtt/cts/WifiRttTest.java
@@ -157,7 +157,8 @@
         reportLog.submit();
 
         // Analyze results
-        assertTrue("Wi-Fi RTT failure rate exceeds threshold",
+        assertTrue("Wi-Fi RTT failure rate exceeds threshold: FAIL=" + numFailures + ", ITERATIONS="
+                        + NUM_OF_RTT_ITERATIONS,
                 numFailures <= NUM_OF_RTT_ITERATIONS * MAX_FAILURE_RATE_PERCENT / 100);
         if (numFailures != NUM_OF_RTT_ITERATIONS) {
             double distanceAvg = distanceSum / (NUM_OF_RTT_ITERATIONS - numFailures);
diff --git a/tests/tests/permission/src/android/permission/cts/BackgroundPermissionsTest.java b/tests/tests/permission/src/android/permission/cts/BackgroundPermissionsTest.java
new file mode 100644
index 0000000..8e1484b
--- /dev/null
+++ b/tests/tests/permission/src/android/permission/cts/BackgroundPermissionsTest.java
@@ -0,0 +1,86 @@
+/*
+ * 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.content.pm.PermissionInfo.PROTECTION_DANGEROUS;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+
+import android.app.AppOpsManager;
+import android.content.pm.PackageInfo;
+import android.content.pm.PackageManager;
+import android.content.pm.PermissionInfo;
+import android.platform.test.annotations.AppModeFull;
+import android.support.test.InstrumentationRegistry;
+import android.support.test.runner.AndroidJUnit4;
+import android.util.Log;
+import android.util.ArrayMap;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+@RunWith(AndroidJUnit4.class)
+public class BackgroundPermissionsTest {
+    private static final String LOG_TAG = BackgroundPermissionsTest.class.getSimpleName();
+
+    @Test
+    @AppModeFull(reason = "Instant apps cannot read properties of other packages")
+    public void backgroundPermissionsNeedToBeInSameGroupAsForegroundPermissions() throws Exception {
+        PackageInfo pkg = InstrumentationRegistry.getContext().getPackageManager().getPackageInfo(
+                "android", PackageManager.GET_PERMISSIONS);
+        ArrayMap<String, String> potentialBackgroundPermissionsToGroup = new ArrayMap<>();
+
+        int numPermissions = pkg.permissions.length;
+        for (int i = 0; i < numPermissions; i++) {
+            PermissionInfo permission = pkg.permissions[i];
+
+            // background permissions must be dangerous
+            if ((permission.getProtection() & PROTECTION_DANGEROUS) != 0) {
+                potentialBackgroundPermissionsToGroup.put(permission.name, permission.group);
+            }
+        }
+
+        for (int i = 0; i < numPermissions; i++) {
+            PermissionInfo permission = pkg.permissions[i];
+            String backgroundPermissionName = permission.backgroundPermission;
+
+            if (backgroundPermissionName != null) {
+                Log.i(LOG_TAG, permission.name + "->" + backgroundPermissionName);
+
+                // foreground permissions must be dangerous
+                assertNotEquals(0, permission.getProtection() & PROTECTION_DANGEROUS);
+
+                // foreground permissions must be in a group
+                assertNotNull(permission.group);
+
+                // All foreground permissions need an app op
+                assertNotNull(AppOpsManager.permissionToOp(permission.name));
+
+                // the background permission must exist
+                assertTrue(potentialBackgroundPermissionsToGroup
+                        .containsKey(backgroundPermissionName));
+
+                // the foreground and background permission must be in the same group
+                assertEquals(permission.group,
+                        potentialBackgroundPermissionsToGroup.get(backgroundPermissionName));
+            }
+        }
+    }
+}
diff --git a/tests/tests/permission2/res/raw/android_manifest.xml b/tests/tests/permission2/res/raw/android_manifest.xml
index 9eeabaf..12ff036 100644
--- a/tests/tests/permission2/res/raw/android_manifest.xml
+++ b/tests/tests/permission2/res/raw/android_manifest.xml
@@ -597,6 +597,7 @@
     <protected-broadcast android:name="android.app.action.AFFILIATED_PROFILE_TRANSFER_OWNERSHIP_COMPLETE" />
     <protected-broadcast android:name="android.app.action.DATA_SHARING_RESTRICTION_CHANGED" />
     <protected-broadcast android:name="android.app.action.STATSD_STARTED" />
+    <protected-broadcast android:name="com.android.server.biometrics.fingerprint.ACTION_LOCKOUT_RESET" />
 
     <!-- ====================================================================== -->
     <!--                          RUNTIME PERMISSIONS                           -->
diff --git a/tests/tests/permission2/src/android/permission2/cts/ProtectedBroadcastsTest.java b/tests/tests/permission2/src/android/permission2/cts/ProtectedBroadcastsTest.java
index 1b1e669..2f155d8 100644
--- a/tests/tests/permission2/src/android/permission2/cts/ProtectedBroadcastsTest.java
+++ b/tests/tests/permission2/src/android/permission2/cts/ProtectedBroadcastsTest.java
@@ -86,7 +86,6 @@
         "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",
     };
 
     /**
diff --git a/tests/tests/secure_element/omapi/src/android/omapi/cts/OmapiTest.java b/tests/tests/secure_element/omapi/src/android/omapi/cts/OmapiTest.java
index 34b6411..438857d 100644
--- a/tests/tests/secure_element/omapi/src/android/omapi/cts/OmapiTest.java
+++ b/tests/tests/secure_element/omapi/src/android/omapi/cts/OmapiTest.java
@@ -83,10 +83,10 @@
             {(byte) 0x80, 0x08, 0x00, 0x00, 0x00},
             {(byte) 0xA0, 0x08, 0x00, 0x00, 0x00},
             {(byte) 0x94, 0x08, 0x00, 0x00, 0x00},
-            {0x00, (byte) 0xC0, 0x00, 0x00, 0x01, (byte) 0xAA, 0x00},
-            {(byte) 0x80, (byte) 0xC0, 0x00, 0x00, 0x01, (byte) 0xAA, 0x00},
-            {(byte) 0xA0, (byte) 0xC0, 0x00, 0x00, 0x01, (byte) 0xAA, 0x00},
-            {(byte) 0x94, (byte) 0xC0, 0x00, 0x00, 0x01, (byte) 0xAA, 0x00}
+            {0x00, (byte) 0x0C, 0x00, 0x00, 0x01, (byte) 0xAA, 0x00},
+            {(byte) 0x80, (byte) 0x0C, 0x00, 0x00, 0x01, (byte) 0xAA, 0x00},
+            {(byte) 0xA0, (byte) 0x0C, 0x00, 0x00, 0x01, (byte) 0xAA, 0x00},
+            {(byte) 0x94, (byte) 0x0C, 0x00, 0x00, 0x01, (byte) 0xAA, 0x00}
     };
 
     private final static byte[] CHECK_SELECT_P2_APDU = new byte[]{0x00, (byte) 0xF4, 0x00, 0x00};
diff --git a/tests/tests/systemui/src/android/systemui/cts/LightBarTestBase.java b/tests/tests/systemui/src/android/systemui/cts/LightBarTestBase.java
index 10ce913..9179a9e 100644
--- a/tests/tests/systemui/src/android/systemui/cts/LightBarTestBase.java
+++ b/tests/tests/systemui/src/android/systemui/cts/LightBarTestBase.java
@@ -92,9 +92,11 @@
                 PackageManager.FEATURE_EMBEDDED));
 
         // No bars on TVs and watches.
+        // Automotive navigation bar is not transparent
         assumeFalse(pm.hasSystemFeature(PackageManager.FEATURE_WATCH)
                 || pm.hasSystemFeature(PackageManager.FEATURE_TELEVISION)
-                || pm.hasSystemFeature(PackageManager.FEATURE_LEANBACK));
+                || pm.hasSystemFeature(PackageManager.FEATURE_LEANBACK)
+                || pm.hasSystemFeature(PackageManager.FEATURE_AUTOMOTIVE));
 
 
         // Non-highEndGfx devices don't do colored system bars.
diff --git a/tests/tests/telephony/src/android/telephony/cts/CellInfoTest.java b/tests/tests/telephony/src/android/telephony/cts/CellInfoTest.java
index ef7f453..264d393 100644
--- a/tests/tests/telephony/src/android/telephony/cts/CellInfoTest.java
+++ b/tests/tests/telephony/src/android/telephony/cts/CellInfoTest.java
@@ -86,8 +86,8 @@
     private static final int PCI = 503;
     // Tracking area code ranges from 0 to 65535.
     private static final int TAC = 65535;
-    // Absolute RF Channel Number ranges from 0 to 262140.
-    private static final int EARFCN = 47000;
+    // Absolute RF Channel Number ranges from 0 to 262143.
+    private static final int EARFCN_MAX = 262143;
     private static final int BANDWIDTH_LOW = 1400;  // kHz
     private static final int BANDWIDTH_HIGH = 20000;  // kHz
 
@@ -317,6 +317,7 @@
         // LTE, the reported EARFCN is the center frequency, rendering these channels
         // out of the range of the narrowest 1.4Mhz deployment.
         int minEarfcn = 7;
+        int maxEarfcn = EARFCN_MAX - 7;
         if (bw != Integer.MAX_VALUE) {
             // The number of channels used by a cell is equal to the cell bandwidth divided
             // by the channel raster (bandwidth of a channel). The center channel is the channel
@@ -327,9 +328,11 @@
             // channel 0, which means that we can exclude from the valid range channels starting
             // from 0 and numbered less than half the total number of channels occupied by a cell.
             minEarfcn = bw / CHANNEL_RASTER_EUTRAN / 2;
+            maxEarfcn = EARFCN_MAX - (bw / CHANNEL_RASTER_EUTRAN / 2);
         }
-        assertTrue("getEarfcn() out of range [7,47000], earfcn=" + earfcn,
-                earfcn == Integer.MAX_VALUE || (earfcn >= minEarfcn && earfcn <= EARFCN));
+        assertTrue(
+                "getEarfcn() out of range [" + minEarfcn + "," + maxEarfcn + "], earfcn=" + earfcn,
+                earfcn == Integer.MAX_VALUE || (earfcn >= minEarfcn && earfcn <= maxEarfcn));
 
         String mccStr = lte.getMccString();
         // mccStr is set as NULL if empty, unknown or invalid.
diff --git a/tests/tests/uirendering/res/layout/skew_layout.xml b/tests/tests/uirendering/res/layout/skew_layout.xml
new file mode 100644
index 0000000..0b67a8f
--- /dev/null
+++ b/tests/tests/uirendering/res/layout/skew_layout.xml
@@ -0,0 +1,26 @@
+<?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.
+  -->
+<android.uirendering.cts.testclasses.view.SkewLayout
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    android:layout_width="@dimen/test_width"
+    android:layout_height="@dimen/test_height">
+    <View
+        android:id="@+id/view1"
+        android:layout_width="50dp"
+        android:layout_height="50dp"
+        android:background="#F00"
+        android:elevation="8dp" />
+</android.uirendering.cts.testclasses.view.SkewLayout>
diff --git a/tests/tests/uirendering/src/android/uirendering/cts/testclasses/LayerTests.java b/tests/tests/uirendering/src/android/uirendering/cts/testclasses/LayerTests.java
index c9e0e42..74786e4 100644
--- a/tests/tests/uirendering/src/android/uirendering/cts/testclasses/LayerTests.java
+++ b/tests/tests/uirendering/src/android/uirendering/cts/testclasses/LayerTests.java
@@ -49,7 +49,6 @@
 
 import androidx.annotation.ColorInt;
 
-import org.junit.Ignore;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 
@@ -538,12 +537,19 @@
 
     @LargeTest
     @Test
-    @Ignore // b/109839751
     public void testWebViewWithUnclippedLayer() {
         if (!getActivity().getPackageManager().hasSystemFeature(PackageManager.FEATURE_WEBVIEW)) {
             return; // no WebView to run test on
         }
         CountDownLatch hwFence = new CountDownLatch(1);
+        Point[] testPoints = new Point[] {
+            // solid area
+            new Point(0, 0),
+            new Point(0, TEST_HEIGHT - 1),
+            // fade area
+            new Point(0, TEST_HEIGHT - 10),
+            new Point(0, TEST_HEIGHT - 5)
+        };
         createTest()
                 .addLayout(R.layout.test_content_webview, (ViewInitializer) view -> {
                     WebView webview = view.requireViewById(R.id.webview);
@@ -553,32 +559,39 @@
                     webview.setVerticalScrollBarEnabled(false);
                     webview.setLayerType(View.LAYER_TYPE_HARDWARE, null);
 
+                    // Adjust Y to match the same gradient percentage, regardless of vertical
+                    // fading edge length.
+                    int verticalFadingEdgeLength = webview.getVerticalFadingEdgeLength();
+                    testPoints[2].y = TEST_HEIGHT - verticalFadingEdgeLength * 10 / 42;
+                    testPoints[3].y = TEST_HEIGHT - verticalFadingEdgeLength * 5 / 42;
                 }, true, hwFence)
                 .runWithVerifier(new SamplePointVerifier(
-                        new Point[] {
-                                // solid area
-                                new Point(0, 0),
-                                new Point(0, TEST_HEIGHT - 1),
-                                // fade area
-                                new Point(0, TEST_HEIGHT - 10),
-                                new Point(0, TEST_HEIGHT - 5)
-                        },
+                        testPoints,
                         new int[] {
                                 Color.BLUE,
                                 Color.WHITE,
-                                0xffb3b3ff, // white blended with blue
+                                0xffc5c5ff, // white blended with blue
                                 0xffdbdbff  // white blended with blue
-                        }));
+                        }, 50));
     }
 
     @LargeTest
     @Test
-    @Ignore // b/109839751
     public void testWebViewWithUnclippedLayerAndComplexClip() {
         if (!getActivity().getPackageManager().hasSystemFeature(PackageManager.FEATURE_WEBVIEW)) {
             return; // no WebView to run test on
         }
         CountDownLatch hwFence = new CountDownLatch(1);
+        Point[] testPoints = new Point[] {
+            // solid white area
+            new Point(0, 0),
+            new Point(0, TEST_HEIGHT - 1),
+            // solid blue area
+            new Point(TEST_WIDTH / 2 , 5),
+            // fade area
+            new Point(TEST_WIDTH / 2, TEST_HEIGHT - 10),
+            new Point(TEST_WIDTH / 2, TEST_HEIGHT - 5)
+        };
         createTest()
                 .addLayout(R.layout.circle_clipped_webview, (ViewInitializer) view -> {
                     WebView webview = view.requireViewById(R.id.webview);
@@ -587,26 +600,21 @@
                     webview.setVerticalFadingEdgeEnabled(true);
                     webview.setVerticalScrollBarEnabled(false);
                     webview.setLayerType(View.LAYER_TYPE_HARDWARE, null);
-
+                    // Adjust Y to match the same gradient percentage, regardless of vertical
+                    // fading edge length.
+                    int verticalFadingEdgeLength = webview.getVerticalFadingEdgeLength();
+                    testPoints[3].y = TEST_HEIGHT - verticalFadingEdgeLength * 10 / 42;
+                    testPoints[4].y = TEST_HEIGHT - verticalFadingEdgeLength * 5 / 42;
                 }, true, hwFence)
                 .runWithVerifier(new SamplePointVerifier(
-                        new Point[] {
-                                // solid white area
-                                new Point(0, 0),
-                                new Point(0, TEST_HEIGHT - 1),
-                                // solid blue area
-                                new Point(TEST_WIDTH / 2 , 5),
-                                // fade area
-                                new Point(TEST_WIDTH / 2, TEST_HEIGHT - 10),
-                                new Point(TEST_WIDTH / 2, TEST_HEIGHT - 5)
-                        },
+                        testPoints,
                         new int[] {
                                 Color.WHITE,
                                 Color.WHITE,
                                 Color.BLUE,
-                                0xffb3b3ff, // white blended with blue
+                                0xffc5c5ff, // white blended with blue
                                 0xffdbdbff  // white blended with blue
-                        }));
+                        }, 50));
     }
 
     @LargeTest
diff --git a/tests/tests/uirendering/src/android/uirendering/cts/testclasses/LayoutTests.java b/tests/tests/uirendering/src/android/uirendering/cts/testclasses/LayoutTests.java
index 3d1c10e..285db5a 100644
--- a/tests/tests/uirendering/src/android/uirendering/cts/testclasses/LayoutTests.java
+++ b/tests/tests/uirendering/src/android/uirendering/cts/testclasses/LayoutTests.java
@@ -16,12 +16,14 @@
 package android.uirendering.cts.testclasses;
 
 import android.graphics.Color;
+import android.graphics.Point;
 import android.graphics.Rect;
 import android.support.test.filters.MediumTest;
 import android.support.test.runner.AndroidJUnit4;
 import android.uirendering.cts.R;
 import android.uirendering.cts.bitmapverifiers.ColorVerifier;
 import android.uirendering.cts.bitmapverifiers.RectVerifier;
+import android.uirendering.cts.bitmapverifiers.SamplePointVerifier;
 import android.uirendering.cts.testinfrastructure.ActivityTestBase;
 
 import org.junit.Test;
@@ -41,5 +43,21 @@
         createTest().addLayout(R.layout.simple_rect_layout, null, false).runWithVerifier(
                 new RectVerifier(Color.WHITE, Color.BLUE, new Rect(5, 5, 85, 85)));
     }
+
+    @Test
+    public void testTransformChildViewLayout() {
+        createTest()
+                // Verify skew tranform matrix is applied for child view.
+                .addLayout(R.layout.skew_layout, null)
+                .runWithVerifier(new SamplePointVerifier(
+                        new Point[] {
+                                new Point(20, 10),
+                                new Point(0, TEST_HEIGHT - 1)
+                        },
+                        new int[] {
+                                Color.RED,
+                                Color.WHITE
+                        }));
+    }
 }
 
diff --git a/tests/tests/uirendering/src/android/uirendering/cts/testclasses/view/SkewLayout.java b/tests/tests/uirendering/src/android/uirendering/cts/testclasses/view/SkewLayout.java
new file mode 100644
index 0000000..f9b8a3c
--- /dev/null
+++ b/tests/tests/uirendering/src/android/uirendering/cts/testclasses/view/SkewLayout.java
@@ -0,0 +1,46 @@
+/*
+ * 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.uirendering.cts.testclasses.view;
+
+import android.content.Context;
+import android.graphics.Canvas;
+import android.util.AttributeSet;
+import android.view.View;
+import android.widget.FrameLayout;
+
+public class SkewLayout extends FrameLayout {
+
+    public SkewLayout(Context context) {
+        super(context);
+    }
+
+    public SkewLayout(Context context, AttributeSet attrs) {
+        super(context, attrs);
+    }
+
+    public SkewLayout(Context context, AttributeSet attrs, int defStyleAttr) {
+        super(context, attrs, defStyleAttr);
+    }
+
+    protected boolean drawChild(Canvas canvas, View child, long drawingTime) {
+        canvas.save();
+        canvas.skew(0.5f, 0f);
+        boolean result = super.drawChild(canvas, child, drawingTime);
+        canvas.restore();
+        return result;
+    }
+}
diff --git a/tests/tests/webkit/src/android/webkit/cts/WebBackForwardListTest.java b/tests/tests/webkit/src/android/webkit/cts/WebBackForwardListTest.java
index eb5b413..fedf521 100644
--- a/tests/tests/webkit/src/android/webkit/cts/WebBackForwardListTest.java
+++ b/tests/tests/webkit/src/android/webkit/cts/WebBackForwardListTest.java
@@ -108,7 +108,4 @@
         }.run();
     }
 
-    public void testClone() {
-    }
-
 }
diff --git a/tests/tests/widget/src/android/widget/cts/PopupMenuTest.java b/tests/tests/widget/src/android/widget/cts/PopupMenuTest.java
index 3a85f47..e76382e 100644
--- a/tests/tests/widget/src/android/widget/cts/PopupMenuTest.java
+++ b/tests/tests/widget/src/android/widget/cts/PopupMenuTest.java
@@ -28,6 +28,7 @@
 
 import android.app.Activity;
 import android.app.Instrumentation;
+import android.content.res.Resources;
 import android.support.test.InstrumentationRegistry;
 import android.support.test.annotation.UiThreadTest;
 import android.support.test.filters.MediumTest;
@@ -323,7 +324,9 @@
             final int prevGroupId =
                     i - 1 >= 0 ? menu.getItem(i - 1).getGroupId() : currGroupId;
             View itemView = menuItemList.getChildAt(i);
-            ImageView groupDivider = itemView.findViewById(com.android.internal.R.id.group_divider);
+            // Find com.android.internal.R.id.group_divider
+            ImageView groupDivider = itemView.findViewById(
+                    Resources.getSystem().getIdentifier("group_divider", "id", "android"));
 
             assertNotNull(groupDivider);
             if (!groupDividerEnabled || currGroupId == prevGroupId) {