Merge "Verify reported display sizes in multi-window" into rvc-dev
diff --git a/apps/CameraITS/pymodules/its/device.py b/apps/CameraITS/pymodules/its/device.py
index bc1d3a6..3d9a42e 100644
--- a/apps/CameraITS/pymodules/its/device.py
+++ b/apps/CameraITS/pymodules/its/device.py
@@ -249,7 +249,7 @@
             ch = self.sock.recv(1)
             if len(ch) == 0:
                 # Socket was probably closed; otherwise don't get empty strings
-                raise its.error.Error('Problem with socket on device side')
+                raise its.error.SocketError(self.device_id, 'Problem with socket on device side')
             chars.append(ch)
         line = ''.join(chars)
         jobj = json.loads(line)
diff --git a/apps/CameraITS/pymodules/its/error.py b/apps/CameraITS/pymodules/its/error.py
index 884389b..5b0c467 100644
--- a/apps/CameraITS/pymodules/its/error.py
+++ b/apps/CameraITS/pymodules/its/error.py
@@ -12,15 +12,54 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 
+import subprocess
 import unittest
 
+
 class Error(Exception):
     pass
 
+
+class SocketError(Error):
+
+    def __init__(self, device_id, message):
+        """Exception raised for socket errors.
+
+        Args:
+            device_id (str): device id
+            message (str): explanation of the error
+        """
+        Error.__init__(self)
+        self.message = message
+        locale = self.get_device_locale(device_id)
+        if locale != "en-US":
+            print "Unsupported default language %s" % locale
+            print "Please set the default language to English (United States)"
+            print "in Settings > Language & input > Languages\n"
+
+    def get_device_locale(self, device_id):
+        """Return the default locale of a given device.
+
+        Args:
+            device_id (str): device id
+
+        Returns:
+             str: Device locale.
+        """
+        locale_property = "persist.sys.locale"
+
+        com = ("adb -s %s shell getprop %s" % (device_id, locale_property))
+        proc = subprocess.Popen(com.split(), stdout=subprocess.PIPE)
+        output, error = proc.communicate()
+        assert error is None
+
+        return output
+
+
 class __UnitTest(unittest.TestCase):
     """Run a suite of unit tests on this module.
     """
 
-if __name__ == '__main__':
+if __name__ == "__main__":
     unittest.main()
 
diff --git a/apps/CameraITS/tests/scene6/test_zoom.py b/apps/CameraITS/tests/scene6/test_zoom.py
index 4671550..eef7144 100644
--- a/apps/CameraITS/tests/scene6/test_zoom.py
+++ b/apps/CameraITS/tests/scene6/test_zoom.py
@@ -24,19 +24,21 @@
 
 import numpy as np
 
+CIRCLE_COLOR = 0  # [0: black, 255: white]
 CIRCLE_TOL = 0.05  # contour area vs ideal circle area pi*((w+h)/4)**2
-COLOR = 0  # [0: black, 255: white]
+LINE_COLOR = (255, 0, 0)  # red
+LINE_THICKNESS = 5
+MIN_AREA_RATIO = 0.00015  # based on 2000/(4000x3000) pixels
+MIN_CIRCLE_PTS = 25
 NAME = os.path.basename(__file__).split('.')[0]
 NUM_STEPS = 10
-MIN_AREA_RATIO = 0.00015  # Based on 2000/(4000x3000) pixels
-MIN_CIRCLE_PTS = 25
 OFFSET_RTOL = 0.10
 RADIUS_RTOL = 0.10
 ZOOM_MAX_THRESH = 10.0
 ZOOM_MIN_THRESH = 2.0
 
 
-def distance(x, y):
+def distance((x, y)):
     return math.sqrt(x**2 + y**2)
 
 
@@ -116,13 +118,19 @@
         print 'circles [x, y, r, pi*r**2/area, area]:', circles
 
     # find circle closest to center
-    circles.sort(key=lambda x: distance(x[0]-img_ctr[0], x[1]-img_ctr[1]))
+    circles.sort(key=lambda x: distance((x[0]-img_ctr[0], x[1]-img_ctr[1])))
     circle = circles[0]
 
+    # mark image center
+    size = gray.shape
+    cv2.drawMarker(img, (size[1]/2, size[0]/2), LINE_COLOR,
+                   markerType=cv2.MARKER_CROSS, markerSize=LINE_THICKNESS*10,
+                   thickness=LINE_THICKNESS)
+
     # add circle to saved image
     center_i = (int(round(circle[0], 0)), int(round(circle[1], 0)))
     radius_i = int(round(circle[2], 0))
-    cv2.circle(img, center_i, radius_i, (255, 0, 0), 5)
+    cv2.circle(img, center_i, radius_i, LINE_COLOR, LINE_THICKNESS)
     its.image.write_image(img/255.0, name)
 
     if not circles:
@@ -137,7 +145,8 @@
     """Test the camera zoom behavior."""
 
     z_test_list = []
-    circle = {}
+    fls = []
+    circles = []
     with its.device.ItsSession() as cam:
         props = cam.get_camera_properties()
         its.caps.skip_unless(its.caps.zoom_ratio_range(props))
@@ -166,13 +175,15 @@
             img = img.astype(np.uint8)
 
             # Find the circles in img
-            circle[i] = find_center_circle(
-                    img, '%s_%s.jpg' % (NAME, round(z, 2)), COLOR,
+            circle = find_center_circle(
+                    img, '%s_%s.jpg' % (NAME, round(z, 2)), CIRCLE_COLOR,
                     min_area=MIN_AREA_RATIO*size[0]*size[1]*z*z, debug=debug)
-            if circle_cropped(circle[i], size):
+            if circle_cropped(circle, size):
                 print 'zoom %.2f is too large! Skip further captures' % z
                 break
+            circles.append(circle)
             z_test_list.append(z)
+            fls.append(cap['metadata']['android.lens.focalLength'])
 
     # assert some range is tested before circles get too big
     zoom_max_thresh = ZOOM_MAX_THRESH
@@ -182,27 +193,37 @@
             z_test_list[-1], zoom_max_thresh)
     assert z_test_list[-1] >= zoom_max_thresh, msg
 
-    # print 'circles:', circle
-    radius_init = float(circle[0][2])
-    offset_init = [circle[0][0]-size[0]/2,
-                   circle[0][1]-size[1]/2]
-    z_init = float(z_test_list[0])
+    # initialize relative size w/ zoom[0] for diff zoom ratio checks
+    radius_0 = float(circles[0][2])
+    z_0 = float(z_test_list[0])
+
     for i, z in enumerate(z_test_list):
-        print '\nZoom: %.2f' % z
-        offset_x_abs = (circle[i][0] - size[0] / 2)
-        offset_y_abs = (circle[i][1] - size[1] / 2)
+        print '\nZoom: %.2f, fl: %.2f' % (z, fls[i])
+        offset_abs = ((circles[i][0] - size[0]/2), (circles[i][1] - size[1]/2))
         print 'Circle r: %.1f, center offset x, y: %d, %d' % (
-                circle[i][2], offset_x_abs, offset_y_abs)
-        z_ratio = z/z_init
-        radius_ratio = circle[i][2]/radius_init
+                circles[i][2], offset_abs[0], offset_abs[1])
+        z_ratio = z / z_0
+
+        # check relative size against zoom[0]
+        radius_ratio = circles[i][2]/radius_0
+        print 'radius_ratio: %.3f' % radius_ratio
         msg = 'zoom: %.2f, radius ratio: %.2f, RTOL: %.2f' % (
                 z_ratio, radius_ratio, RADIUS_RTOL)
         assert np.isclose(z_ratio, radius_ratio, rtol=RADIUS_RTOL), msg
-        offset_rel = (distance(offset_x_abs, offset_y_abs) / radius_ratio /
-                      distance(offset_init[0], offset_init[1]))
-        msg = 'zoom: %.2f, offset(rel): %.2f, RTOL: %.2f' % (
-                z, offset_rel, OFFSET_RTOL)
-        assert np.isclose(offset_rel, 1.0, rtol=OFFSET_RTOL), msg
+
+        # check relative offset against init vals w/ no focal length change
+        if i == 0 or fls[i-1] != fls[i]:  # set init values
+            z_init = float(z_test_list[i])
+            offset_init = (circles[i][0] - size[0] / 2,
+                           circles[i][1] - size[1] / 2)
+        else:  # check
+            z_ratio = z / z_init
+            offset_rel = (distance(offset_abs) / z_ratio /
+                          distance(offset_init))
+            print 'offset_rel: %.3f' % offset_rel
+            msg = 'zoom: %.2f, offset(rel): %.2f, RTOL: %.2f' % (
+                    z, offset_rel, OFFSET_RTOL)
+            assert np.isclose(offset_rel, 1.0, rtol=OFFSET_RTOL), msg
 
 
 if __name__ == '__main__':
diff --git a/apps/CameraITS/tests/scene_change/test_scene_change.py b/apps/CameraITS/tests/scene_change/test_scene_change.py
index 2304759..626c224 100644
--- a/apps/CameraITS/tests/scene_change/test_scene_change.py
+++ b/apps/CameraITS/tests/scene_change/test_scene_change.py
@@ -31,7 +31,7 @@
 #             3: PASSIVE_UNFOCUSED, 4: ACTIVE_SCAN, 5: FOCUS_LOCKED,
 #             6: NOT_FOCUSED_LOCKED}
 # AWB_STATES: {0: INACTIVE, 1: SEARCHING, 2: CONVERGED, 3: LOCKED}
-DELAY_CAPTURE = 0.55  # delay in first capture to sync events (sec)
+DELAY_CAPTURE = 1.5  # delay in first capture to sync events (sec)
 DELAY_DISPLAY = 3.0  # time when display turns OFF (sec)
 FPS = 30
 FRAME_SHIFT = 5.0  # number of frames to shift to try and find scene change
@@ -56,17 +56,16 @@
             converged_frame = i
             break
     print 'Frames index where 3A converges: %d' % converged_frame
-    assert converged_frame != -1, '3A does not converge'
     return converged_frame
 
 
 def determine_if_scene_changed(cap_data, converged_frame):
     scene_changed = False
     bright_changed = False
-    settled_frame_brightness = cap_data[converged_frame]['avg']
+    start_frame_brightness = cap_data[0]['avg']
     for i in range(converged_frame, len(cap_data)):
         if cap_data[i]['avg'] <= (
-                settled_frame_brightness * (1.0 - BRIGHT_CHANGE_TOL)):
+                start_frame_brightness * (1.0 - BRIGHT_CHANGE_TOL)):
             bright_changed = True
         if cap_data[i]['flag'] == 1:
             scene_changed = True
@@ -75,7 +74,6 @@
 
 def toggle_screen(chart_host_id, state, delay):
     t0 = time.time()
-    print 'tablet event start'
     screen_id_arg = ('screen=%s' % chart_host_id)
     state_id_arg = 'state=%s' % state
     delay_arg = 'delay=%.3f' % delay
@@ -88,49 +86,48 @@
     print 'tablet event %s: %.3f' % (state, t)
 
 
-def capture_frames(delay, burst):
+def capture_frames(cam, delay, burst):
     """Capture frames."""
     cap_data_list = []
-    with its.device.ItsSession() as cam:
-        req = its.objects.auto_capture_request()
-        req['android.control.afMode'] = CONTINUOUS_PICTURE_MODE
-        fmt = {'format': 'yuv', 'width': W, 'height': H}
-        t0 = time.time()
-        time.sleep(delay)
-        print 'cap event start:', time.time() - t0
-        caps = cam.do_capture([req]*NUM_FRAMES, fmt)
-        print 'cap event stop:', time.time() - t0
-        # extract frame metadata and frame
-        for i, cap in enumerate(caps):
-            cap_data = {}
-            md = cap['metadata']
-            exp = md['android.sensor.exposureTime']
-            iso = md['android.sensor.sensitivity']
-            fd = md['android.lens.focalLength']
-            ae_state = md['android.control.aeState']
-            af_state = md['android.control.afState']
-            awb_state = md['android.control.awbState']
-            fd_str = 'infinity'
-            if fd != 0.0:
-                fd_str = str(round(1.0E2/fd, 2)) + 'cm'
-            scene_change_flag = md['android.control.afSceneChange']
-            assert scene_change_flag in [0, 1], 'afSceneChange not in [0,1]'
-            img = its.image.convert_capture_to_rgb_image(cap)
-            its.image.write_image(img, '%s_%d_%d.jpg' % (NAME, burst+1, i))
-            tile = its.image.get_image_patch(img, 0.45, 0.45, 0.1, 0.1)
-            g = its.image.compute_image_means(tile)[1]
-            print '%d, iso: %d, exp: %.2fms, fd: %s, avg: %.3f' % (
-                    i, iso, exp*1E-6, fd_str, g),
-            print '[ae,af,awb]: [%d,%d,%d], change: %d' % (
-                    ae_state, af_state, awb_state, scene_change_flag)
-            cap_data['exp'] = exp
-            cap_data['iso'] = iso
-            cap_data['fd'] = fd
-            cap_data['3a_state'] = [ae_state, af_state, awb_state]
-            cap_data['avg'] = g
-            cap_data['flag'] = scene_change_flag
-            cap_data_list.append(cap_data)
-        return cap_data_list
+    req = its.objects.auto_capture_request()
+    req['android.control.afMode'] = CONTINUOUS_PICTURE_MODE
+    fmt = {'format': 'yuv', 'width': W, 'height': H}
+    t0 = time.time()
+    time.sleep(delay)
+    print 'cap event start:', time.time() - t0
+    caps = cam.do_capture([req]*NUM_FRAMES, fmt)
+    print 'cap event stop:', time.time() - t0
+    # extract frame metadata and frame
+    for i, cap in enumerate(caps):
+        cap_data = {}
+        md = cap['metadata']
+        exp = md['android.sensor.exposureTime']
+        iso = md['android.sensor.sensitivity']
+        fd = md['android.lens.focalLength']
+        ae_state = md['android.control.aeState']
+        af_state = md['android.control.afState']
+        awb_state = md['android.control.awbState']
+        fd_str = 'infinity'
+        if fd != 0.0:
+            fd_str = str(round(1.0E2/fd, 2)) + 'cm'
+        scene_change_flag = md['android.control.afSceneChange']
+        assert scene_change_flag in [0, 1], 'afSceneChange not in [0,1]'
+        img = its.image.convert_capture_to_rgb_image(cap)
+        its.image.write_image(img, '%s_%d_%d.jpg' % (NAME, burst, i))
+        tile = its.image.get_image_patch(img, 0.45, 0.45, 0.1, 0.1)
+        g = its.image.compute_image_means(tile)[1]
+        print '%d, iso: %d, exp: %.2fms, fd: %s, avg: %.3f' % (
+                i, iso, exp*1E-6, fd_str, g),
+        print '[ae,af,awb]: [%d,%d,%d], change: %d' % (
+                ae_state, af_state, awb_state, scene_change_flag)
+        cap_data['exp'] = exp
+        cap_data['iso'] = iso
+        cap_data['fd'] = fd
+        cap_data['3a_state'] = [ae_state, af_state, awb_state]
+        cap_data['avg'] = g
+        cap_data['flag'] = scene_change_flag
+        cap_data_list.append(cap_data)
+    return cap_data_list
 
 
 def main():
@@ -148,52 +145,72 @@
                              its.caps.read_3a(props))
         cam.do_3a()
 
-    # do captures with scene change
-    chart_host_id = get_cmd_line_args()
-    cap_delay = DELAY_CAPTURE
-    scene_delay = DELAY_DISPLAY
-    for burst in range(NUM_BURSTS):
-        if chart_host_id:
-            print '\nToggling tablet. Scene change at %.3fs.' % scene_delay
-            multiprocessing.Process(name='p1', target=toggle_screen,
-                                    args=(chart_host_id, 'OFF',
-                                          scene_delay,)).start()
-        else:
-            print '\nWave hand in front of camera to create scene change.'
-        cap_data = capture_frames(cap_delay, burst+1)
-
-        # find frame where 3A converges
-        converged_frame = mask_3a_settling_frames(cap_data)
-
-        # turn tablet back on to return to baseline scene state
-        if chart_host_id:
-            toggle_screen(chart_host_id, 'ON', 0)
-
-        # determine if brightness changed and/or scene change flag asserted
-        scene_changed, bright_changed = determine_if_scene_changed(
-                cap_data, converged_frame)
-        if not scene_changed:
-            if bright_changed:
-                print ' No scene change, but brightness change.'
-                scene_delay -= FRAME_SHIFT/FPS  # tablet-off earlier
+        # do captures with scene change
+        chart_host_id = get_cmd_line_args()
+        scene_delay = DELAY_DISPLAY
+        for burst in range(NUM_BURSTS):
+            print 'burst number: %d' % burst
+            # create scene change by turning off chart display & capture frames
+            if chart_host_id:
+                print '\nToggling tablet. Scene change at %.3fs.' % scene_delay
+                multiprocessing.Process(name='p1', target=toggle_screen,
+                                        args=(chart_host_id, 'OFF',
+                                              scene_delay,)).start()
             else:
-                print ' No scene change, no brightness change.'
-                if cap_data[NUM_FRAMES-1]['avg'] < 0.1:
-                    print ' Scene dark entire capture. Shift later.'
-                    scene_delay += FRAME_SHIFT/FPS  # tablet-off later
+                print '\nWave hand in front of camera to create scene change.'
+            cap_data = capture_frames(cam, DELAY_CAPTURE, burst)
+
+            # find frame where 3A converges
+            converged_frame = mask_3a_settling_frames(cap_data)
+
+            # turn tablet back on to return to baseline scene state
+            if chart_host_id:
+                toggle_screen(chart_host_id, 'ON', 0)
+
+            # determine if brightness changed and/or scene change flag asserted
+            scene_changed, bright_changed = determine_if_scene_changed(
+                    cap_data, converged_frame)
+
+            # handle different capture cases
+            if converged_frame > -1:  # 3A converges
+                if scene_changed:
+                    if bright_changed:
+                        print ' scene & brightness change on burst %d.' % burst
+                        sys.exit(0)
+                    else:
+                        msg = ' scene change, but no brightness change.'
+                        assert False, msg
+                else:  # shift scene change timing if no scene change
+                    scene_shift = FRAME_SHIFT / FPS
+                    if bright_changed:
+                        print ' No scene change, but brightness change.'
+                        print 'Shift %.3fs earlier' % scene_shift
+                        scene_delay -= scene_shift  # tablet-off earlier
+                    else:
+                        scene_shift = FRAME_SHIFT / FPS * NUM_BURSTS
+                        print ' No scene change, no brightness change.'
+                        if cap_data[NUM_FRAMES-1]['avg'] < 0.2:
+                            print ' Scene dark entire capture.',
+                            print 'Shift %.3fs later.' % scene_shift
+                            scene_delay += scene_shift  # tablet-off later
+                        else:
+                            print ' Scene light entire capture.',
+                            print 'Shift %.3fs earlier.' % scene_shift
+                            scene_delay -= scene_shift  # tablet-off earlier
+
+            else:  # 3A does not converge
+                if bright_changed:
+                    scene_shift = FRAME_SHIFT / FPS
+                    print ' 3A does not converge, but brightness change.',
+                    print 'Shift %.3fs later' % scene_shift
+                    scene_delay += scene_shift  # tablet-off earlier
                 else:
-                    print ' Scene light entire capture. Shift earlier.'
-                    scene_delay -= FRAME_SHIFT/FPS  # tablet-off earlier
-            print ' Retry with tablet turning OFF earlier.'
-        elif scene_changed and bright_changed:
-            print ' scene & brightness change on burst %d.' % (burst+1)
-            break
-        elif scene_changed and not bright_changed:
-            msg = ' scene change, but no brightness change.'
-            assert False, msg
-        if burst == NUM_BURSTS - 1:
-            msg = 'No scene change in %dx tries' % NUM_BURSTS
-            assert False, msg
+                    msg = ' 3A does not converge with no brightness change.'
+                    assert False, msg
+
+        # fail out if too many tries
+        msg = 'No scene change in %dx tries' % NUM_BURSTS
+        assert False, msg
 
 
 if __name__ == '__main__':
diff --git a/apps/CtsVerifier/AndroidManifest.xml b/apps/CtsVerifier/AndroidManifest.xml
index 0d5b5b1..36c2284 100644
--- a/apps/CtsVerifier/AndroidManifest.xml
+++ b/apps/CtsVerifier/AndroidManifest.xml
@@ -2407,6 +2407,10 @@
                   android:label="@string/wifi_test_network_request_unavailable"
                   android:configChanges="keyboardHidden|orientation|screenSize" />
 
+        <activity android:name=".wifi.NetworkRequestInvalidCredentialNetworkSpecifierTestActivity"
+                  android:label="@string/wifi_test_network_request_invalid_credential"
+                  android:configChanges="keyboardHidden|orientation|screenSize" />
+
         <activity android:name=".wifi.NetworkSuggestionSsidTestActivity"
                   android:label="@string/wifi_test_network_suggestion_ssid"
                   android:configChanges="keyboardHidden|orientation|screenSize" />
@@ -2419,6 +2423,14 @@
                   android:label="@string/wifi_test_network_suggestion_ssid_post_connect"
                   android:configChanges="keyboardHidden|orientation|screenSize" />
 
+        <activity android:name=".wifi.NetworkSuggestionConnectionFailureTestActivity"
+                  android:label="@string/wifi_test_network_suggestion_connection_failure"
+                  android:configChanges="keyboardHidden|orientation|screenSize" />
+
+        <activity android:name=".wifi.NetworkSuggestionModificationInPlaceTestActivity"
+                  android:label="@string/wifi_test_network_suggestion_modification_in_place"
+                  android:configChanges="keyboardHidden|orientation|screenSize" />
+
         <activity android:name=".p2p.GoNegRequesterTestListActivity"
                 android:label="@string/p2p_go_neg_requester"
                 android:configChanges="keyboardHidden|orientation|screenSize" />
diff --git a/apps/CtsVerifier/jni/audio_loopback/Android.bp b/apps/CtsVerifier/jni/audio_loopback/Android.bp
index 9227c75..29b7e13 100644
--- a/apps/CtsVerifier/jni/audio_loopback/Android.bp
+++ b/apps/CtsVerifier/jni/audio_loopback/Android.bp
@@ -1,21 +1,22 @@
 cc_test_library {
     name: "libaudioloopback_jni",
     srcs: [
-        "sles.cpp",
-        "jni_sles.c",
-        "audio_utils/atomic.c",
-        "audio_utils/fifo.c",
-        "audio_utils/roundup.c",
+        "jni-bridge.cpp",
+        "NativeAudioAnalyzer.cpp",
+    ],
+    include_dirs: [
+        "frameworks/av/media/ndk/include",
+        "system/core/include/cutils",
     ],
     shared_libs: [
-        "libOpenSLES",
+        "libaaudio",
         "liblog",
     ],
+    stl: "libc++_static",
     ldflags: ["-Wl,--hash-style=sysv"],
     cflags: [
-        "-DSTDC_HEADERS",
         "-Werror",
         "-Wall",
     ],
-    sdk_version: "23",
+    sdk_version: "current",
 }
diff --git a/apps/CtsVerifier/jni/audio_loopback/NativeAudioAnalyzer.cpp b/apps/CtsVerifier/jni/audio_loopback/NativeAudioAnalyzer.cpp
new file mode 100644
index 0000000..d8d6946
--- /dev/null
+++ b/apps/CtsVerifier/jni/audio_loopback/NativeAudioAnalyzer.cpp
@@ -0,0 +1,322 @@
+/*
+ * Copyright 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "NativeAudioAnalyzer.h"
+
+static void convertPcm16ToFloat(const int16_t *source,
+                                float *destination,
+                                int32_t numSamples) {
+    constexpr float scaler = 1.0f / 32768.0f;
+    for (int i = 0; i < numSamples; i++) {
+        destination[i] = source[i] * scaler;
+    }
+}
+
+// Fill the audio output buffer.
+int32_t NativeAudioAnalyzer::readFormattedData(int32_t numFrames) {
+    int32_t framesRead = AAUDIO_ERROR_INVALID_FORMAT;
+    if (mActualInputFormat == AAUDIO_FORMAT_PCM_I16) {
+        framesRead = AAudioStream_read(mInputStream, mInputShortData,
+                                       numFrames,
+                                       0 /* timeoutNanoseconds */);
+    } else if (mActualInputFormat == AAUDIO_FORMAT_PCM_FLOAT) {
+        framesRead = AAudioStream_read(mInputStream, mInputFloatData,
+                                       numFrames,
+                                       0 /* timeoutNanoseconds */);
+    } else {
+        ALOGE("ERROR actualInputFormat = %d\n", mActualInputFormat);
+        assert(false);
+    }
+    if (framesRead < 0) {
+        // Expect INVALID_STATE if STATE_STARTING
+        if (mFramesReadTotal > 0) {
+            mInputError = framesRead;
+            ALOGE("ERROR in read = %d = %s\n", framesRead,
+                   AAudio_convertResultToText(framesRead));
+        } else {
+            framesRead = 0;
+        }
+    } else {
+        mFramesReadTotal += framesRead;
+    }
+    return framesRead;
+}
+
+aaudio_data_callback_result_t NativeAudioAnalyzer::dataCallbackProc(
+        void *audioData,
+        int32_t numFrames
+) {
+    aaudio_data_callback_result_t callbackResult = AAUDIO_CALLBACK_RESULT_CONTINUE;
+    float  *outputData = (float  *) audioData;
+
+    // Read audio data from the input stream.
+    int32_t actualFramesRead;
+
+    if (numFrames > mInputFramesMaximum) {
+        ALOGE("%s() numFrames:%d > mInputFramesMaximum:%d", __func__, numFrames, mInputFramesMaximum);
+        mInputError = AAUDIO_ERROR_OUT_OF_RANGE;
+        return AAUDIO_CALLBACK_RESULT_STOP;
+    }
+
+    if (numFrames > mMaxNumFrames) {
+        mMaxNumFrames = numFrames;
+    }
+    if (numFrames < mMinNumFrames) {
+        mMinNumFrames = numFrames;
+    }
+
+    // Silence the output.
+    int32_t numBytes = numFrames * mActualOutputChannelCount * sizeof(float);
+    memset(audioData, 0 /* value */, numBytes);
+
+    if (mNumCallbacksToDrain > 0) {
+        // Drain the input FIFOs.
+        int32_t totalFramesRead = 0;
+        do {
+            actualFramesRead = readFormattedData(numFrames);
+            if (actualFramesRead > 0) {
+                totalFramesRead += actualFramesRead;
+            } else if (actualFramesRead < 0) {
+                callbackResult = AAUDIO_CALLBACK_RESULT_STOP;
+            }
+            // Ignore errors because input stream may not be started yet.
+        } while (actualFramesRead > 0);
+        // Only counts if we actually got some data.
+        if (totalFramesRead > 0) {
+            mNumCallbacksToDrain--;
+        }
+
+    } else if (mNumCallbacksToNotRead > 0) {
+        // Let the input fill up a bit so we are not so close to the write pointer.
+        mNumCallbacksToNotRead--;
+    } else if (mNumCallbacksToDiscard > 0) {
+        // Ignore. Allow the input to fill back up to equilibrium with the output.
+        actualFramesRead = readFormattedData(numFrames);
+        if (actualFramesRead < 0) {
+            callbackResult = AAUDIO_CALLBACK_RESULT_STOP;
+        }
+        mNumCallbacksToDiscard--;
+
+    } else {
+        // The full duplex stream is now stable so process the audio.
+        int32_t numInputBytes = numFrames * mActualInputChannelCount * sizeof(float);
+        memset(mInputFloatData, 0 /* value */, numInputBytes);
+
+        int64_t inputFramesWritten = AAudioStream_getFramesWritten(mInputStream);
+        int64_t inputFramesRead = AAudioStream_getFramesRead(mInputStream);
+        int64_t framesAvailable = inputFramesWritten - inputFramesRead;
+
+        // Read the INPUT data.
+        actualFramesRead = readFormattedData(numFrames); // READ
+        if (actualFramesRead < 0) {
+            callbackResult = AAUDIO_CALLBACK_RESULT_STOP;
+        } else {
+            if (actualFramesRead < numFrames) {
+                if(actualFramesRead < (int32_t) framesAvailable) {
+                    ALOGE("insufficient for no reason, numFrames = %d"
+                                   ", actualFramesRead = %d"
+                                   ", inputFramesWritten = %d"
+                                   ", inputFramesRead = %d"
+                                   ", available = %d\n",
+                           numFrames,
+                           actualFramesRead,
+                           (int) inputFramesWritten,
+                           (int) inputFramesRead,
+                           (int) framesAvailable);
+                }
+                mInsufficientReadCount++;
+                mInsufficientReadFrames += numFrames - actualFramesRead; // deficit
+                // ALOGE("Error insufficientReadCount = %d\n",(int)mInsufficientReadCount);
+            }
+
+            int32_t numSamples = actualFramesRead * mActualInputChannelCount;
+
+            if (mActualInputFormat == AAUDIO_FORMAT_PCM_I16) {
+                convertPcm16ToFloat(mInputShortData, mInputFloatData, numSamples);
+            }
+
+            // Process the INPUT and generate the OUTPUT.
+            mLoopbackProcessor->process(mInputFloatData,
+                                               mActualInputChannelCount,
+                                               numFrames,
+                                               outputData,
+                                               mActualOutputChannelCount,
+                                               numFrames);
+
+            mIsDone = mLoopbackProcessor->isDone();
+            if (mIsDone) {
+                callbackResult = AAUDIO_CALLBACK_RESULT_STOP;
+            }
+        }
+    }
+    mFramesWrittenTotal += numFrames;
+
+    return callbackResult;
+}
+
+static aaudio_data_callback_result_t s_MyDataCallbackProc(
+        AAudioStream * /* outputStream */,
+        void *userData,
+        void *audioData,
+        int32_t numFrames) {
+    NativeAudioAnalyzer *myData = (NativeAudioAnalyzer *) userData;
+    return myData->dataCallbackProc(audioData, numFrames);
+}
+
+static void s_MyErrorCallbackProc(
+        AAudioStream * /* stream */,
+        void * userData,
+        aaudio_result_t error) {
+    ALOGE("Error Callback, error: %d\n",(int)error);
+    NativeAudioAnalyzer *myData = (NativeAudioAnalyzer *) userData;
+    myData->mOutputError = error;
+}
+
+bool NativeAudioAnalyzer::isRecordingComplete() {
+    return mPulseLatencyAnalyzer.isRecordingComplete();
+}
+
+int NativeAudioAnalyzer::analyze() {
+    mPulseLatencyAnalyzer.analyze();
+    return getError(); // TODO review
+}
+
+double NativeAudioAnalyzer::getLatencyMillis() {
+    return mPulseLatencyAnalyzer.getMeasuredLatency() * 1000.0 / 48000;
+}
+
+double NativeAudioAnalyzer::getConfidence() {
+    return mPulseLatencyAnalyzer.getMeasuredConfidence();
+}
+
+aaudio_result_t NativeAudioAnalyzer::openAudio() {
+    AAudioStreamBuilder *builder = nullptr;
+
+    mLoopbackProcessor = &mPulseLatencyAnalyzer; // for latency test
+
+    // Use an AAudioStreamBuilder to contain requested parameters.
+    aaudio_result_t result = AAudio_createStreamBuilder(&builder);
+    if (result != AAUDIO_OK) {
+        ALOGE("AAudio_createStreamBuilder() returned %s",
+               AAudio_convertResultToText(result));
+        return result;
+    }
+
+    // Create the OUTPUT stream -----------------------
+    AAudioStreamBuilder_setDirection(builder, AAUDIO_DIRECTION_OUTPUT);
+    AAudioStreamBuilder_setPerformanceMode(builder, AAUDIO_PERFORMANCE_MODE_LOW_LATENCY);
+    AAudioStreamBuilder_setSharingMode(builder, AAUDIO_SHARING_MODE_EXCLUSIVE);
+    AAudioStreamBuilder_setFormat(builder, AAUDIO_FORMAT_PCM_FLOAT);
+    AAudioStreamBuilder_setChannelCount(builder, 2); // stereo
+    AAudioStreamBuilder_setDataCallback(builder, s_MyDataCallbackProc, this);
+    AAudioStreamBuilder_setErrorCallback(builder, s_MyErrorCallbackProc, this);
+
+    result = AAudioStreamBuilder_openStream(builder, &mOutputStream);
+    if (result != AAUDIO_OK) {
+        ALOGE("NativeAudioAnalyzer::openAudio() OUTPUT error %s",
+               AAudio_convertResultToText(result));
+        return result;
+    }
+
+    int32_t outputFramesPerBurst = AAudioStream_getFramesPerBurst(mOutputStream);
+    (void) AAudioStream_setBufferSizeInFrames(mOutputStream, outputFramesPerBurst * kDefaultOutputSizeBursts);
+
+    int32_t outputSampleRate = AAudioStream_getSampleRate(mOutputStream);
+    mActualOutputChannelCount = AAudioStream_getChannelCount(mOutputStream);
+
+    // Create the INPUT stream -----------------------
+    AAudioStreamBuilder_setDirection(builder, AAUDIO_DIRECTION_INPUT);
+    AAudioStreamBuilder_setFormat(builder, AAUDIO_FORMAT_UNSPECIFIED);
+    AAudioStreamBuilder_setSampleRate(builder, outputSampleRate); // must match
+    AAudioStreamBuilder_setChannelCount(builder, 1); // mono
+    AAudioStreamBuilder_setDataCallback(builder, nullptr, nullptr);
+    AAudioStreamBuilder_setErrorCallback(builder, nullptr, nullptr);
+    result = AAudioStreamBuilder_openStream(builder, &mInputStream);
+    if (result != AAUDIO_OK) {
+        ALOGE("NativeAudioAnalyzer::openAudio() INPUT error %s",
+               AAudio_convertResultToText(result));
+        return result;
+    }
+
+    int32_t actualCapacity = AAudioStream_getBufferCapacityInFrames(mInputStream);
+    (void) AAudioStream_setBufferSizeInFrames(mInputStream, actualCapacity);
+
+    // ------- Setup loopbackData -----------------------------
+    mActualInputFormat = AAudioStream_getFormat(mInputStream);
+    mActualInputChannelCount = AAudioStream_getChannelCount(mInputStream);
+
+    // Allocate a buffer for the audio data.
+    mInputFramesMaximum = 32 * AAudioStream_getFramesPerBurst(mInputStream);
+
+    if (mActualInputFormat == AAUDIO_FORMAT_PCM_I16) {
+        mInputShortData = new int16_t[mInputFramesMaximum * mActualInputChannelCount]{};
+    }
+    mInputFloatData = new float[mInputFramesMaximum * mActualInputChannelCount]{};
+
+    return result;
+}
+
+aaudio_result_t NativeAudioAnalyzer::startAudio() {
+    mLoopbackProcessor->prepareToTest();
+
+    // Start OUTPUT first so INPUT does not overflow.
+    aaudio_result_t result = AAudioStream_requestStart(mOutputStream);
+    if (result != AAUDIO_OK) {
+        stopAudio();
+        return result;
+    }
+
+    result = AAudioStream_requestStart(mInputStream);
+    if (result != AAUDIO_OK) {
+        stopAudio();
+        return result;
+    }
+
+    return result;
+}
+
+aaudio_result_t NativeAudioAnalyzer::stopAudio() {
+    aaudio_result_t result1 = AAUDIO_OK;
+    aaudio_result_t result2 = AAUDIO_OK;
+    ALOGD("stopAudio() , minNumFrames = %d, maxNumFrames = %d\n", mMinNumFrames, mMaxNumFrames);
+    // Stop OUTPUT first because it uses INPUT.
+    if (mOutputStream != nullptr) {
+        result1 = AAudioStream_requestStop(mOutputStream);
+    }
+
+    // Stop INPUT.
+    if (mInputStream != nullptr) {
+        result2 = AAudioStream_requestStop(mInputStream);
+    }
+    return result1 != AAUDIO_OK ? result1 : result2;
+}
+
+aaudio_result_t NativeAudioAnalyzer::closeAudio() {
+    aaudio_result_t result1 = AAUDIO_OK;
+    aaudio_result_t result2 = AAUDIO_OK;
+    // Stop and close OUTPUT first because it uses INPUT.
+    if (mOutputStream != nullptr) {
+        result1 = AAudioStream_close(mOutputStream);
+        mOutputStream = nullptr;
+    }
+
+    // Stop and close INPUT.
+    if (mInputStream != nullptr) {
+        result2 = AAudioStream_close(mInputStream);
+        mInputStream = nullptr;
+    }
+    return result1 != AAUDIO_OK ? result1 : result2;
+}
diff --git a/apps/CtsVerifier/jni/audio_loopback/NativeAudioAnalyzer.h b/apps/CtsVerifier/jni/audio_loopback/NativeAudioAnalyzer.h
new file mode 100644
index 0000000..0d9c64b
--- /dev/null
+++ b/apps/CtsVerifier/jni/audio_loopback/NativeAudioAnalyzer.h
@@ -0,0 +1,139 @@
+/*
+ * Copyright 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef CTS_NATIVE_AUDIO_ANALYZER_H
+#define CTS_NATIVE_AUDIO_ANALYZER_H
+
+#define LOG_TAG "NativeAudioAnalyzer"
+#include <android/log.h>
+
+#ifndef MODULE_NAME
+#define MODULE_NAME  "NativeAudioAnalyzer"
+#endif
+
+#define ALOGV(...) __android_log_print(ANDROID_LOG_VERBOSE, MODULE_NAME, __VA_ARGS__)
+#define ALOGD(...) __android_log_print(ANDROID_LOG_DEBUG, MODULE_NAME, __VA_ARGS__)
+#define ALOGI(...) __android_log_print(ANDROID_LOG_INFO, MODULE_NAME, __VA_ARGS__)
+#define ALOGW(...) __android_log_print(ANDROID_LOG_WARN, MODULE_NAME, __VA_ARGS__)
+#define ALOGE(...) __android_log_print(ANDROID_LOG_ERROR, MODULE_NAME, __VA_ARGS__)
+#define ALOGF(...) __android_log_print(ANDROID_LOG_FATAL, MODULE_NAME, __VA_ARGS__)
+
+#include <aaudio/AAudio.h>
+
+#include "analyzer/GlitchAnalyzer.h"
+#include "analyzer/LatencyAnalyzer.h"
+
+class NativeAudioAnalyzer {
+public:
+
+    /**
+     * Open the audio input and output streams.
+     * @return AAUDIO_OK or negative error
+     */
+    aaudio_result_t openAudio();
+
+    /**
+     * Start the audio input and output streams.
+     * @return AAUDIO_OK or negative error
+     */
+    aaudio_result_t startAudio();
+
+    /**
+     * Stop the audio input and output streams.
+     * @return AAUDIO_OK or negative error
+     */
+    aaudio_result_t stopAudio();
+
+    /**
+     * Close the audio input and output streams.
+     * @return AAUDIO_OK or negative error
+     */
+    aaudio_result_t closeAudio();
+
+    /**
+     * @return true if enough audio input has been recorded
+     */
+    bool isRecordingComplete();
+
+    /**
+     * Analyze the input and measure the latency between output and input.
+     * @return AAUDIO_OK or negative error
+     */
+    int analyze();
+
+    /**
+     * @return the measured latency in milliseconds
+     */
+    double getLatencyMillis();
+
+    /**
+     * The confidence is based on a normalized correlation.
+     * It ranges from 0.0 to 1.0. Higher is better.
+     *
+     * @return the confidence in the latency result
+     */
+    double getConfidence();
+
+    aaudio_result_t getError() {
+        return mInputError ? mInputError : mOutputError;
+    }
+
+    AAudioStream      *mInputStream = nullptr;
+    AAudioStream      *mOutputStream = nullptr;
+    aaudio_format_t    mActualInputFormat = AAUDIO_FORMAT_INVALID;
+    int16_t           *mInputShortData = nullptr;
+    float             *mInputFloatData = nullptr;
+
+    aaudio_result_t    mInputError = AAUDIO_OK;
+    aaudio_result_t    mOutputError = AAUDIO_OK;
+
+aaudio_data_callback_result_t dataCallbackProc(
+        void *audioData,
+        int32_t numFrames);
+
+private:
+
+    int32_t readFormattedData(int32_t numFrames);
+
+    GlitchAnalyzer       mSineAnalyzer;
+    PulseLatencyAnalyzer mPulseLatencyAnalyzer;
+    LoopbackProcessor   *mLoopbackProcessor;
+
+    int32_t            mInputFramesMaximum = 0;
+    int32_t            mActualInputChannelCount = 0;
+    int32_t            mActualOutputChannelCount = 0;
+    int32_t            mNumCallbacksToDrain = kNumCallbacksToDrain;
+    int32_t            mNumCallbacksToNotRead = kNumCallbacksToNotRead;
+    int32_t            mNumCallbacksToDiscard = kNumCallbacksToDiscard;
+    int32_t            mMinNumFrames = INT32_MAX;
+    int32_t            mMaxNumFrames = 0;
+    int32_t            mInsufficientReadCount = 0;
+    int32_t            mInsufficientReadFrames = 0;
+    int32_t            mFramesReadTotal = 0;
+    int32_t            mFramesWrittenTotal = 0;
+    bool               mIsDone = false;
+
+    static constexpr int kLogPeriodMillis         = 1000;
+    static constexpr int kNumInputChannels        = 1;
+    static constexpr int kNumCallbacksToDrain     = 20;
+    static constexpr int kNumCallbacksToNotRead   = 0; // let input fill back up
+    static constexpr int kNumCallbacksToDiscard   = 20;
+    static constexpr int kDefaultHangTimeMillis   = 50;
+    static constexpr int kMaxGlitchEventsToSave   = 32;
+    static constexpr int kDefaultOutputSizeBursts = 2;
+};
+
+#endif // CTS_NATIVE_AUDIO_ANALYZER_H
diff --git a/apps/CtsVerifier/jni/audio_loopback/analyzer/GlitchAnalyzer.h b/apps/CtsVerifier/jni/audio_loopback/analyzer/GlitchAnalyzer.h
new file mode 100644
index 0000000..0adcd6e
--- /dev/null
+++ b/apps/CtsVerifier/jni/audio_loopback/analyzer/GlitchAnalyzer.h
@@ -0,0 +1,445 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef ANALYZER_GLITCH_ANALYZER_H
+#define ANALYZER_GLITCH_ANALYZER_H
+
+#include <algorithm>
+#include <cctype>
+#include <iomanip>
+#include <iostream>
+
+#include "LatencyAnalyzer.h"
+#include "PseudoRandom.h"
+
+/**
+ * Output a steady sine wave and analyze the return signal.
+ *
+ * Use a cosine transform to measure the predicted magnitude and relative phase of the
+ * looped back sine wave. Then generate a predicted signal and compare with the actual signal.
+ */
+class GlitchAnalyzer : public LoopbackProcessor {
+public:
+
+    int32_t getState() const {
+        return mState;
+    }
+
+    double getPeakAmplitude() const {
+        return mPeakFollower.getLevel();
+    }
+
+    double getTolerance() {
+        return mTolerance;
+    }
+
+    void setTolerance(double tolerance) {
+        mTolerance = tolerance;
+        mScaledTolerance = mMagnitude * mTolerance;
+    }
+
+    void setMagnitude(double magnitude) {
+        mMagnitude = magnitude;
+        mScaledTolerance = mMagnitude * mTolerance;
+    }
+
+    int32_t getGlitchCount() const {
+        return mGlitchCount;
+    }
+
+    int32_t getStateFrameCount(int state) const {
+        return mStateFrameCounters[state];
+    }
+
+    double getSignalToNoiseDB() {
+        static const double threshold = 1.0e-14;
+        if (mMeanSquareSignal < threshold || mMeanSquareNoise < threshold) {
+            return 0.0;
+        } else {
+            double signalToNoise = mMeanSquareSignal / mMeanSquareNoise; // power ratio
+            double signalToNoiseDB = 10.0 * log(signalToNoise);
+            if (signalToNoiseDB < MIN_SNR_DB) {
+                ALOGD("ERROR - signal to noise ratio is too low! < %d dB. Adjust volume.",
+                     MIN_SNR_DB);
+                setResult(ERROR_VOLUME_TOO_LOW);
+            }
+            return signalToNoiseDB;
+        }
+    }
+
+    std::string analyze() override {
+        std::stringstream report;
+        report << "GlitchAnalyzer ------------------\n";
+        report << LOOPBACK_RESULT_TAG "peak.amplitude     = " << std::setw(8)
+               << getPeakAmplitude() << "\n";
+        report << LOOPBACK_RESULT_TAG "sine.magnitude     = " << std::setw(8)
+               << mMagnitude << "\n";
+        report << LOOPBACK_RESULT_TAG "rms.noise          = " << std::setw(8)
+               << mMeanSquareNoise << "\n";
+        report << LOOPBACK_RESULT_TAG "signal.to.noise.db = " << std::setw(8)
+               << getSignalToNoiseDB() << "\n";
+        report << LOOPBACK_RESULT_TAG "frames.accumulated = " << std::setw(8)
+               << mFramesAccumulated << "\n";
+        report << LOOPBACK_RESULT_TAG "sine.period        = " << std::setw(8)
+               << mSinePeriod << "\n";
+        report << LOOPBACK_RESULT_TAG "test.state         = " << std::setw(8)
+               << mState << "\n";
+        report << LOOPBACK_RESULT_TAG "frame.count        = " << std::setw(8)
+               << mFrameCounter << "\n";
+        // Did we ever get a lock?
+        bool gotLock = (mState == STATE_LOCKED) || (mGlitchCount > 0);
+        if (!gotLock) {
+            report << "ERROR - failed to lock on reference sine tone.\n";
+            setResult(ERROR_NO_LOCK);
+        } else {
+            // Only print if meaningful.
+            report << LOOPBACK_RESULT_TAG "glitch.count       = " << std::setw(8)
+                   << mGlitchCount << "\n";
+            report << LOOPBACK_RESULT_TAG "max.glitch         = " << std::setw(8)
+                   << mMaxGlitchDelta << "\n";
+            if (mGlitchCount > 0) {
+                report << "ERROR - number of glitches > 0\n";
+                setResult(ERROR_GLITCHES);
+            }
+        }
+        return report.str();
+    }
+
+    void printStatus() override {
+        ALOGD("st = %d, #gl = %3d,", mState, mGlitchCount);
+    }
+    /**
+     * Calculate the magnitude of the component of the input signal
+     * that matches the analysis frequency.
+     * Also calculate the phase that we can use to create a
+     * signal that matches that component.
+     * The phase will be between -PI and +PI.
+     */
+    double calculateMagnitude(double *phasePtr = nullptr) {
+        if (mFramesAccumulated == 0) {
+            return 0.0;
+        }
+        double sinMean = mSinAccumulator / mFramesAccumulated;
+        double cosMean = mCosAccumulator / mFramesAccumulated;
+        double magnitude = 2.0 * sqrt((sinMean * sinMean) + (cosMean * cosMean));
+        if (phasePtr != nullptr) {
+            double phase = M_PI_2 - atan2(sinMean, cosMean);
+            *phasePtr = phase;
+        }
+        return magnitude;
+    }
+
+    /**
+     * @param frameData contains microphone data with sine signal feedback
+     * @param channelCount
+     */
+    result_code processInputFrame(float *frameData, int /* channelCount */) override {
+        result_code result = RESULT_OK;
+
+        float sample = frameData[0];
+        float peak = mPeakFollower.process(sample);
+
+        // Force a periodic glitch to test the detector!
+        if (mForceGlitchDuration > 0) {
+            if (mForceGlitchCounter == 0) {
+                ALOGE("%s: force a glitch!!", __func__);
+                mForceGlitchCounter = getSampleRate();
+            } else if (mForceGlitchCounter <= mForceGlitchDuration) {
+                // Force an abrupt offset.
+                sample += (sample > 0.0) ? -0.5f : 0.5f;
+            }
+            --mForceGlitchCounter;
+        }
+
+        mStateFrameCounters[mState]++; // count how many frames we are in each state
+
+        switch (mState) {
+            case STATE_IDLE:
+                mDownCounter--;
+                if (mDownCounter <= 0) {
+                    mState = STATE_IMMUNE;
+                    mDownCounter = IMMUNE_FRAME_COUNT;
+                    mInputPhase = 0.0; // prevent spike at start
+                    mOutputPhase = 0.0;
+                }
+                break;
+
+            case STATE_IMMUNE:
+                mDownCounter--;
+                if (mDownCounter <= 0) {
+                    mState = STATE_WAITING_FOR_SIGNAL;
+                }
+                break;
+
+            case STATE_WAITING_FOR_SIGNAL:
+                if (peak > mThreshold) {
+                    mState = STATE_WAITING_FOR_LOCK;
+                    //ALOGD("%5d: switch to STATE_WAITING_FOR_LOCK", mFrameCounter);
+                    resetAccumulator();
+                }
+                break;
+
+            case STATE_WAITING_FOR_LOCK:
+                mSinAccumulator += sample * sinf(mInputPhase);
+                mCosAccumulator += sample * cosf(mInputPhase);
+                mFramesAccumulated++;
+                // Must be a multiple of the period or the calculation will not be accurate.
+                if (mFramesAccumulated == mSinePeriod * PERIODS_NEEDED_FOR_LOCK) {
+                    double phaseOffset = 0.0;
+                    setMagnitude(calculateMagnitude(&phaseOffset));
+//                    ALOGD("%s() mag = %f, offset = %f, prev = %f",
+//                            __func__, mMagnitude, mPhaseOffset, mPreviousPhaseOffset);
+                    if (mMagnitude > mThreshold) {
+                        if (abs(phaseOffset) < kMaxPhaseError) {
+                            mState = STATE_LOCKED;
+//                            ALOGD("%5d: switch to STATE_LOCKED", mFrameCounter);
+                        }
+                        // Adjust mInputPhase to match measured phase
+                        mInputPhase += phaseOffset;
+                    }
+                    resetAccumulator();
+                }
+                incrementInputPhase();
+                break;
+
+            case STATE_LOCKED: {
+                // Predict next sine value
+                double predicted = sinf(mInputPhase) * mMagnitude;
+                double diff = predicted - sample;
+                double absDiff = fabs(diff);
+                mMaxGlitchDelta = std::max(mMaxGlitchDelta, absDiff);
+                if (absDiff > mScaledTolerance) {
+                    result = ERROR_GLITCHES;
+                    onGlitchStart();
+//                    LOGI("diff glitch detected, absDiff = %g", absDiff);
+                } else {
+                    mSumSquareSignal += predicted * predicted;
+                    mSumSquareNoise += diff * diff;
+                    // Track incoming signal and slowly adjust magnitude to account
+                    // for drift in the DRC or AGC.
+                    mSinAccumulator += sample * sinf(mInputPhase);
+                    mCosAccumulator += sample * cosf(mInputPhase);
+                    mFramesAccumulated++;
+                    // Must be a multiple of the period or the calculation will not be accurate.
+                    if (mFramesAccumulated == mSinePeriod) {
+                        const double coefficient = 0.1;
+                        double phaseOffset = 0.0;
+                        double magnitude = calculateMagnitude(&phaseOffset);
+                        // One pole averaging filter.
+                        setMagnitude((mMagnitude * (1.0 - coefficient)) + (magnitude * coefficient));
+
+                        mMeanSquareNoise = mSumSquareNoise * mInverseSinePeriod;
+                        mMeanSquareSignal = mSumSquareSignal * mInverseSinePeriod;
+                        resetAccumulator();
+
+                        if (abs(phaseOffset) > kMaxPhaseError) {
+                            result = ERROR_GLITCHES;
+                            onGlitchStart();
+                            ALOGD("phase glitch detected, phaseOffset = %g", phaseOffset);
+                        } else if (mMagnitude < mThreshold) {
+                            result = ERROR_GLITCHES;
+                            onGlitchStart();
+                            ALOGD("magnitude glitch detected, mMagnitude = %g", mMagnitude);
+                        }
+                    }
+                }
+                incrementInputPhase();
+            } break;
+
+            case STATE_GLITCHING: {
+                // Predict next sine value
+                mGlitchLength++;
+                double predicted = sinf(mInputPhase) * mMagnitude;
+                double diff = predicted - sample;
+                double absDiff = fabs(diff);
+                mMaxGlitchDelta = std::max(mMaxGlitchDelta, absDiff);
+                if (absDiff < mScaledTolerance) { // close enough?
+                    // If we get a full sine period of non-glitch samples in a row then consider the glitch over.
+                    // We don't want to just consider a zero crossing the end of a glitch.
+                    if (mNonGlitchCount++ > mSinePeriod) {
+                        onGlitchEnd();
+                    }
+                } else {
+                    mNonGlitchCount = 0;
+                    if (mGlitchLength > (4 * mSinePeriod)) {
+                        relock();
+                    }
+                }
+                incrementInputPhase();
+            } break;
+
+            case NUM_STATES: // not a real state
+                break;
+        }
+
+        mFrameCounter++;
+
+        return result;
+    }
+
+    // advance and wrap phase
+    void incrementInputPhase() {
+        mInputPhase += mPhaseIncrement;
+        if (mInputPhase > M_PI) {
+            mInputPhase -= (2.0 * M_PI);
+        }
+    }
+
+    // advance and wrap phase
+    void incrementOutputPhase() {
+        mOutputPhase += mPhaseIncrement;
+        if (mOutputPhase > M_PI) {
+            mOutputPhase -= (2.0 * M_PI);
+        }
+    }
+
+    /**
+     * @param frameData upon return, contains the reference sine wave
+     * @param channelCount
+     */
+    result_code processOutputFrame(float *frameData, int channelCount) override {
+        float output = 0.0f;
+        // Output sine wave so we can measure it.
+        if (mState != STATE_IDLE) {
+            float sinOut = sinf(mOutputPhase);
+            incrementOutputPhase();
+            output = (sinOut * mOutputAmplitude)
+                     + (mWhiteNoise.nextRandomDouble() * kNoiseAmplitude);
+            // ALOGD("sin(%f) = %f, %f\n", mOutputPhase, sinOut,  mPhaseIncrement);
+        }
+        frameData[0] = output;
+        for (int i = 1; i < channelCount; i++) {
+            frameData[i] = 0.0f;
+        }
+        return RESULT_OK;
+    }
+
+    void onGlitchStart() {
+        mGlitchCount++;
+//        ALOGD("%5d: STARTED a glitch # %d", mFrameCounter, mGlitchCount);
+        mState = STATE_GLITCHING;
+        mGlitchLength = 1;
+        mNonGlitchCount = 0;
+    }
+
+    void onGlitchEnd() {
+//        ALOGD("%5d: ENDED a glitch # %d, length = %d", mFrameCounter, mGlitchCount, mGlitchLength);
+        mState = STATE_LOCKED;
+        resetAccumulator();
+    }
+
+    // reset the sine wave detector
+    void resetAccumulator() {
+        mFramesAccumulated = 0;
+        mSinAccumulator = 0.0;
+        mCosAccumulator = 0.0;
+        mSumSquareSignal = 0.0;
+        mSumSquareNoise = 0.0;
+    }
+
+    void relock() {
+//        ALOGD("relock: %d because of a very long %d glitch", mFrameCounter, mGlitchLength);
+        mState = STATE_WAITING_FOR_LOCK;
+        resetAccumulator();
+    }
+
+    void reset() override {
+        LoopbackProcessor::reset();
+        mState = STATE_IDLE;
+        mDownCounter = IDLE_FRAME_COUNT;
+        resetAccumulator();
+    }
+
+    void prepareToTest() override {
+        LoopbackProcessor::prepareToTest();
+        mSinePeriod = getSampleRate() / kTargetGlitchFrequency;
+        mOutputPhase = 0.0f;
+        mInverseSinePeriod = 1.0 / mSinePeriod;
+        mPhaseIncrement = 2.0 * M_PI * mInverseSinePeriod;
+        mGlitchCount = 0;
+        mMaxGlitchDelta = 0.0;
+        for (int i = 0; i < NUM_STATES; i++) {
+            mStateFrameCounters[i] = 0;
+        }
+    }
+
+private:
+
+    // These must match the values in GlitchActivity.java
+    enum sine_state_t {
+        STATE_IDLE,               // beginning
+        STATE_IMMUNE,             // ignoring input, waiting fo HW to settle
+        STATE_WAITING_FOR_SIGNAL, // looking for a loud signal
+        STATE_WAITING_FOR_LOCK,   // trying to lock onto the phase of the sine
+        STATE_LOCKED,             // locked on the sine wave, looking for glitches
+        STATE_GLITCHING,           // locked on the sine wave but glitching
+        NUM_STATES
+    };
+
+    enum constants {
+        // Arbitrary durations, assuming 48000 Hz
+        IDLE_FRAME_COUNT = 48 * 100,
+        IMMUNE_FRAME_COUNT = 48 * 100,
+        PERIODS_NEEDED_FOR_LOCK = 8,
+        MIN_SNR_DB = 65
+    };
+
+    static constexpr float kNoiseAmplitude = 0.00; // Used to experiment with warbling caused by DRC.
+    static constexpr int kTargetGlitchFrequency = 607;
+    static constexpr double kMaxPhaseError = M_PI * 0.05;
+
+    float   mTolerance = 0.10; // scaled from 0.0 to 1.0
+    double  mThreshold = 0.005;
+    int     mSinePeriod = 1; // this will be set before use
+    double  mInverseSinePeriod = 1.0;
+
+    int32_t mStateFrameCounters[NUM_STATES];
+
+    double  mPhaseIncrement = 0.0;
+    double  mInputPhase = 0.0;
+    double  mOutputPhase = 0.0;
+    double  mMagnitude = 0.0;
+    int32_t mFramesAccumulated = 0;
+    double  mSinAccumulator = 0.0;
+    double  mCosAccumulator = 0.0;
+    double  mMaxGlitchDelta = 0.0;
+    int32_t mGlitchCount = 0;
+    int32_t mNonGlitchCount = 0;
+    int32_t mGlitchLength = 0;
+    // This is used for processing every frame so we cache it here.
+    double  mScaledTolerance = 0.0;
+    int     mDownCounter = IDLE_FRAME_COUNT;
+    int32_t mFrameCounter = 0;
+    double  mOutputAmplitude = 0.75;
+
+    int32_t mForceGlitchDuration = 0; // if > 0 then force a glitch for debugging
+    int32_t mForceGlitchCounter = 4 * 48000; // count down and trigger at zero
+
+    // measure background noise continuously as a deviation from the expected signal
+    double  mSumSquareSignal = 0.0;
+    double  mSumSquareNoise = 0.0;
+    double  mMeanSquareSignal = 0.0;
+    double  mMeanSquareNoise = 0.0;
+
+    PeakDetector  mPeakFollower;
+
+    PseudoRandom  mWhiteNoise;
+
+    sine_state_t  mState = STATE_IDLE;
+};
+
+
+#endif //ANALYZER_GLITCH_ANALYZER_H
diff --git a/apps/CtsVerifier/jni/audio_loopback/analyzer/LatencyAnalyzer.h b/apps/CtsVerifier/jni/audio_loopback/analyzer/LatencyAnalyzer.h
new file mode 100644
index 0000000..59106cb
--- /dev/null
+++ b/apps/CtsVerifier/jni/audio_loopback/analyzer/LatencyAnalyzer.h
@@ -0,0 +1,604 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+ * Tools for measuring latency and for detecting glitches.
+ * These classes are pure math and can be used with any audio system.
+ */
+
+#ifndef ANALYZER_LATENCY_ANALYZER_H
+#define ANALYZER_LATENCY_ANALYZER_H
+
+#include <algorithm>
+#include <assert.h>
+#include <cctype>
+#include <iomanip>
+#include <iostream>
+#include <math.h>
+#include <memory>
+#include <sstream>
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <vector>
+
+#include "PeakDetector.h"
+#include "PseudoRandom.h"
+#include "RandomPulseGenerator.h"
+
+
+#define LOOPBACK_RESULT_TAG  "RESULT: "
+
+static constexpr int32_t kDefaultSampleRate = 48000;
+static constexpr int32_t kMillisPerSecond   = 1000;
+static constexpr int32_t kMaxLatencyMillis  = 700;  // arbitrary and generous
+static constexpr double  kMinimumConfidence = 0.2;
+
+struct LatencyReport {
+    int32_t latencyInFrames = 0.0;
+    double confidence = 0.0;
+
+    void reset() {
+        latencyInFrames = 0;
+        confidence = 0.0;
+    }
+};
+
+// Calculate a normalized cross correlation.
+static double calculateNormalizedCorrelation(const float *a,
+                                             const float *b,
+                                             int windowSize) {
+    double correlation = 0.0;
+    double sumProducts = 0.0;
+    double sumSquares = 0.0;
+
+    // Correlate a against b.
+    for (int i = 0; i < windowSize; i++) {
+        float s1 = a[i];
+        float s2 = b[i];
+        // Use a normalized cross-correlation.
+        sumProducts += s1 * s2;
+        sumSquares += ((s1 * s1) + (s2 * s2));
+    }
+
+    if (sumSquares >= 1.0e-9) {
+        correlation = 2.0 * sumProducts / sumSquares;
+    }
+    return correlation;
+}
+
+static double calculateRootMeanSquare(float *data, int32_t numSamples) {
+    double sum = 0.0;
+    for (int32_t i = 0; i < numSamples; i++) {
+        float sample = data[i];
+        sum += sample * sample;
+    }
+    return sqrt(sum / numSamples);
+}
+
+/**
+ * Monophonic recording with processing.
+ */
+class AudioRecording
+{
+public:
+
+    void allocate(int maxFrames) {
+        mData = std::make_unique<float[]>(maxFrames);
+        mMaxFrames = maxFrames;
+    }
+
+    // Write SHORT data from the first channel.
+    int32_t write(int16_t *inputData, int32_t inputChannelCount, int32_t numFrames) {
+        // stop at end of buffer
+        if ((mFrameCounter + numFrames) > mMaxFrames) {
+            numFrames = mMaxFrames - mFrameCounter;
+        }
+        for (int i = 0; i < numFrames; i++) {
+            mData[mFrameCounter++] = inputData[i * inputChannelCount] * (1.0f / 32768);
+        }
+        return numFrames;
+    }
+
+    // Write FLOAT data from the first channel.
+    int32_t write(float *inputData, int32_t inputChannelCount, int32_t numFrames) {
+        // stop at end of buffer
+        if ((mFrameCounter + numFrames) > mMaxFrames) {
+            numFrames = mMaxFrames - mFrameCounter;
+        }
+        for (int i = 0; i < numFrames; i++) {
+            mData[mFrameCounter++] = inputData[i * inputChannelCount];
+        }
+        return numFrames;
+    }
+
+    // Write FLOAT data from the first channel.
+    int32_t write(float sample) {
+        // stop at end of buffer
+        if (mFrameCounter < mMaxFrames) {
+            mData[mFrameCounter++] = sample;
+            return 1;
+        }
+        return 0;
+    }
+
+    void clear() {
+        mFrameCounter = 0;
+    }
+    int32_t size() const {
+        return mFrameCounter;
+    }
+
+    bool isFull() const {
+        return mFrameCounter >= mMaxFrames;
+    }
+
+    float *getData() const {
+        return mData.get();
+    }
+
+    void setSampleRate(int32_t sampleRate) {
+        mSampleRate = sampleRate;
+    }
+
+    int32_t getSampleRate() const {
+        return mSampleRate;
+    }
+
+    /**
+     * Square the samples so they are all positive and so the peaks are emphasized.
+     */
+    void square() {
+        float *x = mData.get();
+        for (int i = 0; i < mFrameCounter; i++) {
+            x[i] *= x[i];
+        }
+    }
+
+    /**
+     * Amplify a signal so that the peak matches the specified target.
+     *
+     * @param target final max value
+     * @return gain applied to signal
+     */
+    float normalize(float target) {
+        float maxValue = 1.0e-9f;
+        for (int i = 0; i < mFrameCounter; i++) {
+            maxValue = std::max(maxValue, abs(mData[i]));
+        }
+        float gain = target / maxValue;
+        for (int i = 0; i < mFrameCounter; i++) {
+            mData[i] *= gain;
+        }
+        return gain;
+    }
+
+private:
+    std::unique_ptr<float[]> mData;
+    int32_t       mFrameCounter = 0;
+    int32_t       mMaxFrames = 0;
+    int32_t       mSampleRate = kDefaultSampleRate; // common default
+};
+
+static int measureLatencyFromPulse(AudioRecording &recorded,
+                                   AudioRecording &pulse,
+                                   LatencyReport *report) {
+
+    report->latencyInFrames = 0;
+    report->confidence = 0.0;
+
+    int numCorrelations = recorded.size() - pulse.size();
+    if (numCorrelations < 10) {
+        ALOGE("%s() recording too small = %d frames\n", __func__, recorded.size());
+        return -1;
+    }
+    std::unique_ptr<float[]> correlations= std::make_unique<float[]>(numCorrelations);
+
+    // Correlate pulse against the recorded data.
+    for (int i = 0; i < numCorrelations; i++) {
+        float correlation = (float) calculateNormalizedCorrelation(&recorded.getData()[i],
+                                                                   &pulse.getData()[0],
+                                                                   pulse.size());
+        correlations[i] = correlation;
+    }
+
+    // Find highest peak in correlation array.
+    float peakCorrelation = 0.0;
+    int peakIndex = -1;
+    for (int i = 0; i < numCorrelations; i++) {
+        float value = abs(correlations[i]);
+        if (value > peakCorrelation) {
+            peakCorrelation = value;
+            peakIndex = i;
+        }
+    }
+    if (peakIndex < 0) {
+        ALOGE("%s() no signal for correlation\n", __func__);
+        return -2;
+    }
+
+    report->latencyInFrames = peakIndex;
+    report->confidence = peakCorrelation;
+
+    return 0;
+}
+
+// ====================================================================================
+class LoopbackProcessor {
+public:
+    virtual ~LoopbackProcessor() = default;
+
+    enum result_code {
+        RESULT_OK = 0,
+        ERROR_NOISY = -99,
+        ERROR_VOLUME_TOO_LOW,
+        ERROR_VOLUME_TOO_HIGH,
+        ERROR_CONFIDENCE,
+        ERROR_INVALID_STATE,
+        ERROR_GLITCHES,
+        ERROR_NO_LOCK
+    };
+
+    virtual void prepareToTest() {
+        reset();
+    }
+
+    virtual void reset() {
+        mResult = 0;
+        mResetCount++;
+    }
+
+    virtual result_code processInputFrame(float *frameData, int channelCount) = 0;
+    virtual result_code processOutputFrame(float *frameData, int channelCount) = 0;
+
+    void process(float *inputData, int inputChannelCount, int numInputFrames,
+                 float *outputData, int outputChannelCount, int numOutputFrames) {
+        int numBoth = std::min(numInputFrames, numOutputFrames);
+        // Process one frame at a time.
+        for (int i = 0; i < numBoth; i++) {
+            processInputFrame(inputData, inputChannelCount);
+            inputData += inputChannelCount;
+            processOutputFrame(outputData, outputChannelCount);
+            outputData += outputChannelCount;
+        }
+        // If there is more input than output.
+        for (int i = numBoth; i < numInputFrames; i++) {
+            processInputFrame(inputData, inputChannelCount);
+            inputData += inputChannelCount;
+        }
+        // If there is more output than input.
+        for (int i = numBoth; i < numOutputFrames; i++) {
+            processOutputFrame(outputData, outputChannelCount);
+            outputData += outputChannelCount;
+        }
+    }
+
+    virtual std::string analyze() = 0;
+
+    virtual void printStatus() {};
+
+    int32_t getResult() {
+        return mResult;
+    }
+
+    void setResult(int32_t result) {
+        mResult = result;
+    }
+
+    virtual bool isDone() {
+        return false;
+    }
+
+    virtual int save(const char *fileName) {
+        (void) fileName;
+        return -1;
+    }
+
+    virtual int load(const char *fileName) {
+        (void) fileName;
+        return -1;
+    }
+
+    virtual void setSampleRate(int32_t sampleRate) {
+        mSampleRate = sampleRate;
+    }
+
+    int32_t getSampleRate() const {
+        return mSampleRate;
+    }
+
+    int32_t getResetCount() const {
+        return mResetCount;
+    }
+
+    /** Called when not enough input frames could be read after synchronization.
+     */
+    virtual void onInsufficientRead() {
+        reset();
+    }
+
+protected:
+    int32_t   mResetCount = 0;
+
+private:
+    int32_t mSampleRate = kDefaultSampleRate;
+    int32_t mResult = 0;
+};
+
+class LatencyAnalyzer : public LoopbackProcessor {
+public:
+
+    LatencyAnalyzer() : LoopbackProcessor() {}
+    virtual ~LatencyAnalyzer() = default;
+
+    virtual int32_t getProgress() const = 0;
+
+    virtual int getState() = 0;
+
+    // @return latency in frames
+    virtual int32_t getMeasuredLatency() = 0;
+
+    virtual double getMeasuredConfidence() = 0;
+
+    virtual double getBackgroundRMS() = 0;
+
+    virtual double getSignalRMS() = 0;
+
+};
+
+// ====================================================================================
+/**
+ * Measure latency given a loopback stream data.
+ * Use an encoded bit train as the sound source because it
+ * has an unambiguous correlation value.
+ * Uses a state machine to cycle through various stages.
+ *
+ */
+class PulseLatencyAnalyzer : public LatencyAnalyzer {
+public:
+
+    PulseLatencyAnalyzer() : LatencyAnalyzer() {
+        int32_t maxLatencyFrames = getSampleRate() * kMaxLatencyMillis / kMillisPerSecond;
+        int32_t numPulseBits = getSampleRate() * kPulseLengthMillis
+                / (kFramesPerEncodedBit * kMillisPerSecond);
+        int32_t  pulseLength = numPulseBits * kFramesPerEncodedBit;
+        mFramesToRecord = pulseLength + maxLatencyFrames;
+        mAudioRecording.allocate(mFramesToRecord);
+        mAudioRecording.setSampleRate(getSampleRate());
+        generateRandomPulse(pulseLength);
+    }
+
+    void generateRandomPulse(int32_t pulseLength) {
+        mPulse.allocate(pulseLength);
+        RandomPulseGenerator pulser(kFramesPerEncodedBit);
+        for (int i = 0; i < pulseLength; i++) {
+            mPulse.write(pulser.nextFloat());
+        }
+    }
+
+    int getState() override {
+        return mState;
+    }
+
+    void setSampleRate(int32_t sampleRate) override {
+        LoopbackProcessor::setSampleRate(sampleRate);
+        mAudioRecording.setSampleRate(sampleRate);
+    }
+
+    void reset() override {
+        LoopbackProcessor::reset();
+        mDownCounter = getSampleRate() / 2;
+        mLoopCounter = 0;
+
+        mPulseCursor = 0;
+        mBackgroundSumSquare = 0.0f;
+        mBackgroundSumCount = 0;
+        mBackgroundRMS = 0.0f;
+        mSignalRMS = 0.0f;
+
+        mState = STATE_MEASURE_BACKGROUND;
+        mAudioRecording.clear();
+        mLatencyReport.reset();
+    }
+
+    bool hasEnoughData() {
+        return mAudioRecording.isFull();
+    }
+
+    bool isDone() override {
+        return mState == STATE_DONE;
+    }
+
+    int32_t getProgress() const override {
+        return mAudioRecording.size();
+    }
+
+    std::string analyze() override {
+        std::stringstream report;
+        report << "PulseLatencyAnalyzer ---------------\n";
+        report << LOOPBACK_RESULT_TAG "test.state             = "
+                << std::setw(8) << mState << "\n";
+        report << LOOPBACK_RESULT_TAG "test.state.name        = "
+                << convertStateToText(mState) << "\n";
+        report << LOOPBACK_RESULT_TAG "background.rms         = "
+                << std::setw(8) << mBackgroundRMS << "\n";
+
+        int32_t newResult = RESULT_OK;
+        if (mState != STATE_GOT_DATA) {
+            report << "WARNING - Bad state. Check volume on device.\n";
+            // setResult(ERROR_INVALID_STATE);
+        } else {
+            float gain = mAudioRecording.normalize(1.0f);
+            measureLatencyFromPulse(mAudioRecording,
+                                    mPulse,
+                                    &mLatencyReport);
+
+            if (mLatencyReport.confidence < kMinimumConfidence) {
+                report << "   ERROR - confidence too low!";
+                newResult = ERROR_CONFIDENCE;
+            } else {
+                mSignalRMS = calculateRootMeanSquare(
+                        &mAudioRecording.getData()[mLatencyReport.latencyInFrames], mPulse.size())
+                                / gain;
+            }
+            double latencyMillis = kMillisPerSecond * (double) mLatencyReport.latencyInFrames
+                                   / getSampleRate();
+            report << LOOPBACK_RESULT_TAG "latency.frames         = " << std::setw(8)
+                   << mLatencyReport.latencyInFrames << "\n";
+            report << LOOPBACK_RESULT_TAG "latency.msec           = " << std::setw(8)
+                   << latencyMillis << "\n";
+            report << LOOPBACK_RESULT_TAG "latency.confidence     = " << std::setw(8)
+                   << mLatencyReport.confidence << "\n";
+        }
+        mState = STATE_DONE;
+        if (getResult() == RESULT_OK) {
+            setResult(newResult);
+        }
+
+        return report.str();
+    }
+
+    int32_t getMeasuredLatency() override {
+        return mLatencyReport.latencyInFrames;
+    }
+
+    double getMeasuredConfidence() override {
+        return mLatencyReport.confidence;
+    }
+
+    double getBackgroundRMS() override {
+        return mBackgroundRMS;
+    }
+
+    double getSignalRMS() override {
+        return mSignalRMS;
+    }
+
+    bool isRecordingComplete() {
+        return mState == STATE_GOT_DATA;
+    }
+
+    void printStatus() override {
+        ALOGD("latency: st = %d = %s", mState, convertStateToText(mState));
+    }
+
+    result_code processInputFrame(float *frameData, int channelCount) override {
+        echo_state nextState = mState;
+        mLoopCounter++;
+
+        switch (mState) {
+            case STATE_MEASURE_BACKGROUND:
+                // Measure background RMS on channel 0
+                mBackgroundSumSquare += frameData[0] * frameData[0];
+                mBackgroundSumCount++;
+                mDownCounter--;
+                if (mDownCounter <= 0) {
+                    mBackgroundRMS = sqrtf(mBackgroundSumSquare / mBackgroundSumCount);
+                    nextState = STATE_IN_PULSE;
+                    mPulseCursor = 0;
+                }
+                break;
+
+            case STATE_IN_PULSE:
+                // Record input until the mAudioRecording is full.
+                mAudioRecording.write(frameData, channelCount, 1);
+                if (hasEnoughData()) {
+                    nextState = STATE_GOT_DATA;
+                }
+                break;
+
+            case STATE_GOT_DATA:
+            case STATE_DONE:
+            default:
+                break;
+        }
+
+        mState = nextState;
+        return RESULT_OK;
+    }
+
+    result_code processOutputFrame(float *frameData, int channelCount) override {
+        switch (mState) {
+            case STATE_IN_PULSE:
+                if (mPulseCursor < mPulse.size()) {
+                    float pulseSample = mPulse.getData()[mPulseCursor++];
+                    for (int i = 0; i < channelCount; i++) {
+                        frameData[i] = pulseSample;
+                    }
+                } else {
+                    for (int i = 0; i < channelCount; i++) {
+                        frameData[i] = 0;
+                    }
+                }
+                break;
+
+            case STATE_MEASURE_BACKGROUND:
+            case STATE_GOT_DATA:
+            case STATE_DONE:
+            default:
+                for (int i = 0; i < channelCount; i++) {
+                    frameData[i] = 0.0f; // silence
+                }
+                break;
+        }
+
+        return RESULT_OK;
+    }
+
+private:
+
+    enum echo_state {
+        STATE_MEASURE_BACKGROUND,
+        STATE_IN_PULSE,
+        STATE_GOT_DATA, // must match RoundTripLatencyActivity.java
+        STATE_DONE,
+    };
+
+    const char *convertStateToText(echo_state state) {
+        switch (state) {
+            case STATE_MEASURE_BACKGROUND:
+                return "INIT";
+            case STATE_IN_PULSE:
+                return "PULSE";
+            case STATE_GOT_DATA:
+                return "GOT_DATA";
+            case STATE_DONE:
+                return "DONE";
+        }
+        return "UNKNOWN";
+    }
+
+    int32_t         mDownCounter = 500;
+    int32_t         mLoopCounter = 0;
+    echo_state      mState = STATE_MEASURE_BACKGROUND;
+
+    static constexpr int32_t kFramesPerEncodedBit = 8; // multiple of 2
+    static constexpr int32_t kPulseLengthMillis = 500;
+
+    AudioRecording     mPulse;
+    int32_t            mPulseCursor = 0;
+
+    double             mBackgroundSumSquare = 0.0;
+    int32_t            mBackgroundSumCount = 0;
+    double             mBackgroundRMS = 0.0;
+    double             mSignalRMS = 0.0;
+    int32_t            mFramesToRecord = 0;
+
+    AudioRecording     mAudioRecording; // contains only the input after starting the pulse
+    LatencyReport      mLatencyReport;
+};
+
+#endif // ANALYZER_LATENCY_ANALYZER_H
diff --git a/apps/CtsVerifier/jni/audio_loopback/analyzer/ManchesterEncoder.h b/apps/CtsVerifier/jni/audio_loopback/analyzer/ManchesterEncoder.h
new file mode 100644
index 0000000..3f7eebb
--- /dev/null
+++ b/apps/CtsVerifier/jni/audio_loopback/analyzer/ManchesterEncoder.h
@@ -0,0 +1,98 @@
+/*
+ * Copyright 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef ANALYZER_MANCHESTER_ENCODER_H
+#define ANALYZER_MANCHESTER_ENCODER_H
+
+#include <cstdint>
+
+/**
+ * Encode bytes using Manchester Coding scheme.
+ *
+ * Manchester Code is self clocking.
+ * There is a transition in the middle of every bit.
+ * Zero is high then low.
+ * One is low then high.
+ *
+ * This avoids having long DC sections that would droop when
+ * passed though analog circuits with AC coupling.
+ *
+ * IEEE 802.3 compatible.
+ */
+
+class ManchesterEncoder {
+public:
+    ManchesterEncoder(int samplesPerPulse)
+            : mSamplesPerPulse(samplesPerPulse)
+            , mSamplesPerPulseHalf(samplesPerPulse / 2)
+            , mCursor(samplesPerPulse) {
+    }
+
+    virtual ~ManchesterEncoder() = default;
+
+    /**
+     * This will be called when the next byte is needed.
+     * @return
+     */
+    virtual uint8_t onNextByte() = 0;
+
+    /**
+     * Generate the next floating point sample.
+     * @return
+     */
+    virtual float nextFloat() {
+        advanceSample();
+        if (mCurrentBit) {
+            return (mCursor < mSamplesPerPulseHalf) ? -1.0f : 1.0f; // one
+        } else {
+            return (mCursor < mSamplesPerPulseHalf) ? 1.0f : -1.0f; // zero
+        }
+    }
+
+protected:
+    /**
+     * This will be called when a new bit is ready to be encoded.
+     * It can be used to prepare the encoded samples.
+     * @param current
+     */
+    virtual void onNextBit(bool /* current */) {};
+
+    void advanceSample() {
+        // Are we ready for a new bit?
+        if (++mCursor >= mSamplesPerPulse) {
+            mCursor = 0;
+            if (mBitsLeft == 0) {
+                mCurrentByte = onNextByte();
+                mBitsLeft = 8;
+            }
+            --mBitsLeft;
+            mCurrentBit = (mCurrentByte >> mBitsLeft) & 1;
+            onNextBit(mCurrentBit);
+        }
+    }
+
+    bool getCurrentBit() {
+        return mCurrentBit;
+    }
+
+    const int mSamplesPerPulse;
+    const int mSamplesPerPulseHalf;
+    int       mCursor;
+    int       mBitsLeft = 0;
+    uint8_t   mCurrentByte = 0;
+    bool      mCurrentBit = false;
+};
+#endif //ANALYZER_MANCHESTER_ENCODER_H
diff --git a/apps/CtsVerifier/jni/audio_loopback/analyzer/PeakDetector.h b/apps/CtsVerifier/jni/audio_loopback/analyzer/PeakDetector.h
new file mode 100644
index 0000000..e407eac
--- /dev/null
+++ b/apps/CtsVerifier/jni/audio_loopback/analyzer/PeakDetector.h
@@ -0,0 +1,68 @@
+/*
+ * Copyright 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef ANALYZER_PEAK_DETECTOR_H
+#define ANALYZER_PEAK_DETECTOR_H
+
+#include <math.h>
+
+/**
+ * Measure a peak envelope by rising with the peaks,
+ * and decaying exponentially after each peak.
+ * The absolute value of the input signal is used.
+ */
+class PeakDetector {
+public:
+
+    void reset() {
+        mLevel = 0.0;
+    }
+
+    double process(double input) {
+        mLevel *= mDecay; // exponential decay
+        input = fabs(input);
+        // never fall below the input signal
+        if (input > mLevel) {
+            mLevel = input;
+        }
+        return mLevel;
+    }
+
+    double getLevel() const {
+        return mLevel;
+    }
+
+    double getDecay() const {
+        return mDecay;
+    }
+
+    /**
+     * Multiply the level by this amount on every iteration.
+     * This provides an exponential decay curve.
+     * A value just under 1.0 is best, for example, 0.99;
+     * @param decay scale level for each input
+     */
+    void setDecay(double decay) {
+        mDecay = decay;
+    }
+
+private:
+    static constexpr double kDefaultDecay = 0.99f;
+
+    double mLevel = 0.0;
+    double mDecay = kDefaultDecay;
+};
+#endif //ANALYZER_PEAK_DETECTOR_H
diff --git a/apps/CtsVerifier/jni/audio_loopback/analyzer/PseudoRandom.h b/apps/CtsVerifier/jni/audio_loopback/analyzer/PseudoRandom.h
new file mode 100644
index 0000000..d8f5894
--- /dev/null
+++ b/apps/CtsVerifier/jni/audio_loopback/analyzer/PseudoRandom.h
@@ -0,0 +1,57 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+
+#ifndef ANALYZER_PSEUDORANDOM_H
+#define ANALYZER_PSEUDORANDOM_H
+
+#include <cctype>
+
+class PseudoRandom {
+public:
+    PseudoRandom(int64_t seed = 99887766)
+            :    mSeed(seed)
+    {}
+
+    /**
+     * Returns the next random double from -1.0 to 1.0
+     *
+     * @return value from -1.0 to 1.0
+     */
+    double nextRandomDouble() {
+        return nextRandomInteger() * (0.5 / (((int32_t)1) << 30));
+    }
+
+    /** Calculate random 32 bit number using linear-congruential method
+     * with known real-time performance.
+     */
+    int32_t nextRandomInteger() {
+#if __has_builtin(__builtin_mul_overflow) && __has_builtin(__builtin_add_overflow)
+        int64_t prod;
+        // Use values for 64-bit sequence from MMIX by Donald Knuth.
+        __builtin_mul_overflow(mSeed, (int64_t)6364136223846793005, &prod);
+        __builtin_add_overflow(prod, (int64_t)1442695040888963407, &mSeed);
+#else
+        mSeed = (mSeed * (int64_t)6364136223846793005) + (int64_t)1442695040888963407;
+#endif
+        return (int32_t) (mSeed >> 32); // The higher bits have a longer sequence.
+    }
+
+private:
+    int64_t mSeed;
+};
+
+#endif //ANALYZER_PSEUDORANDOM_H
diff --git a/apps/CtsVerifier/jni/audio_loopback/analyzer/RandomPulseGenerator.h b/apps/CtsVerifier/jni/audio_loopback/analyzer/RandomPulseGenerator.h
new file mode 100644
index 0000000..b057d09
--- /dev/null
+++ b/apps/CtsVerifier/jni/audio_loopback/analyzer/RandomPulseGenerator.h
@@ -0,0 +1,43 @@
+/*
+ * Copyright 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef ANALYZER_RANDOM_PULSE_GENERATOR_H
+#define ANALYZER_RANDOM_PULSE_GENERATOR_H
+
+#include <stdlib.h>
+#include "RoundedManchesterEncoder.h"
+
+/**
+ * Encode random ones and zeros using Manchester Code per IEEE 802.3.
+ */
+class RandomPulseGenerator : public RoundedManchesterEncoder {
+public:
+    RandomPulseGenerator(int samplesPerPulse)
+    : RoundedManchesterEncoder(samplesPerPulse) {
+    }
+
+    virtual ~RandomPulseGenerator() = default;
+
+    /**
+     * This will be called when the next byte is needed.
+     * @return random byte
+     */
+    uint8_t onNextByte() override {
+        return static_cast<uint8_t>(rand());
+    }
+};
+
+#endif //ANALYZER_RANDOM_PULSE_GENERATOR_H
diff --git a/apps/CtsVerifier/jni/audio_loopback/analyzer/RoundedManchesterEncoder.h b/apps/CtsVerifier/jni/audio_loopback/analyzer/RoundedManchesterEncoder.h
new file mode 100644
index 0000000..76f57e7
--- /dev/null
+++ b/apps/CtsVerifier/jni/audio_loopback/analyzer/RoundedManchesterEncoder.h
@@ -0,0 +1,88 @@
+/*
+ * Copyright 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef ANALYZER_ROUNDED_MANCHESTER_ENCODER_H
+#define ANALYZER_ROUNDED_MANCHESTER_ENCODER_H
+
+#include <math.h>
+#include <memory.h>
+#include <stdlib.h>
+#include "ManchesterEncoder.h"
+
+/**
+ * Encode bytes using Manchester Code.
+ * Round the edges using a half cosine to reduce ringing caused by a hard edge.
+ */
+
+class RoundedManchesterEncoder : public ManchesterEncoder {
+public:
+    RoundedManchesterEncoder(int samplesPerPulse)
+            : ManchesterEncoder(samplesPerPulse) {
+        int rampSize = samplesPerPulse / 4;
+        mZeroAfterZero = std::make_unique<float[]>(samplesPerPulse);
+        mZeroAfterOne = std::make_unique<float[]>(samplesPerPulse);
+
+        int sampleIndex = 0;
+        for (int rampIndex = 0; rampIndex < rampSize; rampIndex++) {
+            float phase = (rampIndex + 1) * M_PI / rampSize;
+            float sample = -cosf(phase);
+            mZeroAfterZero[sampleIndex] = sample;
+            mZeroAfterOne[sampleIndex] = 1.0f;
+            sampleIndex++;
+        }
+        for (int rampIndex = 0; rampIndex < rampSize; rampIndex++) {
+            mZeroAfterZero[sampleIndex] = 1.0f;
+            mZeroAfterOne[sampleIndex] = 1.0f;
+            sampleIndex++;
+        }
+        for (int rampIndex = 0; rampIndex < rampSize; rampIndex++) {
+            float phase = (rampIndex + 1) * M_PI / rampSize;
+            float sample = cosf(phase);
+            mZeroAfterZero[sampleIndex] = sample;
+            mZeroAfterOne[sampleIndex] = sample;
+            sampleIndex++;
+        }
+        for (int rampIndex = 0; rampIndex < rampSize; rampIndex++) {
+            mZeroAfterZero[sampleIndex] = -1.0f;
+            mZeroAfterOne[sampleIndex] = -1.0f;
+            sampleIndex++;
+        }
+    }
+
+    void onNextBit(bool current) override {
+        // Do we need to use the rounded edge?
+        mCurrentSamples = (current ^ mPreviousBit)
+                          ? mZeroAfterOne.get()
+                          : mZeroAfterZero.get();
+        mPreviousBit = current;
+    }
+
+    float nextFloat() override {
+        advanceSample();
+        float output = mCurrentSamples[mCursor];
+        if (getCurrentBit()) output = -output;
+        return output;
+    }
+
+private:
+
+    bool mPreviousBit = false;
+    float *mCurrentSamples = nullptr;
+    std::unique_ptr<float[]> mZeroAfterZero;
+    std::unique_ptr<float[]> mZeroAfterOne;
+};
+
+#endif //ANALYZER_ROUNDED_MANCHESTER_ENCODER_H
diff --git a/apps/CtsVerifier/jni/audio_loopback/audio_utils/atomic.c b/apps/CtsVerifier/jni/audio_loopback/audio_utils/atomic.c
deleted file mode 100644
index db2b3fc..0000000
--- a/apps/CtsVerifier/jni/audio_loopback/audio_utils/atomic.c
+++ /dev/null
@@ -1,31 +0,0 @@
-/*
- * Copyright (C) 2015 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include "atomic.h"
-
-#include <stdatomic.h>
-
-int32_t android_atomic_acquire_load(volatile const int32_t* addr)
-{
-    volatile atomic_int_least32_t* a = (volatile atomic_int_least32_t*)addr;
-    return atomic_load_explicit(a, memory_order_acquire);
-}
-
-void android_atomic_release_store(int32_t value, volatile int32_t* addr)
-{
-    volatile atomic_int_least32_t* a = (volatile atomic_int_least32_t*)addr;
-    atomic_store_explicit(a, value, memory_order_release);
-}
diff --git a/apps/CtsVerifier/jni/audio_loopback/audio_utils/atomic.h b/apps/CtsVerifier/jni/audio_loopback/audio_utils/atomic.h
deleted file mode 100644
index 535c926..0000000
--- a/apps/CtsVerifier/jni/audio_loopback/audio_utils/atomic.h
+++ /dev/null
@@ -1,33 +0,0 @@
-/*
- * Copyright (C) 2015 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef ANDROID_AUDIO_ATOMIC_H
-#define ANDROID_AUDIO_ATOMIC_H
-
-#include <stdlib.h>
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-int32_t android_atomic_acquire_load(volatile const int32_t* addr);
-void android_atomic_release_store(int32_t value, volatile int32_t* addr);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif // ANDROID_AUDIO_ATOMIC_H
diff --git a/apps/CtsVerifier/jni/audio_loopback/audio_utils/fifo.c b/apps/CtsVerifier/jni/audio_loopback/audio_utils/fifo.c
deleted file mode 100644
index ea9a8d1..0000000
--- a/apps/CtsVerifier/jni/audio_loopback/audio_utils/fifo.c
+++ /dev/null
@@ -1,135 +0,0 @@
-/*
- * Copyright (C) 2015 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-//#define LOG_NDEBUG 0
-#define LOG_TAG "audio_utils_fifo"
-
-#include <stdlib.h>
-#include <string.h>
-#include "fifo.h"
-#include "roundup.h"
-#include "atomic.h"
-//#include <cutils/log.h>
-#define ALOG_ASSERT(exp)
-
-void audio_utils_fifo_init(struct audio_utils_fifo *fifo, size_t frameCount, size_t frameSize,
-        void *buffer)
-{
-    // We would need a 64-bit roundup to support larger frameCount.
-    ALOG_ASSERT(fifo != NULL && frameCount > 0 && frameSize > 0 && buffer != NULL);
-    fifo->mFrameCount = frameCount;
-    fifo->mFrameCountP2 = roundup(frameCount);
-    fifo->mFudgeFactor = fifo->mFrameCountP2 - fifo->mFrameCount;
-    fifo->mFrameSize = frameSize;
-    fifo->mBuffer = buffer;
-    fifo->mFront = 0;
-    fifo->mRear = 0;
-}
-
-void audio_utils_fifo_deinit(struct audio_utils_fifo *fifo __unused)
-{
-}
-
-// Return a new index as the sum of an old index (either mFront or mRear) and a specified increment.
-static inline int32_t audio_utils_fifo_sum(struct audio_utils_fifo *fifo, int32_t index,
-        uint32_t increment)
-{
-    if (fifo->mFudgeFactor) {
-        uint32_t mask = fifo->mFrameCountP2 - 1;
-        ALOG_ASSERT((index & mask) < fifo->mFrameCount);
-        ALOG_ASSERT(/*0 <= increment &&*/ increment <= fifo->mFrameCountP2);
-        if ((index & mask) + increment >= fifo->mFrameCount) {
-            increment += fifo->mFudgeFactor;
-        }
-        index += increment;
-        ALOG_ASSERT((index & mask) < fifo->mFrameCount);
-        return index;
-    } else {
-        return index + increment;
-    }
-}
-
-// Return the difference between two indices: rear - front, where 0 <= difference <= mFrameCount.
-static inline size_t audio_utils_fifo_diff(struct audio_utils_fifo *fifo, int32_t rear,
-        int32_t front)
-{
-    int32_t diff = rear - front;
-    if (fifo->mFudgeFactor) {
-        uint32_t mask = ~(fifo->mFrameCountP2 - 1);
-        int32_t genDiff = (rear & mask) - (front & mask);
-        if (genDiff != 0) {
-            ALOG_ASSERT(genDiff == (int32_t) fifo->mFrameCountP2);
-            diff -= fifo->mFudgeFactor;
-        }
-    }
-    // FIFO should not be overfull
-    ALOG_ASSERT(0 <= diff && diff <= (int32_t) fifo->mFrameCount);
-    return (size_t) diff;
-}
-
-ssize_t audio_utils_fifo_write(struct audio_utils_fifo *fifo, const void *buffer, size_t count)
-{
-    int32_t front = android_atomic_acquire_load(&fifo->mFront);
-    int32_t rear = fifo->mRear;
-    size_t availToWrite = fifo->mFrameCount - audio_utils_fifo_diff(fifo, rear, front);
-    if (availToWrite > count) {
-        availToWrite = count;
-    }
-    rear &= fifo->mFrameCountP2 - 1;
-    size_t part1 = fifo->mFrameCount - rear;
-    if (part1 > availToWrite) {
-        part1 = availToWrite;
-    }
-    if (part1 > 0) {
-        memcpy((char *) fifo->mBuffer + (rear * fifo->mFrameSize), buffer,
-                part1 * fifo->mFrameSize);
-        size_t part2 = availToWrite - part1;
-        if (part2 > 0) {
-            memcpy(fifo->mBuffer, (char *) buffer + (part1 * fifo->mFrameSize),
-                    part2 * fifo->mFrameSize);
-        }
-        android_atomic_release_store(audio_utils_fifo_sum(fifo, fifo->mRear, availToWrite),
-                &fifo->mRear);
-    }
-    return availToWrite;
-}
-
-ssize_t audio_utils_fifo_read(struct audio_utils_fifo *fifo, void *buffer, size_t count)
-{
-    int32_t rear = android_atomic_acquire_load(&fifo->mRear);
-    int32_t front = fifo->mFront;
-    size_t availToRead = audio_utils_fifo_diff(fifo, rear, front);
-    if (availToRead > count) {
-        availToRead = count;
-    }
-    front &= fifo->mFrameCountP2 - 1;
-    size_t part1 = fifo->mFrameCount - front;
-    if (part1 > availToRead) {
-        part1 = availToRead;
-    }
-    if (part1 > 0) {
-        memcpy(buffer, (char *) fifo->mBuffer + (front * fifo->mFrameSize),
-                part1 * fifo->mFrameSize);
-        size_t part2 = availToRead - part1;
-        if (part2 > 0) {
-            memcpy((char *) buffer + (part1 * fifo->mFrameSize), fifo->mBuffer,
-                    part2 * fifo->mFrameSize);
-        }
-        android_atomic_release_store(audio_utils_fifo_sum(fifo, fifo->mFront, availToRead),
-                &fifo->mFront);
-    }
-    return availToRead;
-}
diff --git a/apps/CtsVerifier/jni/audio_loopback/audio_utils/fifo.h b/apps/CtsVerifier/jni/audio_loopback/audio_utils/fifo.h
deleted file mode 100644
index ba4c5c6..0000000
--- a/apps/CtsVerifier/jni/audio_loopback/audio_utils/fifo.h
+++ /dev/null
@@ -1,86 +0,0 @@
-/*
- * Copyright (C) 2015 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef ANDROID_AUDIO_FIFO_H
-#define ANDROID_AUDIO_FIFO_H
-
-#include <stdlib.h>
-
-// FIXME use atomic_int_least32_t and new atomic operations instead of legacy Android ones
-// #include <stdatomic.h>
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-// Single writer, single reader non-blocking FIFO.
-// Writer and reader must be in same process.
-
-// No user-serviceable parts within.
-struct audio_utils_fifo {
-    // These fields are const after initialization
-    size_t     mFrameCount;   // max number of significant frames to be stored in the FIFO > 0
-    size_t     mFrameCountP2; // roundup(mFrameCount)
-    size_t     mFudgeFactor;  // mFrameCountP2 - mFrameCount, the number of "wasted" frames after
-                              // the end of mBuffer.  Only the indices are wasted, not any memory.
-    size_t     mFrameSize;    // size of each frame in bytes
-    void      *mBuffer;       // pointer to caller-allocated buffer of size mFrameCount frames
-
-    volatile int32_t mFront; // frame index of first frame slot available to read, or read index
-    volatile int32_t mRear;  // frame index of next frame slot available to write, or write index
-};
-
-// Initialize a FIFO object.
-// Input parameters:
-//  fifo        Pointer to the FIFO object.
-//  frameCount  Max number of significant frames to be stored in the FIFO > 0.
-//              If writes and reads always use the same count, and that count is a divisor of
-//              frameCount, then the writes and reads will never do a partial transfer.
-//  frameSize   Size of each frame in bytes.
-//  buffer      Pointer to a caller-allocated buffer of frameCount frames.
-void audio_utils_fifo_init(struct audio_utils_fifo *fifo, size_t frameCount, size_t frameSize,
-        void *buffer);
-
-// De-initialize a FIFO object.
-// Input parameters:
-//  fifo        Pointer to the FIFO object.
-void audio_utils_fifo_deinit(struct audio_utils_fifo *fifo);
-
-// Write to FIFO.
-// Input parameters:
-//  fifo        Pointer to the FIFO object.
-//  buffer      Pointer to source buffer containing 'count' frames of data.
-// Returns actual number of frames written <= count.
-// The actual transfer count may be zero if the FIFO is full,
-// or partial if the FIFO was almost full.
-// A negative return value indicates an error.  Currently there are no errors defined.
-ssize_t audio_utils_fifo_write(struct audio_utils_fifo *fifo, const void *buffer, size_t count);
-
-// Read from FIFO.
-// Input parameters:
-//  fifo        Pointer to the FIFO object.
-//  buffer      Pointer to destination buffer to be filled with up to 'count' frames of data.
-// Returns actual number of frames read <= count.
-// The actual transfer count may be zero if the FIFO is empty,
-// or partial if the FIFO was almost empty.
-// A negative return value indicates an error.  Currently there are no errors defined.
-ssize_t audio_utils_fifo_read(struct audio_utils_fifo *fifo, void *buffer, size_t count);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif  // !ANDROID_AUDIO_FIFO_H
diff --git a/apps/CtsVerifier/jni/audio_loopback/audio_utils/roundup.c b/apps/CtsVerifier/jni/audio_loopback/audio_utils/roundup.c
deleted file mode 100644
index 4f9af6a..0000000
--- a/apps/CtsVerifier/jni/audio_loopback/audio_utils/roundup.c
+++ /dev/null
@@ -1,32 +0,0 @@
-/*
- * Copyright (C) 2012 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include "roundup.h"
-
-unsigned roundup(unsigned v)
-{
-    // __builtin_clz is undefined for zero input
-    if (v == 0) {
-        v = 1;
-    }
-    int lz = __builtin_clz((int) v);
-    unsigned rounded = ((unsigned) 0x80000000) >> lz;
-    // 0x800000001 and higher are actually rounded _down_ to prevent overflow
-    if (v > rounded && lz > 0) {
-        rounded <<= 1;
-    }
-    return rounded;
-}
diff --git a/apps/CtsVerifier/jni/audio_loopback/jni-bridge.cpp b/apps/CtsVerifier/jni/audio_loopback/jni-bridge.cpp
new file mode 100644
index 0000000..a851cbe
--- /dev/null
+++ b/apps/CtsVerifier/jni/audio_loopback/jni-bridge.cpp
@@ -0,0 +1,116 @@
+/*
+ * Copyright 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <cassert>
+#include <cstring>
+#include <jni.h>
+#include <stdint.h>
+
+#include "NativeAudioAnalyzer.h"
+
+extern "C" {
+
+JNIEXPORT jlong JNICALL Java_com_android_cts_verifier_audio_NativeAnalyzerThread_openAudio
+  (JNIEnv * /*env */, jobject /* obj */,
+          jint /* micSource */) {
+    // It is OK to use a raw pointer here because the pointer will be passed back
+    // to Java and only used from one thread.
+    // Java then deletes it from that same thread by calling _closeAudio() below.
+    NativeAudioAnalyzer * analyzer = new NativeAudioAnalyzer();
+    aaudio_result_t result = analyzer->openAudio();
+    if (result != AAUDIO_OK) {
+        delete analyzer;
+        analyzer = nullptr;
+    }
+    return (jlong) analyzer;
+}
+
+JNIEXPORT jint JNICALL Java_com_android_cts_verifier_audio_NativeAnalyzerThread_startAudio
+  (JNIEnv *env __unused, jobject obj __unused, jlong pAnalyzer) {
+    NativeAudioAnalyzer * analyzer = (NativeAudioAnalyzer *) pAnalyzer;
+    int result = AAUDIO_ERROR_NULL;
+    if (analyzer != nullptr) {
+        result = analyzer->startAudio();
+    }
+    return result;
+}
+
+JNIEXPORT jint JNICALL Java_com_android_cts_verifier_audio_NativeAnalyzerThread_stopAudio
+  (JNIEnv *env __unused, jobject obj __unused, jlong pAnalyzer) {
+    NativeAudioAnalyzer * analyzer = (NativeAudioAnalyzer *) pAnalyzer;
+    if (analyzer != nullptr) {
+        return analyzer->stopAudio();
+    }
+    return AAUDIO_ERROR_NULL;
+}
+
+JNIEXPORT jint JNICALL Java_com_android_cts_verifier_audio_NativeAnalyzerThread_closeAudio
+  (JNIEnv *env __unused, jobject obj __unused, jlong pAnalyzer) {
+    NativeAudioAnalyzer * analyzer = (NativeAudioAnalyzer *) pAnalyzer;
+    int result = AAUDIO_ERROR_NULL;
+    if (analyzer != nullptr) {
+        result = analyzer->closeAudio();
+        delete analyzer;
+    }
+    return result;
+}
+
+JNIEXPORT jboolean JNICALL Java_com_android_cts_verifier_audio_NativeAnalyzerThread_isRecordingComplete
+  (JNIEnv *env __unused, jobject obj __unused, jlong pAnalyzer) {
+    NativeAudioAnalyzer * analyzer = (NativeAudioAnalyzer *) pAnalyzer;
+    if (analyzer != nullptr) {
+        return analyzer->isRecordingComplete();
+    }
+    return false;
+}
+
+JNIEXPORT jint JNICALL Java_com_android_cts_verifier_audio_NativeAnalyzerThread_getError
+  (JNIEnv *env __unused, jobject obj __unused, jlong pAnalyzer) {
+    NativeAudioAnalyzer * analyzer = (NativeAudioAnalyzer *) pAnalyzer;
+    if (analyzer != nullptr) {
+        return (jint) analyzer->getError();
+    }
+    return (jint) AAUDIO_ERROR_NULL;
+}
+
+JNIEXPORT jint JNICALL Java_com_android_cts_verifier_audio_NativeAnalyzerThread_analyze
+  (JNIEnv *env __unused, jobject obj __unused, jlong pAnalyzer) {
+    NativeAudioAnalyzer * analyzer = (NativeAudioAnalyzer *) pAnalyzer;
+    if (analyzer != nullptr) {
+        return analyzer->analyze();
+    }
+    return AAUDIO_ERROR_NULL;
+}
+
+JNIEXPORT jdouble JNICALL Java_com_android_cts_verifier_audio_NativeAnalyzerThread_getLatencyMillis
+  (JNIEnv *env __unused, jobject obj __unused, jlong pAnalyzer) {
+    NativeAudioAnalyzer * analyzer = (NativeAudioAnalyzer *) pAnalyzer;
+    if (analyzer != nullptr) {
+        return analyzer->getLatencyMillis();
+    }
+    return -1.0;
+}
+
+JNIEXPORT jdouble JNICALL Java_com_android_cts_verifier_audio_NativeAnalyzerThread_getConfidence
+  (JNIEnv *env __unused, jobject obj __unused, jlong pAnalyzer) {
+    NativeAudioAnalyzer * analyzer = (NativeAudioAnalyzer *) pAnalyzer;
+    if (analyzer != nullptr) {
+        return analyzer->getConfidence();
+    }
+    return 0.0;
+}
+
+}
diff --git a/apps/CtsVerifier/jni/audio_loopback/jni_sles.c b/apps/CtsVerifier/jni/audio_loopback/jni_sles.c
deleted file mode 100644
index e8a837e..0000000
--- a/apps/CtsVerifier/jni/audio_loopback/jni_sles.c
+++ /dev/null
@@ -1,65 +0,0 @@
-/*
- * Copyright (C) 2015 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include <android/log.h>
-#include "sles.h"
-#include "jni_sles.h"
-#include <stdio.h>
-#include <stddef.h>
-
-/////
-JNIEXPORT jlong JNICALL Java_com_android_cts_verifier_audio_NativeAudioThread_slesInit
-  (JNIEnv *env __unused, jobject obj __unused, jint samplingRate, jint frameCount,
-   jint micSource, jint numFramesToIgnore) {
-
-    sles_data * pSles = NULL;
-
-    if (slesInit(&pSles, samplingRate, frameCount, micSource, numFramesToIgnore) != SLES_FAIL) {
-
-        return (long)pSles;
-    }
-    // FIXME This should be stored as a (long) field in the object,
-    //       so that incorrect Java code could not synthesize a bad sles pointer.
-    return 0;
-}
-
-JNIEXPORT jint JNICALL Java_com_android_cts_verifier_audio_NativeAudioThread_slesProcessNext
-  (JNIEnv *env __unused, jobject obj __unused, jlong sles, jdoubleArray samplesArray,
-          jlong offset) {
-    sles_data * pSles= (sles_data*) ((long)sles);
-
-    long maxSamples = (*env)->GetArrayLength(env, samplesArray);
-    double *pSamples = (*env)->GetDoubleArrayElements(env, samplesArray,0);
-
-    long availableSamples = maxSamples-offset;
-    double *pCurrentSample = pSamples+offset;
-
-    SLES_PRINTF("jni slesProcessNext pSles:%p, currentSample %p, availableSamples %ld ", pSles,
-            pCurrentSample, availableSamples);
-
-    int samplesRead = slesProcessNext(pSles, pCurrentSample, availableSamples);
-
-    return samplesRead;
-}
-
-JNIEXPORT jint JNICALL Java_com_android_cts_verifier_audio_NativeAudioThread_slesDestroy
-  (JNIEnv *env __unused, jobject obj __unused, jlong sles) {
-    sles_data * pSles= (sles_data*) ((long) sles);
-
-    int status = slesDestroy(&pSles);
-
-    return status;
-}
diff --git a/apps/CtsVerifier/jni/audio_loopback/jni_sles.h b/apps/CtsVerifier/jni/audio_loopback/jni_sles.h
deleted file mode 100644
index d7aa625..0000000
--- a/apps/CtsVerifier/jni/audio_loopback/jni_sles.h
+++ /dev/null
@@ -1,40 +0,0 @@
-/*
- * Copyright (C) 2015 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include <jni.h>
-
-#ifndef _Included_org_drrickorang_loopback_jni
-#define _Included_org_drrickorang_loopback_jni
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-
-////////////////////////
-JNIEXPORT jlong JNICALL Java_com_android_cts_verifier_audio_NativeAudioThread_slesInit
-  (JNIEnv *, jobject, jint, jint, jint, jint );
-
-JNIEXPORT jint JNICALL Java_com_android_cts_verifier_audio_NativeAudioThread_slesProcessNext
-  (JNIEnv *, jobject , jlong, jdoubleArray, jlong );
-
-JNIEXPORT jint JNICALL Java_com_android_cts_verifier_audio_NativeAudioThread_slesDestroy
-  (JNIEnv *, jobject , jlong );
-
-
-#ifdef __cplusplus
-}
-#endif
-#endif //_Included_org_drrickorang_loopback_jni
diff --git a/apps/CtsVerifier/jni/audio_loopback/sles.cpp b/apps/CtsVerifier/jni/audio_loopback/sles.cpp
deleted file mode 100644
index 586c60f..0000000
--- a/apps/CtsVerifier/jni/audio_loopback/sles.cpp
+++ /dev/null
@@ -1,673 +0,0 @@
-/*
- * Copyright (C) 2015 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-
-////////////////////////////////////////////
-/// Actual sles functions.
-
-
-// Test program to record from default audio input and playback to default audio output.
-// It will generate feedback (Larsen effect) if played through on-device speakers,
-// or acts as a delay if played through headset.
-
-#include "sles.h"
-#include <stdio.h>
-#include <stdlib.h>
-#include <stddef.h>
-
-#include <assert.h>
-#include <pthread.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <unistd.h>
-
-int slesInit(sles_data ** ppSles, int samplingRate, int frameCount, int micSource,
-             int numFramesToIgnore) {
-    int status = SLES_FAIL;
-    if (ppSles != NULL) {
-        sles_data * pSles = (sles_data*) calloc(1, sizeof (sles_data));
-
-        SLES_PRINTF("malloc %zu bytes at %p", sizeof(sles_data), pSles);
-        *ppSles = pSles;
-        if (pSles != NULL)
-        {
-            SLES_PRINTF("creating server. Sampling rate =%d, frame count = %d",samplingRate,
-                    frameCount);
-            status = slesCreateServer(pSles, samplingRate, frameCount, micSource,
-                                      numFramesToIgnore);
-            SLES_PRINTF("slesCreateServer =%d", status);
-        }
-    }
-    return status;
-}
-int slesDestroy(sles_data ** ppSles) {
-    int status = SLES_FAIL;
-    if (ppSles != NULL) {
-        slesDestroyServer(*ppSles);
-
-        if (*ppSles != NULL)
-        {
-            free(*ppSles);
-            *ppSles = 0;
-        }
-        status = SLES_SUCCESS;
-    }
-    return status;
-}
-
-#define ASSERT_EQ(x, y) do { if ((x) == (y)) ; else { fprintf(stderr, "0x%x != 0x%x\n", \
-        (unsigned) (x), (unsigned) (y)); assert((x) == (y)); } } while (0)
-
-
-// Called after audio recorder fills a buffer with data
-static void recorderCallback(SLAndroidSimpleBufferQueueItf caller __unused, void *context) {
-    sles_data *pSles = (sles_data*) context;
-    if (pSles != NULL) {
-
-
-
-        SLresult result;
-
-        pthread_mutex_lock(&(pSles->mutex));
-        //ee  SLES_PRINTF("<R");
-
-        // We should only be called when a recording buffer is done
-        assert(pSles->rxFront <= pSles->rxBufCount);
-        assert(pSles->rxRear <= pSles->rxBufCount);
-        assert(pSles->rxFront != pSles->rxRear);
-        char *buffer = pSles->rxBuffers[pSles->rxFront];
-
-        // Remove buffer from record queue
-        if (++pSles->rxFront > pSles->rxBufCount) {
-            pSles->rxFront = 0;
-        }
-
-        // Throw out first frames
-        if (pSles->numFramesToIgnore) {
-            SLuint32 framesToErase = pSles->numFramesToIgnore;
-            if (framesToErase > pSles->bufSizeInFrames) {
-                framesToErase = pSles->bufSizeInFrames;
-            }
-            pSles->numFramesToIgnore -= framesToErase;
-            // FIXME: this assumes each sample is a short
-            memset(buffer, 0, framesToErase * pSles->channels * sizeof(short));
-        }
-
-        ssize_t actual = audio_utils_fifo_write(&(pSles->fifo), buffer,
-                (size_t) pSles->bufSizeInFrames);
-        if (actual != (ssize_t) pSles->bufSizeInFrames) {
-            write(1, "?", 1);
-        }
-
-        // This is called by a realtime (SCHED_FIFO) thread,
-        // and it is unsafe to do I/O as it could block for unbounded time.
-        // Flash filesystem is especially notorious for blocking.
-        if (pSles->fifo2Buffer != NULL) {
-            actual = audio_utils_fifo_write(&(pSles->fifo2), buffer,
-                    (size_t) pSles->bufSizeInFrames);
-            if (actual != (ssize_t) pSles->bufSizeInFrames) {
-                write(1, "?", 1);
-            }
-        }
-
-        // Enqueue this same buffer for the recorder to fill again.
-        result = (*(pSles->recorderBufferQueue))->Enqueue(pSles->recorderBufferQueue, buffer,
-                pSles->bufSizeInBytes);
-        ASSERT_EQ(SL_RESULT_SUCCESS, result);
-
-        // Update our model of the record queue
-        SLuint32 rxRearNext = pSles->rxRear+1;
-        if (rxRearNext > pSles->rxBufCount) {
-            rxRearNext = 0;
-        }
-        assert(rxRearNext != pSles->rxFront);
-        pSles->rxBuffers[pSles->rxRear] = buffer;
-        pSles->rxRear = rxRearNext;
-
-
-
-        //ee  SLES_PRINTF("r>");
-        pthread_mutex_unlock(&(pSles->mutex));
-
-    } //pSles not null
-}
-
-
-// Called after audio player empties a buffer of data
-static void playerCallback(SLBufferQueueItf caller __unused, void *context) {
-    sles_data *pSles = (sles_data*) context;
-    if (pSles != NULL) {
-
-        SLresult result;
-
-        pthread_mutex_lock(&(pSles->mutex));
-        //ee  SLES_PRINTF("<P");
-
-        // Get the buffer that just finished playing
-        assert(pSles->txFront <= pSles->txBufCount);
-        assert(pSles->txRear <= pSles->txBufCount);
-        assert(pSles->txFront != pSles->txRear);
-        char *buffer = pSles->txBuffers[pSles->txFront];
-        if (++pSles->txFront > pSles->txBufCount) {
-            pSles->txFront = 0;
-        }
-
-
-        ssize_t actual = audio_utils_fifo_read(&(pSles->fifo), buffer, pSles->bufSizeInFrames);
-        if (actual != (ssize_t) pSles->bufSizeInFrames) {
-            write(1, "/", 1);
-            // on underrun from pipe, substitute silence
-            memset(buffer, 0, pSles->bufSizeInFrames * pSles->channels * sizeof(short));
-        }
-
-        if (pSles->injectImpulse == -1) {
-            // Experimentally, a single frame impulse was insufficient to trigger feedback.
-            // Also a Nyquist frequency signal was also insufficient, probably because
-            // the response of output and/or input path was not adequate at high frequencies.
-            // This short burst of a few cycles of square wave at Nyquist/4 was found to work well.
-            for (unsigned i = 0; i < pSles->bufSizeInFrames / 8; i += 8) {
-                for (int j = 0; j < 8; j++) {
-                    for (unsigned k = 0; k < pSles->channels; k++) {
-                        ((short *)buffer)[(i+j)*pSles->channels+k] = j < 4 ? 0x7FFF : 0x8000;
-                    }
-                }
-            }
-            pSles->injectImpulse = 0;
-        }
-
-        // Enqueue the filled buffer for playing
-        result = (*(pSles->playerBufferQueue))->Enqueue(pSles->playerBufferQueue, buffer,
-                pSles->bufSizeInBytes);
-        ASSERT_EQ(SL_RESULT_SUCCESS, result);
-
-        // Update our model of the player queue
-        assert(pSles->txFront <= pSles->txBufCount);
-        assert(pSles->txRear <= pSles->txBufCount);
-        SLuint32 txRearNext = pSles->txRear+1;
-        if (txRearNext > pSles->txBufCount) {
-            txRearNext = 0;
-        }
-        assert(txRearNext != pSles->txFront);
-        pSles->txBuffers[pSles->txRear] = buffer;
-        pSles->txRear = txRearNext;
-
-
-        //ee    SLES_PRINTF("p>");
-        pthread_mutex_unlock(&(pSles->mutex));
-
-    } //pSles not null
-}
-
-int slesCreateServer(sles_data *pSles, int samplingRate, int frameCount,
-                     int micSource, int numFramesToIgnore) {
-    int status = SLES_FAIL;
-
-    if (pSles == NULL) {
-        return status;
-    }
-
-    //        adb shell slesTest_feedback -r1 -t1 -s48000 -f240 -i300 -e3 -o/sdcard/log.wav
-    //            r1 and t1 are the receive and transmit buffer counts, typically 1
-    //            s is the sample rate, typically 48000 or 44100
-    //            f is the frame count per buffer, typically 240 or 256
-    //            i is the number of milliseconds before impulse.  You may need to adjust this.
-    //            e is number of seconds to record
-    //            o is output .wav file name
-
-
-    //        // default values
-    //        SLuint32 rxBufCount = 1;     // -r#
-    //        SLuint32 txBufCount = 1;     // -t#
-    //        SLuint32 bufSizeInFrames = 240;  // -f#
-    //        SLuint32 channels = 1;       // -c#
-    //        SLuint32 sampleRate = 48000; // -s#
-    //        SLuint32 exitAfterSeconds = 3; // -e#
-    //        SLuint32 freeBufCount = 0;   // calculated
-    //        SLuint32 bufSizeInBytes = 0; // calculated
-    //        int injectImpulse = 300; // -i#i
-    //
-    //        // Storage area for the buffer queues
-    //        char **rxBuffers;
-    //        char **txBuffers;
-    //        char **freeBuffers;
-    //
-    //        // Buffer indices
-    //        SLuint32 rxFront;    // oldest recording
-    //        SLuint32 rxRear;     // next to be recorded
-    //        SLuint32 txFront;    // oldest playing
-    //        SLuint32 txRear;     // next to be played
-    //        SLuint32 freeFront;  // oldest free
-    //        SLuint32 freeRear;   // next to be freed
-    //
-    //        audio_utils_fifo fifo; //(*)
-    //        SLAndroidSimpleBufferQueueItf recorderBufferQueue;
-    //        SLBufferQueueItf playerBufferQueue;
-
-    // default values
-    pSles->rxBufCount = 1;     // -r#
-    pSles->txBufCount = 1;     // -t#
-    pSles->bufSizeInFrames = frameCount;//240;  // -f#
-    pSles->channels = 1;       // -c#
-    pSles->sampleRate = samplingRate;//48000; // -s#
-    pSles->exitAfterSeconds = 3; // -e#
-    pSles->freeBufCount = 0;   // calculated
-    pSles->bufSizeInBytes = 0; // calculated
-    pSles->injectImpulse = 300; // -i#i
-
-    if (numFramesToIgnore > 0) {
-        pSles->numFramesToIgnore = numFramesToIgnore;
-    } else {
-        pSles->numFramesToIgnore = 0;
-    }
-
-    // Storage area for the buffer queues
-    //        char **rxBuffers;
-    //        char **txBuffers;
-    //        char **freeBuffers;
-
-    // Buffer indices
-/*
-    pSles->rxFront;    // oldest recording
-    pSles->rxRear;     // next to be recorded
-    pSles->txFront;    // oldest playing
-    pSles->txRear;     // next to be played
-    pSles->freeFront;  // oldest free
-    pSles->freeRear;   // next to be freed
-
-    pSles->fifo; //(*)
-*/
-    pSles->fifo2Buffer = NULL;
-
-    // compute total free buffers as -r plus -t
-    pSles->freeBufCount = pSles->rxBufCount + pSles->txBufCount;
-    // compute buffer size
-    pSles->bufSizeInBytes = pSles->channels * pSles->bufSizeInFrames * sizeof(short);
-
-    // Initialize free buffers
-    pSles->freeBuffers = (char **) calloc(pSles->freeBufCount+1, sizeof(char *));
-    unsigned j;
-    for (j = 0; j < pSles->freeBufCount; ++j) {
-        pSles->freeBuffers[j] = (char *) malloc(pSles->bufSizeInBytes);
-    }
-    pSles->freeFront = 0;
-    pSles->freeRear = pSles->freeBufCount;
-    pSles->freeBuffers[j] = NULL;
-
-    // Initialize record queue
-    pSles->rxBuffers = (char **) calloc(pSles->rxBufCount+1, sizeof(char *));
-    pSles->rxFront = 0;
-    pSles->rxRear = 0;
-
-    // Initialize play queue
-    pSles->txBuffers = (char **) calloc(pSles->txBufCount+1, sizeof(char *));
-    pSles->txFront = 0;
-    pSles->txRear = 0;
-
-    size_t frameSize = pSles->channels * sizeof(short);
-#define FIFO_FRAMES 1024
-    pSles->fifoBuffer = new short[FIFO_FRAMES * pSles->channels];
-    audio_utils_fifo_init(&(pSles->fifo), FIFO_FRAMES, frameSize, pSles->fifoBuffer);
-
-    //        SNDFILE *sndfile;
-    //        if (outFileName != NULL) {
-    // create .wav writer
-    //            SF_INFO info;
-    //            info.frames = 0;
-    //            info.samplerate = sampleRate;
-    //            info.channels = channels;
-    //            info.format = SF_FORMAT_WAV | SF_FORMAT_PCM_16;
-    //            sndfile = sf_open(outFileName, SFM_WRITE, &info);
-    //            if (sndfile != NULL) {
-#define FIFO2_FRAMES 65536
-    pSles->fifo2Buffer = new short[FIFO2_FRAMES * pSles->channels];
-    audio_utils_fifo_init(&(pSles->fifo2), FIFO2_FRAMES, frameSize, pSles->fifo2Buffer);
-    //            } else {
-    //                fprintf(stderr, "sf_open failed\n");
-    //            }
-    //        } else {
-    //            sndfile = NULL;
-    //        }
-
-    SLresult result;
-
-    // create engine
-    result = slCreateEngine(&(pSles->engineObject), 0, NULL, 0, NULL, NULL);
-    ASSERT_EQ(SL_RESULT_SUCCESS, result);
-    result = (*(pSles->engineObject))->Realize(pSles->engineObject, SL_BOOLEAN_FALSE);
-    ASSERT_EQ(SL_RESULT_SUCCESS, result);
-    SLEngineItf engineEngine;
-    result = (*(pSles->engineObject))->GetInterface(pSles->engineObject, SL_IID_ENGINE,
-            &engineEngine);
-    ASSERT_EQ(SL_RESULT_SUCCESS, result);
-
-    // create output mix
-    result = (*engineEngine)->CreateOutputMix(engineEngine, &(pSles->outputmixObject), 0, NULL,
-            NULL);
-    ASSERT_EQ(SL_RESULT_SUCCESS, result);
-    result = (*(pSles->outputmixObject))->Realize(pSles->outputmixObject, SL_BOOLEAN_FALSE);
-    ASSERT_EQ(SL_RESULT_SUCCESS, result);
-
-    // create an audio player with buffer queue source and output mix sink
-    SLDataSource audiosrc;
-    SLDataSink audiosnk;
-    SLDataFormat_PCM pcm;
-    SLDataLocator_OutputMix locator_outputmix;
-    SLDataLocator_BufferQueue locator_bufferqueue_tx;
-    locator_bufferqueue_tx.locatorType = SL_DATALOCATOR_BUFFERQUEUE;
-    locator_bufferqueue_tx.numBuffers = pSles->txBufCount;
-    locator_outputmix.locatorType = SL_DATALOCATOR_OUTPUTMIX;
-    locator_outputmix.outputMix = pSles->outputmixObject;
-    pcm.formatType = SL_DATAFORMAT_PCM;
-    pcm.numChannels = pSles->channels;
-    pcm.samplesPerSec = pSles->sampleRate * 1000;
-    pcm.bitsPerSample = SL_PCMSAMPLEFORMAT_FIXED_16;
-    pcm.containerSize = 16;
-    pcm.channelMask = pSles->channels == 1 ? SL_SPEAKER_FRONT_CENTER :
-            (SL_SPEAKER_FRONT_LEFT | SL_SPEAKER_FRONT_RIGHT);
-    pcm.endianness = SL_BYTEORDER_LITTLEENDIAN;
-    audiosrc.pLocator = &locator_bufferqueue_tx;
-    audiosrc.pFormat = &pcm;
-    audiosnk.pLocator = &locator_outputmix;
-    audiosnk.pFormat = NULL;
-    pSles->playerObject = NULL;
-    pSles->recorderObject = NULL;
-    SLInterfaceID ids_tx[1] = {SL_IID_BUFFERQUEUE};
-    SLboolean flags_tx[1] = {SL_BOOLEAN_TRUE};
-    result = (*engineEngine)->CreateAudioPlayer(engineEngine, &(pSles->playerObject),
-            &audiosrc, &audiosnk, 1, ids_tx, flags_tx);
-    if (SL_RESULT_CONTENT_UNSUPPORTED == result) {
-        fprintf(stderr, "Could not create audio player (result %x), check sample rate\n",
-                result);
-        SLES_PRINTF("ERROR: Could not create audio player (result %x), check sample rate\n",
-                result);
-        goto cleanup;
-    }
-    ASSERT_EQ(SL_RESULT_SUCCESS, result);
-    result = (*(pSles->playerObject))->Realize(pSles->playerObject, SL_BOOLEAN_FALSE);
-    ASSERT_EQ(SL_RESULT_SUCCESS, result);
-    SLPlayItf playerPlay;
-    result = (*(pSles->playerObject))->GetInterface(pSles->playerObject, SL_IID_PLAY,
-            &playerPlay);
-    ASSERT_EQ(SL_RESULT_SUCCESS, result);
-    result = (*(pSles->playerObject))->GetInterface(pSles->playerObject, SL_IID_BUFFERQUEUE,
-            &(pSles->playerBufferQueue));
-    ASSERT_EQ(SL_RESULT_SUCCESS, result);
-    result = (*(pSles->playerBufferQueue))->RegisterCallback(pSles->playerBufferQueue,
-            playerCallback, pSles);
-    ASSERT_EQ(SL_RESULT_SUCCESS, result);
-
-    // Enqueue some zero buffers for the player
-    for (j = 0; j < pSles->txBufCount; ++j) {
-
-        // allocate a free buffer
-        assert(pSles->freeFront != pSles->freeRear);
-        char *buffer = pSles->freeBuffers[pSles->freeFront];
-        if (++pSles->freeFront > pSles->freeBufCount) {
-            pSles->freeFront = 0;
-        }
-
-        // put on play queue
-        SLuint32 txRearNext = pSles->txRear + 1;
-        if (txRearNext > pSles->txBufCount) {
-            txRearNext = 0;
-        }
-        assert(txRearNext != pSles->txFront);
-        pSles->txBuffers[pSles->txRear] = buffer;
-        pSles->txRear = txRearNext;
-        result = (*(pSles->playerBufferQueue))->Enqueue(pSles->playerBufferQueue,
-                buffer, pSles->bufSizeInBytes);
-        ASSERT_EQ(SL_RESULT_SUCCESS, result);
-    }
-
-    result = (*playerPlay)->SetPlayState(playerPlay, SL_PLAYSTATE_PLAYING);
-    ASSERT_EQ(SL_RESULT_SUCCESS, result);
-
-    // Create an audio recorder with microphone device source and buffer queue sink.
-    // The buffer queue as sink is an Android-specific extension.
-
-    SLDataLocator_IODevice locator_iodevice;
-    SLDataLocator_AndroidSimpleBufferQueue locator_bufferqueue_rx;
-    locator_iodevice.locatorType = SL_DATALOCATOR_IODEVICE;
-    locator_iodevice.deviceType = SL_IODEVICE_AUDIOINPUT;
-    locator_iodevice.deviceID = SL_DEFAULTDEVICEID_AUDIOINPUT;
-    locator_iodevice.device = NULL;
-    audiosrc.pLocator = &locator_iodevice;
-    audiosrc.pFormat = NULL;
-    locator_bufferqueue_rx.locatorType = SL_DATALOCATOR_ANDROIDSIMPLEBUFFERQUEUE;
-    locator_bufferqueue_rx.numBuffers = pSles->rxBufCount;
-    audiosnk.pLocator = &locator_bufferqueue_rx;
-    audiosnk.pFormat = &pcm;
-    {
-        SLInterfaceID ids_rx[2] = {SL_IID_ANDROIDSIMPLEBUFFERQUEUE,
-                SL_IID_ANDROIDCONFIGURATION};
-        SLboolean flags_rx[2] = {SL_BOOLEAN_TRUE, SL_BOOLEAN_TRUE};
-        result = (*engineEngine)->CreateAudioRecorder(engineEngine, &(pSles->recorderObject),
-                &audiosrc, &audiosnk, 2, ids_rx, flags_rx);
-        if (SL_RESULT_SUCCESS != result) {
-            fprintf(stderr, "Could not create audio recorder (result %x), "
-                    "check sample rate and channel count\n", result);
-            status = SLES_FAIL;
-
-            SLES_PRINTF("ERROR: Could not create audio recorder (result %x), "
-                    "check sample rate and channel count\n", result);
-            goto cleanup;
-        }
-    }
-    ASSERT_EQ(SL_RESULT_SUCCESS, result);
-
-    {
-        /* Get the Android configuration interface which is explicit */
-        SLAndroidConfigurationItf configItf;
-        result = (*(pSles->recorderObject))->GetInterface(pSles->recorderObject,
-                SL_IID_ANDROIDCONFIGURATION, (void*)&configItf);
-        ASSERT_EQ(SL_RESULT_SUCCESS, result);
-        SLuint32 presetValue = micSource;
-        /* Use the configuration interface to configure the recorder before it's realized */
-        if (presetValue != SL_ANDROID_RECORDING_PRESET_NONE) {
-            result = (*configItf)->SetConfiguration(configItf, SL_ANDROID_KEY_RECORDING_PRESET,
-                    &presetValue, sizeof(SLuint32));
-            ASSERT_EQ(SL_RESULT_SUCCESS, result);
-        }
-
-    }
-
-    result = (*(pSles->recorderObject))->Realize(pSles->recorderObject, SL_BOOLEAN_FALSE);
-    ASSERT_EQ(SL_RESULT_SUCCESS, result);
-    SLRecordItf recorderRecord;
-    result = (*(pSles->recorderObject))->GetInterface(pSles->recorderObject, SL_IID_RECORD,
-            &recorderRecord);
-    ASSERT_EQ(SL_RESULT_SUCCESS, result);
-    result = (*(pSles->recorderObject))->GetInterface(pSles->recorderObject,
-            SL_IID_ANDROIDSIMPLEBUFFERQUEUE, &(pSles->recorderBufferQueue));
-    ASSERT_EQ(SL_RESULT_SUCCESS, result);
-    result = (*(pSles->recorderBufferQueue))->RegisterCallback(pSles->recorderBufferQueue,
-            recorderCallback, pSles);
-    ASSERT_EQ(SL_RESULT_SUCCESS, result);
-
-    // Enqueue some empty buffers for the recorder
-    for (j = 0; j < pSles->rxBufCount; ++j) {
-
-        // allocate a free buffer
-        assert(pSles->freeFront != pSles->freeRear);
-        char *buffer = pSles->freeBuffers[pSles->freeFront];
-        if (++pSles->freeFront > pSles->freeBufCount) {
-            pSles->freeFront = 0;
-        }
-
-        // put on record queue
-        SLuint32 rxRearNext = pSles->rxRear + 1;
-        if (rxRearNext > pSles->rxBufCount) {
-            rxRearNext = 0;
-        }
-        assert(rxRearNext != pSles->rxFront);
-        pSles->rxBuffers[pSles->rxRear] = buffer;
-        pSles->rxRear = rxRearNext;
-        result = (*(pSles->recorderBufferQueue))->Enqueue(pSles->recorderBufferQueue,
-                buffer, pSles->bufSizeInBytes);
-        ASSERT_EQ(SL_RESULT_SUCCESS, result);
-    }
-
-    // Kick off the recorder
-    result = (*recorderRecord)->SetRecordState(recorderRecord, SL_RECORDSTATE_RECORDING);
-    ASSERT_EQ(SL_RESULT_SUCCESS, result);
-
-    // Tear down the objects and exit
-    status = SLES_SUCCESS;
-    cleanup:
-    SLES_PRINTF("Finished initialization with status: %d", status);
-
-    return status;
-}
-
-int slesProcessNext(sles_data *pSles, double *pSamples, long maxSamples) {
-    //int status = SLES_FAIL;
-
-    SLES_PRINTF("slesProcessNext: pSles = %p, currentSample: %p,  maxSamples = %ld", pSles,
-            pSamples, maxSamples);
-
-    int samplesRead = 0;
-
-    int currentSample = 0;
-    double *pCurrentSample = pSamples;
-    int maxValue = 32768;
-
-    if (pSles == NULL) {
-        return samplesRead;
-    }
-
-    SLresult result;
-    for (int i = 0; i < 10; i++) {
-        usleep(100000);
-        if (pSles->fifo2Buffer != NULL) {
-            for (;;) {
-                short buffer[pSles->bufSizeInFrames * pSles->channels];
-                ssize_t actual = audio_utils_fifo_read(&(pSles->fifo2), buffer,
-                        pSles->bufSizeInFrames);
-                if (actual <= 0)
-                    break;
-                {
-                    for (int jj =0; jj<actual && currentSample < maxSamples; jj++) {
-                        *(pCurrentSample++) = ((double)buffer[jj])/maxValue;
-                        currentSample++;
-                    }
-                }
-                samplesRead +=actual;
-            }
-        }
-        if (pSles->injectImpulse > 0) {
-            if (pSles->injectImpulse <= 100) {
-                pSles->injectImpulse = -1;
-                write(1, "I", 1);
-            } else {
-                if ((pSles->injectImpulse % 1000) < 100) {
-                    write(1, "i", 1);
-                }
-                pSles->injectImpulse -= 100;
-            }
-        } else if (i == 9) {
-            write(1, ".", 1);
-        }
-    }
-    SLBufferQueueState playerBQState;
-    result = (*(pSles->playerBufferQueue))->GetState(pSles->playerBufferQueue,
-            &playerBQState);
-    ASSERT_EQ(SL_RESULT_SUCCESS, result);
-    SLAndroidSimpleBufferQueueState recorderBQState;
-    result = (*(pSles->recorderBufferQueue))->GetState(pSles->recorderBufferQueue,
-            &recorderBQState);
-    ASSERT_EQ(SL_RESULT_SUCCESS, result);
-
-    SLES_PRINTF("End of slesProcessNext: pSles = %p, samplesRead = %d, maxSamples= %ld", pSles,
-            samplesRead, maxSamples);
-
-    return samplesRead;
-}
-
-int slesDestroyServer(sles_data *pSles) {
-    int status = SLES_FAIL;
-
-    SLES_PRINTF("Start slesDestroyServer: pSles = %p", pSles);
-    if (pSles == NULL) {
-        return status;
-    }
-
-    if (NULL != pSles->playerObject) {
-
-        SLES_PRINTF("stopping player...");
-        SLPlayItf playerPlay;
-        SLresult result = (*(pSles->playerObject))->GetInterface(pSles->playerObject,
-                SL_IID_PLAY, &playerPlay);
-
-        ASSERT_EQ(SL_RESULT_SUCCESS, result);
-
-        //stop player and recorder if they exist
-        result = (*playerPlay)->SetPlayState(playerPlay, SL_PLAYSTATE_STOPPED);
-        ASSERT_EQ(SL_RESULT_SUCCESS, result);
-    }
-
-    if (NULL != pSles->recorderObject) {
-        SLES_PRINTF("stopping recorder...");
-        SLRecordItf recorderRecord;
-        SLresult result = (*(pSles->recorderObject))->GetInterface(pSles->recorderObject,
-                SL_IID_RECORD, &recorderRecord);
-        ASSERT_EQ(SL_RESULT_SUCCESS, result);
-
-        result = (*recorderRecord)->SetRecordState(recorderRecord, SL_RECORDSTATE_STOPPED);
-        ASSERT_EQ(SL_RESULT_SUCCESS, result);
-    }
-
-    usleep(1000);
-
-    audio_utils_fifo_deinit(&(pSles->fifo));
-    delete[] pSles->fifoBuffer;
-
-    SLES_PRINTF("slesDestroyServer 2");
-
-    //        if (sndfile != NULL) {
-    audio_utils_fifo_deinit(&(pSles->fifo2));
-    delete[] pSles->fifo2Buffer;
-
-    SLES_PRINTF("slesDestroyServer 3");
-
-    //            sf_close(sndfile);
-    //        }
-    if (NULL != pSles->playerObject) {
-        (*(pSles->playerObject))->Destroy(pSles->playerObject);
-    }
-
-    SLES_PRINTF("slesDestroyServer 4");
-
-    if (NULL != pSles->recorderObject) {
-        (*(pSles->recorderObject))->Destroy(pSles->recorderObject);
-    }
-
-    SLES_PRINTF("slesDestroyServer 5");
-
-    (*(pSles->outputmixObject))->Destroy(pSles->outputmixObject);
-    SLES_PRINTF("slesDestroyServer 6");
-    (*(pSles->engineObject))->Destroy(pSles->engineObject);
-    SLES_PRINTF("slesDestroyServer 7");
-
-    //        free(pSles);
-    //        pSles=NULL;
-
-    status = SLES_SUCCESS;
-
-    SLES_PRINTF("End slesDestroyServer: status = %d", status);
-    return status;
-}
-
diff --git a/apps/CtsVerifier/jni/audio_loopback/sles.h b/apps/CtsVerifier/jni/audio_loopback/sles.h
deleted file mode 100644
index 607f724..0000000
--- a/apps/CtsVerifier/jni/audio_loopback/sles.h
+++ /dev/null
@@ -1,96 +0,0 @@
-/*
- * Copyright (C) 2015 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include <SLES/OpenSLES.h>
-#include <SLES/OpenSLES_Android.h>
-#include <pthread.h>
-#include <android/log.h>
-
-#ifndef _Included_org_drrickorang_loopback_sles
-#define _Included_org_drrickorang_loopback_sles
-
-//struct audio_utils_fifo;
-#define SLES_PRINTF(...)  __android_log_print(ANDROID_LOG_INFO, "sles_jni", __VA_ARGS__);
-
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-#include <audio_utils/fifo.h>
-
-typedef struct {
-    SLuint32 rxBufCount;     // -r#
-    SLuint32 txBufCount;     // -t#
-    SLuint32 bufSizeInFrames;  // -f#
-    SLuint32 channels;       // -c#
-    SLuint32 sampleRate; // -s#
-    SLuint32 exitAfterSeconds; // -e#
-    SLuint32 freeBufCount;   // calculated
-    SLuint32 bufSizeInBytes; // calculated
-    int injectImpulse; // -i#i
-    SLuint32 numFramesToIgnore;
-
-    // Storage area for the buffer queues
-    char **rxBuffers;
-    char **txBuffers;
-    char **freeBuffers;
-
-    // Buffer indices
-    SLuint32 rxFront;    // oldest recording
-    SLuint32 rxRear;     // next to be recorded
-    SLuint32 txFront;    // oldest playing
-    SLuint32 txRear;     // next to be played
-    SLuint32 freeFront;  // oldest free
-    SLuint32 freeRear;   // next to be freed
-
-    struct audio_utils_fifo fifo; //(*)
-    struct audio_utils_fifo fifo2;
-    short *fifo2Buffer;
-    short *fifoBuffer;
-    SLAndroidSimpleBufferQueueItf recorderBufferQueue;
-    SLBufferQueueItf playerBufferQueue;
-
-    pthread_mutex_t mutex;// = PTHREAD_MUTEX_INITIALIZER;
-
-    //other things that belong here
-    SLObjectItf playerObject;
-    SLObjectItf recorderObject;
-    SLObjectItf outputmixObject;
-    SLObjectItf engineObject;
-} sles_data;
-
-enum {
-    SLES_SUCCESS = 0,
-    SLES_FAIL = 1,
-} SLES_STATUS_ENUM;
-
-int slesInit(sles_data ** ppSles, int samplingRate, int frameCount,
-             int micSource, int numFramesToIgnore);
-
-//note the double pointer to properly free the memory of the structure
-int slesDestroy(sles_data ** ppSles);
-
-///full
-int slesFull(sles_data *pSles);
-
-int slesCreateServer(sles_data *pSles, int samplingRate, int frameCount, int micSource, int numFramesToIgnore);
-int slesProcessNext(sles_data *pSles, double *pSamples, long maxSamples);
-int slesDestroyServer(sles_data *pSles);
-
-#ifdef __cplusplus
-}
-#endif
-#endif //_Included_org_drrickorang_loopback_sles
diff --git a/apps/CtsVerifier/res/layout/biometric_test_credential_enrolled_tests.xml b/apps/CtsVerifier/res/layout/biometric_test_credential_enrolled_tests.xml
index 722e478..a6539ba 100644
--- a/apps/CtsVerifier/res/layout/biometric_test_credential_enrolled_tests.xml
+++ b/apps/CtsVerifier/res/layout/biometric_test_credential_enrolled_tests.xml
@@ -26,10 +26,18 @@
         android:text="@string/biometric_test_credential_enrolled_instructions" />
 
     <Button
+        android:id="@+id/enroll_credential_button"
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:layout_centerInParent="true"
+        android:text="@string/biometric_test_credential_enroll_button"/>
+
+    <Button
         android:id="@+id/bm_button"
         android:layout_width="match_parent"
         android:layout_height="wrap_content"
         android:layout_centerInParent="true"
+        android:enabled="false"
         android:text="@string/biometric_test_credential_enrolled_bm_button"/>
 
     <Button
@@ -37,6 +45,7 @@
         android:layout_width="match_parent"
         android:layout_height="wrap_content"
         android:layout_centerInParent="true"
+        android:enabled="false"
         android:text="@string/biometric_test_credential_enrolled_bp_setAllowedAuthenticators_button"/>
 
     <Button
@@ -44,6 +53,7 @@
         android:layout_width="wrap_content"
         android:layout_height="wrap_content"
         android:layout_centerInParent="true"
+        android:enabled="false"
         android:text="@string/biometric_test_credential_enrolled_bp_setDeviceCredentialAllowed_button"/>
 
     <Space
diff --git a/apps/CtsVerifier/res/values/strings.xml b/apps/CtsVerifier/res/values/strings.xml
index bbc663c..3bc5bb6 100755
--- a/apps/CtsVerifier/res/values/strings.xml
+++ b/apps/CtsVerifier/res/values/strings.xml
@@ -242,9 +242,9 @@
     <string name="biometric_test_credential_not_enrolled_bp_setDeviceCredentialAllowed_button">Check BiometricPrompt setDeviceCredentialAllowed(true)</string>
 
     <string name="biometric_test_credential_enrolled_label">2) Credential Enrolled Tests</string>
-    <string name="biometric_test_credential_enrolled_instructions">This test checks that the BiometricManager/BiometricPrompt
-        APIs return results consistent with credential (PIN/Pattern/Password) state. Before starting this test, please ensure that you DO
-        have a credential set up.</string>
+    <string name="biometric_test_credential_enrolled_instructions">This test checks that apps are able to request credential enrollment, and that the BiometricManager/BiometricPrompt
+        APIs return results consistent with credential (PIN/Pattern/Password) state.</string>
+    <string name="biometric_test_credential_enroll_button">Enroll credential</string>
     <string name="biometric_test_credential_enrolled_bm_button">Check BiometricManager</string>
     <string name="biometric_test_credential_enrolled_bp_setAllowedAuthenticators_button">Check BiometricPrompt setAllowedAuthenticators(DEVICE_CREDENTIAL)</string>
     <string name="biometric_test_credential_enrolled_bp_setDeviceCredentialAllowed_button">Check BiometricPrompt setDeviceCredentialAllowed(true)</string>
@@ -278,7 +278,7 @@
 
     <string name="biometric_test_strong_label">4) Strong Biometrics + Crypto</string>
     <string name="biometric_test_strong_instructions">This test checks that the Settings.ACTION_BIOMETRIC_ENROLL and its corresponding
-        EXTRA_BIOMETRIC_MINIMUM_STRENGTH_REQUIRED APIs enroll only a STRONG biometric. Please ensure that the device
+        EXTRA_BIOMETRIC_AUTHENTICATOR_REQUIREMENTS APIs enroll only a STRONG biometric. Please ensure that the device
         does NOT have ANY biometrics enrolled before starting this test. After passing the first part of the test, it will check various use cases
         when authentication is invoked with the STRONG biometric.</string>
     <string name="biometric_test_strong_check_and_enroll_button">Start enrollment</string>
@@ -292,7 +292,7 @@
 
     <string name="biometric_test_weak_label">5) Weak Biometrics</string>
     <string name="biometric_test_weak_instructions">This test checks that the Settings.ACTION_BIOMETRIC_ENROLL and its corresponding
-        EXTRA_BIOMETRIC_MINIMUM_STRENGTH_REQUIRED APIs enroll a biometric that meets or exceeds WEAK. Please ensure that the device
+        EXTRA_BIOMETRIC_AUTHENTICATOR_REQUIREMENTS APIs enroll a biometric that meets or exceeds WEAK. Please ensure that the device
         does NOT have ANY biometrics enrolled before starting this test. After passing the first part of the test, it will check various use cases
         when authentication is invoked.</string>
     <string name="biometric_test_weak_enroll">Start enrollment</string>
@@ -1651,10 +1651,8 @@
         Click the button below to go to system settings and enable Wi-Fi and Location Mode.</string>
     <string name="wifi_settings">Wi-Fi Settings</string>
     <string name="location_settings">Location Settings</string>
-    <string name="wifi_setup_error">
-        Test failed.\n\nSet up error. Check whether Wi-Fi is enabled.</string>
-    <string name="wifi_unexpected_error">
-        Test failed.\n\nUnexpected error. Check logcat.</string>
+    <string name="wifi_setup_error">Test failed with set up error.</string>
+    <string name="wifi_unexpected_error">Test failed with unexpected error. Check logcat.</string>
 
     <string name="wifi_status_initiating_scan">Initiating scan.</string>
     <string name="wifi_status_scan_failure">Unable to initiate scan or find any open network in scan results.</string>
@@ -1662,7 +1660,9 @@
     <string name="wifi_status_initiating_network_request">Initiating network request.</string>
     <string name="wifi_status_network_wait_for_available">Waiting for network connection. Please click the network in the dialog that pops up for approving the request.</string>
     <string name="wifi_status_network_available">"Connected to network."</string>
+    <string name="wifi_status_network_available_error">Connected to network unexpectedly.</string>
     <string name="wifi_status_network_wait_for_unavailable">"Ensuring device does not connect to any network. You should see an empty dialog that pops up for approving the request."</string>
+    <string name="wifi_status_network_wait_for_unavailable_invalid_credential">"Ensuring device does not connect to the network. Please click the network in the dialog that pops up for approving the request."</string>
     <string name="wifi_status_network_unavailable">"Did not connect to any network."</string>
     <string name="wifi_status_network_wait_for_lost">Ensuring device does not disconnect from the network until the request is released.</string>
     <string name="wifi_status_network_lost">Disconnected from the network.</string>
@@ -1670,14 +1670,25 @@
 
     <string name="wifi_status_suggestion_add">Adding suggestions to the device.</string>
     <string name="wifi_status_suggestion_add_failure">Failed to add suggestions.</string>
+    <string name="wifi_status_suggestion_get_failure">Failed to get suggestions.</string>
     <string name="wifi_status_suggestion_remove">Removing suggestions from the device.</string>
     <string name="wifi_status_suggestion_remove_failure">Failed to remove suggestions.</string>
-    <string name="wifi_status_suggestion_wait_for_connect">Waiting for network connection. Please click \"Yes\" in the notification that pops up for approving the request.</string>
+    <string name="wifi_status_suggestion_wait_for_connect">Waiting for network connection. Please click \"Allow\" in the dialog that pops up for approving the app.</string>
+    <string name="wifi_status_suggestion_ensure_no_connect">Ensuring no network connection. Please click \"Allow\" in the dialog that pops up for approving the app.</string>
     <string name="wifi_status_suggestion_connect">Connected to the network.</string>
+    <string name="wifi_status_suggestion_not_connected">Did not connect to the network.</string>
     <string name="wifi_status_suggestion_wait_for_post_connect_bcast">Waiting for post connection broadcast.</string>
     <string name="wifi_status_suggestion_post_connect_bcast">Received post connection broadcast.</string>
     <string name="wifi_status_suggestion_post_connect_bcast_failure">Failed to receive post connection broadcast.</string>
-    <string name="wifi_status_suggestion_wait_for_disconnect">Ensuring device does not disconnect from the network after removing suggestions.</string>
+    <string name="wifi_status_suggestion_wait_for_connection_status">Waiting for connection status.</string>
+    <string name="wifi_status_suggestion_connection_status">Received connection status.</string>
+    <string name="wifi_status_suggestion_connection_status_failure">Failed to receive connection status.</string>
+    <string name="wifi_status_suggestion_wait_for_disconnect">Ensuring device does disconnect from the network after removing suggestions.</string>
+    <string name="wifi_status_suggestion_metered_change">Marking the network metered.</string>
+    <string name="wifi_status_suggestion_metered_check_failed">Network meteredness check failed.</string>
+    <string name="wifi_status_suggestion_metered_changed">Network marked metered successfully.</string>
+    <string name="wifi_status_suggestion_capabilities_not_changed">Network capabilities did not change.</string>
+    <string name="wifi_status_suggestion_not_disconnected">Did not disconnect from the network.</string>
     <string name="wifi_status_suggestion_disconnected">Disconnected from the network.</string>
 
     <string name="wifi_status_test_success">Test completed successfully!</string>
@@ -1690,6 +1701,8 @@
     <string name="wifi_test_network_request_pattern_info">Tests whether the API can be used to a connect to network with a SSID and BSSID pattern specified in the request.</string>
     <string name="wifi_test_network_request_unavailable">Network Request with a specific network that is unavailable.</string>
     <string name="wifi_test_network_request_unavailable_info">Tests that the API fails to connect when an unavailable network is specified in the request.</string>
+    <string name="wifi_test_network_request_invalid_credential">Network Request with a specific network with wrong credential.</string>
+    <string name="wifi_test_network_request_invalid_credential_info">Tests that the API fails to connect when a network with wrong credential is specified in the request.</string>
 
     <string name="wifi_test_network_suggestion">Network Suggestion tests</string>
     <string name="wifi_test_network_suggestion_ssid">Network suggestion with SSID.</string>
@@ -1698,6 +1711,10 @@
     <string name="wifi_test_network_suggestion_ssid_bssid_info">Tests whether the API can be used to suggest a network with SSID and specific BSSID to the device and the device connects to it.</string>
     <string name="wifi_test_network_suggestion_ssid_post_connect">Network suggestion with SSID and post connection broadcast.</string>
     <string name="wifi_test_network_suggestion_ssid_post_connect_info">Tests whether the API can be used to suggest a network with SSID to the device and the device connects to it and sends the post connect broadcast back to the app.</string>
+    <string name="wifi_test_network_suggestion_connection_failure">Network suggestion connection failure.</string>
+    <string name="wifi_test_network_suggestion_connection_failure_info">Tests whether the SuggestionConnectionStatusListener API can be used to listen to connection failures for suggested networks.</string>
+    <string name="wifi_test_network_suggestion_modification_in_place">Network suggestion modification in place.</string>
+    <string name="wifi_test_network_suggestion_modification_in_place_info">Tests whether the suggested network params can be modified in place when connected to it.</string>
 
     <!-- Strings for P2pTestActivity -->
     <string name="p2p_test">Wi-Fi Direct Test</string>
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/audio/AudioLoopbackActivity.java b/apps/CtsVerifier/src/com/android/cts/verifier/audio/AudioLoopbackActivity.java
index f5cf4e1..5c3fa9f 100644
--- a/apps/CtsVerifier/src/com/android/cts/verifier/audio/AudioLoopbackActivity.java
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/audio/AudioLoopbackActivity.java
@@ -27,6 +27,7 @@
 import android.media.AudioDeviceInfo;
 import android.media.AudioManager;
 import android.media.AudioTrack;
+import android.media.MediaRecorder;
 
 import android.os.Bundle;
 import android.os.Handler;
@@ -51,15 +52,14 @@
 
     public static final int BYTES_PER_FRAME = 2;
 
-    NativeAudioThread nativeAudioThread = null;
+    NativeAnalyzerThread mNativeAnalyzerThread = null;
 
     private int mSamplingRate = 44100;
     private int mMinBufferSizeInFrames = 0;
     private static final double CONFIDENCE_THRESHOLD = 0.6;
-    private Correlation mCorrelation = new Correlation();
 
-    // TODO: remove this variable
-    private int mNumFramesToIgnore = 0;
+    private double mLatencyMillis;
+    private double mConfidence;
 
     OnBtnClickListener mBtnClickListener = new OnBtnClickListener();
     Context mContext;
@@ -92,13 +92,13 @@
                 case R.id.audio_general_headset_yes:
                     Log.i(TAG, "User confirms Headset Port existence");
                     mLoopbackPlugReady.setEnabled(true);
-                    recordHeasetPortFound(true);
+                    recordHeadsetPortFound(true);
                     mHeadsetPortYes.setEnabled(false);
                     mHeadsetPortNo.setEnabled(false);
                     break;
                 case R.id.audio_general_headset_no:
                     Log.i(TAG, "User denies Headset Port existence");
-                    recordHeasetPortFound(false);
+                    recordHeadsetPortFound(false);
                     getPassButton().setEnabled(true);
                     mHeadsetPortYes.setEnabled(false);
                     mHeadsetPortNo.setEnabled(false);
@@ -161,6 +161,7 @@
         setPassFailButtonClickListeners();
         getPassButton().setEnabled(false);
         setInfoResources(R.string.audio_loopback_test, R.string.audio_loopback_info, -1);
+
     }
 
     /**
@@ -204,41 +205,43 @@
      */
     private void startAudioTest() {
         getPassButton().setEnabled(false);
+        mTestButton.setEnabled(false);
+        mLatencyMillis = 0.0;
+        mConfidence = 0.0;
 
-        //get system defaults for sampling rate, buffers.
-        AudioManager am = (AudioManager) getSystemService(Context.AUDIO_SERVICE);
-        String value = am.getProperty(AudioManager.PROPERTY_OUTPUT_FRAMES_PER_BUFFER);
-        mMinBufferSizeInFrames = Integer.parseInt(value);
-
-        int minBufferSizeInBytes = BYTES_PER_FRAME * mMinBufferSizeInFrames;
-
-        mSamplingRate = AudioTrack.getNativeOutputSampleRate(AudioManager.STREAM_MUSIC);
-
-        Log.i(TAG, String.format("startAudioTest sr:%d , buffer:%d frames",
-                mSamplingRate, mMinBufferSizeInFrames));
-
-        nativeAudioThread = new NativeAudioThread();
-        if (nativeAudioThread != null) {
-            nativeAudioThread.setMessageHandler(mMessageHandler);
-            nativeAudioThread.mSessionId = 0;
-            nativeAudioThread.setParams(mSamplingRate,
-                    minBufferSizeInBytes,
-                    minBufferSizeInBytes,
-                    0x03 /*voice recognition*/,
-                    mNumFramesToIgnore);
-            nativeAudioThread.start();
+        mNativeAnalyzerThread = new NativeAnalyzerThread();
+        if (mNativeAnalyzerThread != null) {
+            mNativeAnalyzerThread.setMessageHandler(mMessageHandler);
+            // This value matches AAUDIO_INPUT_PRESET_VOICE_RECOGNITION
+            mNativeAnalyzerThread.setInputPreset(MediaRecorder.AudioSource.VOICE_RECOGNITION);
+            mNativeAnalyzerThread.startTest();
 
             try {
                 Thread.sleep(200);
             } catch (InterruptedException e) {
                 e.printStackTrace();
             }
-
-            nativeAudioThread.runTest();
-
         }
     }
 
+    private void handleTestCompletion() {
+        recordTestResults();
+        boolean resultValid = mConfidence >= CONFIDENCE_THRESHOLD
+                && mLatencyMillis > 1.0;
+        getPassButton().setEnabled(resultValid);
+
+        // Make sure the test thread is finished. It should already be done.
+        if (mNativeAnalyzerThread != null) {
+            try {
+                mNativeAnalyzerThread.stopTest(2 * 1000);
+            } catch (InterruptedException e) {
+                e.printStackTrace();
+            }
+        }
+        showWait(false);
+        mTestButton.setEnabled(true);
+    }
+
     /**
      * handler for messages from audio thread
      */
@@ -246,45 +249,35 @@
         public void handleMessage(Message msg) {
             super.handleMessage(msg);
             switch(msg.what) {
-                case NativeAudioThread.NATIVE_AUDIO_THREAD_MESSAGE_REC_STARTED:
+                case NativeAnalyzerThread.NATIVE_AUDIO_THREAD_MESSAGE_REC_STARTED:
                     Log.v(TAG,"got message native rec started!!");
                     showWait(true);
                     mResultText.setText("Test Running...");
                     break;
-                case NativeAudioThread.NATIVE_AUDIO_THREAD_MESSAGE_REC_ERROR:
+                case NativeAnalyzerThread.NATIVE_AUDIO_THREAD_MESSAGE_OPEN_ERROR:
                     Log.v(TAG,"got message native rec can't start!!");
-                    showWait(false);
-                    mResultText.setText("Test Error.");
+                    mResultText.setText("Test Error opening streams.");
+                    handleTestCompletion();
                     break;
-                case NativeAudioThread.NATIVE_AUDIO_THREAD_MESSAGE_REC_COMPLETE:
-                case NativeAudioThread.NATIVE_AUDIO_THREAD_MESSAGE_REC_COMPLETE_ERRORS:
-                    if (nativeAudioThread != null) {
-                        Log.v(TAG,"Finished recording.");
-                        double [] waveData = nativeAudioThread.getWaveData();
-                        mCorrelation.computeCorrelation(waveData, mSamplingRate);
-                        mResultText.setText(String.format(
-                                "Test Finished\nLatency:%.2f ms\nConfidence: %.2f",
-                                mCorrelation.mEstimatedLatencyMs,
-                                mCorrelation.mEstimatedLatencyConfidence));
-
-                        recordTestResults();
-                        if (mCorrelation.mEstimatedLatencyConfidence >= CONFIDENCE_THRESHOLD) {
-                            getPassButton().setEnabled(true);
-                        }
-
-                        //close
-                        if (nativeAudioThread != null) {
-                            nativeAudioThread.isRunning = false;
-                            try {
-                                nativeAudioThread.finish();
-                                nativeAudioThread.join();
-                            } catch (InterruptedException e) {
-                                e.printStackTrace();
-                            }
-                            nativeAudioThread = null;
-                        }
-                        showWait(false);
+                case NativeAnalyzerThread.NATIVE_AUDIO_THREAD_MESSAGE_REC_ERROR:
+                    Log.v(TAG,"got message native rec can't start!!");
+                    mResultText.setText("Test Error while recording.");
+                    handleTestCompletion();
+                    break;
+                case NativeAnalyzerThread.NATIVE_AUDIO_THREAD_MESSAGE_REC_COMPLETE_ERRORS:
+                    mResultText.setText("Test FAILED due to errors.");
+                    handleTestCompletion();
+                    break;
+                case NativeAnalyzerThread.NATIVE_AUDIO_THREAD_MESSAGE_REC_COMPLETE:
+                    if (mNativeAnalyzerThread != null) {
+                        mLatencyMillis = mNativeAnalyzerThread.getLatencyMillis();
+                        mConfidence = mNativeAnalyzerThread.getConfidence();
                     }
+                    mResultText.setText(String.format(
+                            "Test Finished\nLatency:%.2f ms\nConfidence: %.2f",
+                            mLatencyMillis,
+                            mConfidence));
+                    handleTestCompletion();
                     break;
                 default:
                     break;
@@ -299,13 +292,13 @@
 
         getReportLog().addValue(
                 "Estimated Latency",
-                mCorrelation.mEstimatedLatencyMs,
+                mLatencyMillis,
                 ResultType.LOWER_BETTER,
                 ResultUnit.MS);
 
         getReportLog().addValue(
                 "Confidence",
-                mCorrelation.mEstimatedLatencyConfidence,
+                mConfidence,
                 ResultType.HIGHER_BETTER,
                 ResultUnit.NONE);
 
@@ -331,7 +324,7 @@
         Log.v(TAG,"Results Recorded");
     }
 
-    private void recordHeasetPortFound(boolean found) {
+    private void recordHeadsetPortFound(boolean found) {
         getReportLog().addValue(
                 "User Reported Headset Port",
                 found ? 1.0 : 0,
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/audio/Correlation.java b/apps/CtsVerifier/src/com/android/cts/verifier/audio/Correlation.java
deleted file mode 100644
index c653d1d..0000000
--- a/apps/CtsVerifier/src/com/android/cts/verifier/audio/Correlation.java
+++ /dev/null
@@ -1,169 +0,0 @@
-/*
- * Copyright (C) 2015 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.cts.verifier.audio;
-
-import android.util.Log;
-
-
-public class Correlation {
-
-    private int mBlockSize = 4096;
-    private int mSamplingRate = 44100;
-    private double [] mDataDownsampled = new double [mBlockSize];
-    private double [] mDataAutocorrelated = new double[mBlockSize];
-
-    public double mEstimatedLatencySamples = 0;
-    public double mEstimatedLatencyMs = 0;
-    public double mEstimatedLatencyConfidence = 0.0;
-
-    private double mAmplitudeThreshold = 0.001;  // 0.001 = -60 dB noise
-
-    public void init(int blockSize, int samplingRate) {
-        mBlockSize = blockSize;
-        mSamplingRate = samplingRate;
-    }
-
-    public boolean computeCorrelation(double [] data, int samplingRate) {
-        boolean status = false;
-        log("Started Auto Correlation for data with " + data.length + " points");
-        mSamplingRate = samplingRate;
-
-        downsampleData(data, mDataDownsampled, mAmplitudeThreshold);
-
-        //correlation vector
-        autocorrelation(mDataDownsampled, mDataAutocorrelated);
-
-        int N = data.length; //all samples available
-        double groupSize =  (double) N / mBlockSize;  //samples per downsample point.
-
-        double maxValue = 0;
-        int maxIndex = -1;
-
-        double minLatencyMs = 8; //min latency expected. This algorithm should be improved.
-        int minIndex = (int)(0.5 + minLatencyMs * mSamplingRate / (groupSize*1000));
-
-        double average = 0;
-        double rms = 0;
-        //find max
-        for (int i=minIndex; i<mDataAutocorrelated.length; i++) {
-            average += mDataAutocorrelated[i];
-            rms += mDataAutocorrelated[i]*mDataAutocorrelated[i];
-            if (mDataAutocorrelated[i] > maxValue) {
-                maxValue = mDataAutocorrelated[i];
-                maxIndex = i;
-            }
-        }
-
-        rms = Math.sqrt(rms/mDataAutocorrelated.length);
-        average = average/mDataAutocorrelated.length;
-        log(String.format(" Maxvalue %f, max Index : %d/%d (%d)  minIndex=%d",maxValue, maxIndex,
-                mDataAutocorrelated.length, data.length, minIndex));
-
-        log(String.format("  average : %.3f  rms: %.3f", average, rms));
-
-        mEstimatedLatencyConfidence = 0.0;
-        if (average>0) {
-            double factor = 3.0;
-
-            double raw = (rms-average) /(factor*average);
-            log(String.format("Raw: %.3f",raw));
-            mEstimatedLatencyConfidence = Math.max(Math.min(raw, 1.0),0.0);
-        }
-
-        log(String.format(" ****Confidence: %.2f",mEstimatedLatencyConfidence));
-
-        mEstimatedLatencySamples = maxIndex*groupSize;
-
-        mEstimatedLatencyMs = mEstimatedLatencySamples *1000/mSamplingRate;
-
-        log(String.format(" latencySamples: %.2f  %.2f ms", mEstimatedLatencySamples,
-                mEstimatedLatencyMs));
-
-        status = true;
-        return status;
-    }
-
-    private boolean downsampleData(double [] data, double [] dataDownsampled, double threshold) {
-
-        boolean status = false;
-        // mDataDownsampled = new double[mBlockSize];
-        for (int i=0; i<mBlockSize; i++) {
-            dataDownsampled[i] = 0;
-        }
-
-        int N = data.length; //all samples available
-        double groupSize =  (double) N / mBlockSize;
-
-        int ignored = 0;
-
-        int currentIndex = 0;
-        double nextGroup = groupSize;
-        for (int i = 0; i<N && currentIndex<mBlockSize; i++) {
-
-            if (i> nextGroup) { //advanced to next group.
-                currentIndex++;
-                nextGroup += groupSize;
-            }
-
-            if (currentIndex>=mBlockSize) {
-                break;
-            }
-
-            double value =  Math.abs(data[i]);
-            if (value >= threshold) {
-                dataDownsampled[currentIndex] += value;
-            } else {
-                ignored++;
-            }
-        }
-
-        log(String.format(" Threshold: %.3f, ignored:%d/%d (%.2f)", threshold, ignored, N,
-                (double) ignored/(double)N));
-
-        status = true;
-        return status;
-    }
-
-    private boolean autocorrelation(double [] data, double [] dataOut) {
-        boolean status = false;
-
-        double sumsquared = 0;
-        int N = data.length;
-        for (int i=0; i<N; i++) {
-            double value = data[i];
-            sumsquared += value*value;
-        }
-
-        if (sumsquared>0) {
-            for (int i = 0; i < N; i++) {
-                dataOut[i] = 0;
-                for (int j = 0; j < N - i; j++) {
-
-                    dataOut[i] += data[j] * data[i + j];
-                }
-                dataOut[i] = dataOut[i] / sumsquared;
-            }
-            status = true;
-        }
-
-        return status;
-    }
-
-    private static void log(String msg) {
-        Log.v("Recorder", msg);
-    }
-}
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/audio/NativeAnalyzerThread.java b/apps/CtsVerifier/src/com/android/cts/verifier/audio/NativeAnalyzerThread.java
new file mode 100644
index 0000000..42f22aa
--- /dev/null
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/audio/NativeAnalyzerThread.java
@@ -0,0 +1,187 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+
+package com.android.cts.verifier.audio;
+
+import android.media.AudioFormat;
+import android.media.AudioManager;
+import android.media.AudioTrack;
+import android.media.MediaRecorder;
+import android.media.AudioRecord;
+import android.media.MediaRecorder;
+import android.util.Log;
+
+import android.os.Handler;
+import  android.os.Message;
+
+/**
+ * A thread that runs a native audio loopback analyzer.
+ */
+public class NativeAnalyzerThread {
+    private final int mSecondsToRun = 5;
+    private Handler mMessageHandler;
+    private Thread mThread;
+    private volatile boolean mEnabled = false;
+    private volatile double mLatencyMillis = 0.0;
+    private volatile double mConfidence = 0.0;
+    private int mInputPreset = 0;
+
+    static final int NATIVE_AUDIO_THREAD_MESSAGE_REC_STARTED = 892;
+    static final int NATIVE_AUDIO_THREAD_MESSAGE_OPEN_ERROR = 893;
+    static final int NATIVE_AUDIO_THREAD_MESSAGE_REC_ERROR = 894;
+    static final int NATIVE_AUDIO_THREAD_MESSAGE_REC_COMPLETE = 895;
+    static final int NATIVE_AUDIO_THREAD_MESSAGE_REC_COMPLETE_ERRORS = 896;
+
+    public void setInputPreset(int inputPreset) {
+        mInputPreset = inputPreset;
+    }
+
+    //JNI load
+    static {
+        try {
+            System.loadLibrary("audioloopback_jni");
+        } catch (UnsatisfiedLinkError e) {
+            log("Error loading loopback JNI library");
+            e.printStackTrace();
+        }
+
+        /* TODO: gracefully fail/notify if the library can't be loaded */
+    }
+
+    /**
+     * @return native audio context
+     */
+    private native long openAudio(int micSource);
+    private native int startAudio(long audio_context);
+    private native int stopAudio(long audio_context);
+    private native int closeAudio(long audio_context);
+    private native int getError(long audio_context);
+    private native boolean isRecordingComplete(long audio_context);
+    private native int analyze(long audio_context);
+    private native double getLatencyMillis(long audio_context);
+    private native double getConfidence(long audio_context);
+
+    public double getLatencyMillis() {
+        return mLatencyMillis;
+    }
+
+    public double getConfidence() {
+        return mConfidence;
+    }
+
+    public synchronized void startTest() {
+        if (mThread == null) {
+            mEnabled = true;
+            mThread = new Thread(mBackGroundTask);
+            mThread.start();
+        }
+    }
+
+    public synchronized void stopTest(int millis) throws InterruptedException {
+        mEnabled = false;
+        if (mThread != null) {
+            mThread.interrupt();
+            mThread.join(millis);
+            mThread = null;
+        }
+    }
+
+    private void sendMessage(int what) {
+        if (mMessageHandler != null) {
+            Message msg = Message.obtain();
+            msg.what = what;
+            mMessageHandler.sendMessage(msg);
+        }
+    }
+
+    private Runnable mBackGroundTask = () -> {
+        mLatencyMillis = 0.0;
+        mConfidence = 0.0;
+        boolean analysisComplete = false;
+
+        log(" Started capture test");
+        sendMessage(NATIVE_AUDIO_THREAD_MESSAGE_REC_STARTED);
+
+        long audioContext = openAudio(mInputPreset);
+        log(String.format("audioContext = 0x%X",audioContext));
+
+        if (audioContext == 0 ) {
+            log(" ERROR at JNI initialization");
+            sendMessage(NATIVE_AUDIO_THREAD_MESSAGE_OPEN_ERROR);
+        }  else if (mEnabled) {
+            int result = startAudio(audioContext);
+            if (result < 0) {
+                sendMessage(NATIVE_AUDIO_THREAD_MESSAGE_REC_ERROR);
+                mEnabled = false;
+            }
+
+            final long timeoutMillis = mSecondsToRun * 1000;
+            final long startedAtMillis = System.currentTimeMillis();
+            boolean timedOut = false;
+            int loopCounter = 0;
+            while (mEnabled && !timedOut) {
+                result = getError(audioContext);
+                if (result < 0) {
+                    sendMessage(NATIVE_AUDIO_THREAD_MESSAGE_REC_ERROR);
+                    break;
+                } else if (isRecordingComplete(audioContext)) {
+                    result = stopAudio(audioContext);
+                    if (result < 0) {
+                        sendMessage(NATIVE_AUDIO_THREAD_MESSAGE_REC_ERROR);
+                        break;
+                    }
+
+                    // Analyze the recording and measure latency.
+                    mThread.setPriority(Thread.MAX_PRIORITY);
+                    result = analyze(audioContext);
+                    if (result < 0) {
+                        break;
+                    } else {
+                        analysisComplete = true;
+                    }
+                    mLatencyMillis = getLatencyMillis(audioContext);
+                    mConfidence = getConfidence(audioContext);
+                    break;
+                } else {
+                    try {
+                        Thread.sleep(100);
+                    } catch (InterruptedException e) {
+                        e.printStackTrace();
+                    }
+                }
+                long now = System.currentTimeMillis();
+                timedOut = (now - startedAtMillis) > timeoutMillis;
+            }
+            log("latency: analyze returns " + result);
+            closeAudio(audioContext);
+
+            int what = (analysisComplete && result == 0)
+                    ? NATIVE_AUDIO_THREAD_MESSAGE_REC_COMPLETE
+                    : NATIVE_AUDIO_THREAD_MESSAGE_REC_COMPLETE_ERRORS;
+            sendMessage(what);
+        }
+    };
+
+    public void setMessageHandler(Handler messageHandler) {
+        mMessageHandler = messageHandler;
+    }
+
+    private static void log(String msg) {
+        Log.v("Loopback", msg);
+    }
+
+}  //end thread.
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/audio/NativeAudioThread.java b/apps/CtsVerifier/src/com/android/cts/verifier/audio/NativeAudioThread.java
deleted file mode 100644
index 0bb1298..0000000
--- a/apps/CtsVerifier/src/com/android/cts/verifier/audio/NativeAudioThread.java
+++ /dev/null
@@ -1,278 +0,0 @@
-/*
- * Copyright (C) 2015 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-//package org.drrickorang.loopback;
-
-package com.android.cts.verifier.audio;
-
-import android.media.AudioFormat;
-import android.media.AudioManager;
-import android.media.AudioTrack;
-//import android.media.MediaPlayer;
-import android.media.AudioRecord;
-import android.media.MediaRecorder;
-import android.util.Log;
-
-import android.os.Handler;
-import  android.os.Message;
-
-/**
- * A thread/audio track based audio synth.
- */
-public class NativeAudioThread extends Thread {
-
-    public boolean isRunning = false;
-    double twoPi = 6.28318530718;
-
-    public int mSessionId;
-
-    public double[] mvSamples; //captured samples
-    int mSamplesIndex;
-
-    private final int mSecondsToRun = 2;
-    public int mSamplingRate = 48000;
-    private int mChannelConfigIn = AudioFormat.CHANNEL_IN_MONO;
-    private int mAudioFormat = AudioFormat.ENCODING_PCM_16BIT;
-
-    int mMinPlayBufferSizeInBytes = 0;
-    int mMinRecordBuffSizeInBytes = 0;
-    private int mChannelConfigOut = AudioFormat.CHANNEL_OUT_MONO;
-
-    int mMicSource = 0;
-
-    int mNumFramesToIgnore;
-
-//    private double [] samples = new double[50000];
-
-    boolean isPlaying = false;
-    private Handler mMessageHandler;
-    boolean isDestroying = false;
-    boolean hasDestroyingErrors = false;
-
-    static final int NATIVE_AUDIO_THREAD_MESSAGE_REC_STARTED = 892;
-    static final int NATIVE_AUDIO_THREAD_MESSAGE_REC_ERROR = 893;
-    static final int NATIVE_AUDIO_THREAD_MESSAGE_REC_COMPLETE = 894;
-    static final int NATIVE_AUDIO_THREAD_MESSAGE_REC_COMPLETE_ERRORS = 895;
-
-    public void setParams(int samplingRate, int playBufferInBytes, int recBufferInBytes,
-                          int micSource, int numFramesToIgnore) {
-        mSamplingRate = samplingRate;
-        mMinPlayBufferSizeInBytes = playBufferInBytes;
-        mMinRecordBuffSizeInBytes = recBufferInBytes;
-        mMicSource = micSource;
-        mNumFramesToIgnore = numFramesToIgnore;
-    }
-
-    //JNI load
-    static {
-        try {
-            System.loadLibrary("audioloopback_jni");
-        } catch (UnsatisfiedLinkError e) {
-            log("Error loading loopback JNI library");
-            e.printStackTrace();
-        }
-
-        /* TODO: gracefully fail/notify if the library can't be loaded */
-    }
-
-    //jni calls
-    public native long slesInit(int samplingRate, int frameCount, int micSource,
-                                int numFramesToIgnore);
-    public native int slesProcessNext(long sles_data, double[] samples, long offset);
-    public native int slesDestroy(long sles_data);
-
-    public void run() {
-
-        setPriority(Thread.MAX_PRIORITY);
-        isRunning = true;
-
-        //erase output buffer
-        if (mvSamples != null)
-            mvSamples = null;
-
-        //resize
-        int nNewSize = (int)(1.1* mSamplingRate * mSecondsToRun ); //10% more just in case
-        mvSamples = new double[nNewSize];
-        mSamplesIndex = 0; //reset index
-
-        //clear samples
-        for (int i=0; i<nNewSize; i++) {
-            mvSamples[i] = 0;
-        }
-
-        //start playing
-        isPlaying = true;
-
-
-        log(" Started capture test");
-        if (mMessageHandler != null) {
-            Message msg = Message.obtain();
-            msg.what = NATIVE_AUDIO_THREAD_MESSAGE_REC_STARTED;
-            mMessageHandler.sendMessage(msg);
-        }
-
-
-
-        log(String.format("about to init, sampling rate: %d, buffer:%d", mSamplingRate,
-                mMinPlayBufferSizeInBytes/2 ));
-        long sles_data = slesInit(mSamplingRate, mMinPlayBufferSizeInBytes/2, mMicSource,
-                                  mNumFramesToIgnore);
-        log(String.format("sles_data = 0x%X",sles_data));
-
-        if (sles_data == 0 ) {
-            log(" ERROR at JNI initialization");
-            if (mMessageHandler != null) {
-                Message msg = Message.obtain();
-                msg.what = NATIVE_AUDIO_THREAD_MESSAGE_REC_ERROR;
-                mMessageHandler.sendMessage(msg);
-            }
-        }  else {
-
-            //wait a little bit...
-            try {
-                sleep(10); //just to let it start properly?
-            } catch (InterruptedException e) {
-                e.printStackTrace();
-            }
-
-
-
-            mSamplesIndex = 0;
-            int totalSamplesRead = 0;
-            long offset = 0;
-            for (int ii = 0; ii < mSecondsToRun; ii++) {
-                log(String.format("block %d...", ii));
-                int samplesRead = slesProcessNext(sles_data, mvSamples,offset);
-                totalSamplesRead += samplesRead;
-
-                offset += samplesRead;
-                log(" [" + ii + "] jni samples read:" + samplesRead + "  currentOffset:" + offset);
-            }
-
-            log(String.format(" samplesRead: %d, sampleOffset:%d", totalSamplesRead, offset));
-            log(String.format("about to destroy..."));
-
-            runDestroy(sles_data);
-
-            int maxTry = 20;
-            int tryCount = 0;
-            //isDestroying = true;
-            while (isDestroying) {
-
-                try {
-                    sleep(40);
-                } catch (InterruptedException e) {
-                    e.printStackTrace();
-                }
-
-                tryCount++;
-
-                log("destroy try: " + tryCount);
-
-                if (tryCount >= maxTry) {
-                    hasDestroyingErrors = true;
-                    log("WARNING: waited for max time to properly destroy JNI.");
-                    break;
-                }
-            }
-            log(String.format("after destroying. TotalSamplesRead = %d", totalSamplesRead));
-
-            if (totalSamplesRead==0)
-            {
-                hasDestroyingErrors = true;
-            }
-
-            endTest();
-        }
-    }
-
-    public void setMessageHandler(Handler messageHandler) {
-        mMessageHandler = messageHandler;
-    }
-
-    private void runDestroy(final long sles_data ) {
-        isDestroying = true;
-
-        //start thread
-
-        final long local_sles_data = sles_data;
-        ////
-        Thread thread = new Thread(new Runnable() {
-            public void run() {
-                isDestroying = true;
-                log("**Start runnable destroy");
-
-                int status = slesDestroy(local_sles_data);
-                log(String.format("**End runnable destroy sles delete status: %d", status));
-                isDestroying = false;
-            }
-        });
-
-        thread.start();
-
-
-
-        log("end of runDestroy()");
-
-
-    }
-
-    public void togglePlay() {
-
-    }
-
-    public void runTest() {
-
-
-    }
-
-   public void endTest() {
-       log("--Ending capture test--");
-       isPlaying = false;
-
-
-       if (mMessageHandler != null) {
-           Message msg = Message.obtain();
-           if (hasDestroyingErrors)
-               msg.what = NATIVE_AUDIO_THREAD_MESSAGE_REC_COMPLETE_ERRORS;
-           else
-               msg.what = NATIVE_AUDIO_THREAD_MESSAGE_REC_COMPLETE;
-           mMessageHandler.sendMessage(msg);
-       }
-
-   }
-
-    public void finish() {
-
-        if (isRunning) {
-            isRunning = false;
-            try {
-                sleep(20);
-            } catch (InterruptedException e) {
-                e.printStackTrace();
-            }
-        }
-    }
-
-    private static void log(String msg) {
-        Log.v("Loopback", msg);
-    }
-
-    double [] getWaveData () {
-        return mvSamples;
-    }
-
-}  //end thread.
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/biometrics/AbstractBaseTest.java b/apps/CtsVerifier/src/com/android/cts/verifier/biometrics/AbstractBaseTest.java
index d1a300e..a79d82a 100644
--- a/apps/CtsVerifier/src/com/android/cts/verifier/biometrics/AbstractBaseTest.java
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/biometrics/AbstractBaseTest.java
@@ -42,7 +42,8 @@
  */
 public abstract class AbstractBaseTest extends PassFailButtons.Activity {
 
-    private static final int REQUEST_ENROLL = 1;
+    private static final int REQUEST_ENROLL_WHEN_NONE_ENROLLED = 1;
+    private static final int REQUEST_ENROLL_WHEN_ENROLLED = 2;
 
     abstract protected String getTag();
     abstract protected boolean isOnPauseAllowed();
@@ -52,6 +53,10 @@
 
     protected boolean mCurrentlyEnrolling;
 
+    // Not great to keep this here, but we use it to check that requesting enrollment of a
+    // combination that was just enrolled results in RESULT_CANCELED.
+    private int mRequestedStrength;
+
     BiometricManager mBiometricManager;
 
     @Override
@@ -77,9 +82,22 @@
 
     @Override
     public void onActivityResult(int requestCode, int resultCode, Intent data) {
-        if (requestCode == REQUEST_ENROLL) {
-            mCurrentlyEnrolling = false;
-            onBiometricEnrollFinished();
+        mCurrentlyEnrolling = false;
+
+        if (requestCode == REQUEST_ENROLL_WHEN_NONE_ENROLLED) {
+            if (resultCode == RESULT_OK) {
+                startBiometricEnroll(REQUEST_ENROLL_WHEN_ENROLLED, mRequestedStrength);
+            } else {
+                showToastAndLog("Unexpected result when requesting enrollment when not enrolled"
+                        + " yet: " + resultCode);
+            }
+        } else if (requestCode == REQUEST_ENROLL_WHEN_ENROLLED) {
+            if (resultCode == RESULT_CANCELED) {
+                onBiometricEnrollFinished();
+            } else {
+                showToastAndLog("Unexpected result when requesting enrollment when already"
+                        + " enrolled: " + resultCode);
+            }
         }
     }
 
@@ -93,8 +111,10 @@
 
     void checkAndEnroll(Button enrollButton, int requestedStrength,
             int[] acceptableConfigStrengths) {
+        mRequestedStrength = requestedStrength;
+
         // Check that no biometrics (of any strength) are enrolled
-        int result = mBiometricManager.canAuthenticate(requestedStrength);
+        int result = mBiometricManager.canAuthenticate(Authenticators.BIOMETRIC_WEAK);
         if (result == BiometricManager.BIOMETRIC_SUCCESS) {
             showToastAndLog("Please ensure that all biometrics are removed before starting"
                     + " this test");
@@ -124,18 +144,22 @@
                 getPassButton().setEnabled(true);
             }
         } else if (result == BiometricManager.BIOMETRIC_ERROR_NONE_ENROLLED) {
-            mCurrentlyEnrolling = true;
-            final Intent enrollIntent = new Intent(Settings.ACTION_BIOMETRIC_ENROLL);
-            enrollIntent.putExtra(Settings.EXTRA_BIOMETRIC_MINIMUM_STRENGTH_REQUIRED,
-                    requestedStrength);
-
-            startActivityForResult(enrollIntent, REQUEST_ENROLL);
+            startBiometricEnroll(REQUEST_ENROLL_WHEN_NONE_ENROLLED, requestedStrength);
         } else {
             showToastAndLog("Unexpected result: " + result + ". Please ensure you have removed"
                     + "all biometric enrollments.");
         }
     }
 
+    private void startBiometricEnroll(int requestCode, int requestedStrength) {
+        mCurrentlyEnrolling = true;
+        final Intent enrollIntent = new Intent(Settings.ACTION_BIOMETRIC_ENROLL);
+        enrollIntent.putExtra(Settings.EXTRA_BIOMETRIC_AUTHENTICATORS_ALLOWED,
+                requestedStrength);
+
+        startActivityForResult(enrollIntent, requestCode);
+    }
+
     void testBiometricUI(Utils.VerifyRandomContents contents, int allowedAuthenticators) {
         Utils.showInstructionDialog(this,
                 R.string.biometric_test_ui_instruction_dialog_title,
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/biometrics/BiometricStrongTests.java b/apps/CtsVerifier/src/com/android/cts/verifier/biometrics/BiometricStrongTests.java
index 367d76d..079c56f 100644
--- a/apps/CtsVerifier/src/com/android/cts/verifier/biometrics/BiometricStrongTests.java
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/biometrics/BiometricStrongTests.java
@@ -48,7 +48,7 @@
  * Ensure that this result is consistent with the configuration in core/res/res/values/config.xml
  *
  * Ensure that invoking {@link Settings.ACTION_BIOMETRIC_ENROLL} with its corresponding
- * {@link Settings.EXTRA_BIOMETRIC_MINIMUM_STRENGTH_REQUIRED} enrolls a
+ * {@link Settings.EXTRA_BIOMETRIC_AUTHENTICATORS_ALLOWED} enrolls a
  * {@link BiometricManager.Authenticators.BIOMETRIC_STRONG} authenticator. This can be done by
  * authenticating a {@link BiometricPrompt.CryptoObject}.
  *
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/biometrics/BiometricWeakTests.java b/apps/CtsVerifier/src/com/android/cts/verifier/biometrics/BiometricWeakTests.java
index f6fad5c..3ce9ccb 100644
--- a/apps/CtsVerifier/src/com/android/cts/verifier/biometrics/BiometricWeakTests.java
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/biometrics/BiometricWeakTests.java
@@ -40,7 +40,7 @@
  * Ensure that this result is consistent with the configuration in core/res/res/values/config.xml
  *
  * Ensure that invoking {@link Settings.ACTION_BIOMETRIC_ENROLL} with its corresponding
- * {@link Settings.EXTRA_BIOMETRIC_MINIMUM_STRENGTH_REQUIRED} enrolls a biometric that meets or
+ * {@link Settings.EXTRA_BIOMETRIC_AUTHENTICATORS_ALLOWED} enrolls a biometric that meets or
  * exceeds {@link BiometricManager.Authenticators.BIOMETRIC_WEAK}.
  *
  * Ensure that the BiometricPrompt UI displays all fields in the public API surface.
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/biometrics/CredentialEnrolledTests.java b/apps/CtsVerifier/src/com/android/cts/verifier/biometrics/CredentialEnrolledTests.java
index 1fc950e..0186ecb 100644
--- a/apps/CtsVerifier/src/com/android/cts/verifier/biometrics/CredentialEnrolledTests.java
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/biometrics/CredentialEnrolledTests.java
@@ -16,6 +16,7 @@
 
 package com.android.cts.verifier.biometrics;
 
+import android.content.Intent;
 import android.hardware.biometrics.BiometricManager;
 import android.hardware.biometrics.BiometricManager.Authenticators;
 import android.hardware.biometrics.BiometricPrompt;
@@ -23,6 +24,7 @@
 import android.os.CancellationSignal;
 import android.os.Handler;
 import android.os.Looper;
+import android.provider.Settings;
 import android.util.Log;
 import android.widget.Button;
 import android.widget.Toast;
@@ -39,6 +41,15 @@
 public class CredentialEnrolledTests extends AbstractBaseTest {
     private static final String TAG = "CredentialEnrolledTests";
 
+    private static final int REQUEST_ENROLL_WHEN_NONE_ENROLLED = 1;
+    private static final int REQUEST_ENROLL_WHEN_ENROLLED = 2;
+
+    private Button mEnrollButton;
+    private Button mBiometricManagerButton;
+    private Button mBPSetAllowedAuthenticatorsButton;
+    private Button mBPSetDeviceCredentialAllowedButton;
+
+    private boolean mEnrollPass;
     private boolean mBiometricManagerPass;
     private boolean mBiometricPromptSetAllowedAuthenticatorsPass;
     private boolean mBiometricPromptSetDeviceCredentialAllowedPass;
@@ -58,10 +69,23 @@
         setPassFailButtonClickListeners();
         getPassButton().setEnabled(false);
 
+        final BiometricManager bm = getSystemService(BiometricManager.class);
+
+        mEnrollButton = findViewById(R.id.enroll_credential_button);
+        mEnrollButton.setOnClickListener((view) -> {
+            final int biometricResult = bm.canAuthenticate(Authenticators.DEVICE_CREDENTIAL);
+            if (biometricResult != BiometricManager.BIOMETRIC_ERROR_NONE_ENROLLED) {
+                showToastAndLog("Please ensure you do not have a PIN/Pattern/Password set");
+                return;
+            }
+
+            requestCredentialEnrollment(REQUEST_ENROLL_WHEN_NONE_ENROLLED);
+        });
+
         // Test BiometricManager#canAuthenticate(DEVICE_CREDENTIAL)
-        final Button bmButton = findViewById(R.id.bm_button);
-        bmButton.setOnClickListener((view) -> {
-            final BiometricManager bm = getSystemService(BiometricManager.class);
+        mBiometricManagerButton = findViewById(R.id.bm_button);
+        mBiometricManagerButton.setOnClickListener((view) -> {
+
 
             final int biometricResult = bm.canAuthenticate(Authenticators.BIOMETRIC_WEAK);
             switch (biometricResult) {
@@ -80,7 +104,7 @@
 
             final int credentialResult = bm.canAuthenticate(Authenticators.DEVICE_CREDENTIAL);
             if (credentialResult == BiometricManager.BIOMETRIC_SUCCESS) {
-                bmButton.setEnabled(false);
+                mBiometricManagerButton.setEnabled(false);
                 mBiometricManagerPass = true;
                 updatePassButton();
             } else {
@@ -91,9 +115,8 @@
         });
 
         // Test setAllowedAuthenticators(DEVICE_CREDENTIAL)
-        final Button bpSetAllowedAuthenticatorsButton =
-                findViewById(R.id.setAllowedAuthenticators_button);
-        bpSetAllowedAuthenticatorsButton.setOnClickListener((view) -> {
+        mBPSetAllowedAuthenticatorsButton = findViewById(R.id.setAllowedAuthenticators_button);
+        mBPSetAllowedAuthenticatorsButton.setOnClickListener((view) -> {
             BiometricPrompt.Builder builder = new BiometricPrompt.Builder(this);
             builder.setTitle("Title");
             builder.setSubtitle("Subtitle");
@@ -108,7 +131,7 @@
                             final int authenticator = result.getAuthenticationType();
                             if (authenticator ==
                                     BiometricPrompt.AUTHENTICATION_RESULT_TYPE_DEVICE_CREDENTIAL) {
-                                bpSetAllowedAuthenticatorsButton.setEnabled(false);
+                                mBPSetAllowedAuthenticatorsButton.setEnabled(false);
                                 mBiometricPromptSetAllowedAuthenticatorsPass = true;
                                 updatePassButton();
                             } else {
@@ -124,9 +147,8 @@
         });
 
         // Test setDeviceCredentialAllowed(true)
-        final Button bpSetDeviceCredentialAllowedButton =
-                findViewById(R.id.setDeviceCredentialAllowed_button);
-        bpSetDeviceCredentialAllowedButton.setOnClickListener((view) -> {
+        mBPSetDeviceCredentialAllowedButton = findViewById(R.id.setDeviceCredentialAllowed_button);
+        mBPSetDeviceCredentialAllowedButton.setOnClickListener((view) -> {
             BiometricPrompt.Builder builder = new BiometricPrompt.Builder(this);
             builder.setTitle("Title");
             builder.setSubtitle("Subtitle");
@@ -141,7 +163,7 @@
                             final int authenticator = result.getAuthenticationType();
                             if (authenticator ==
                                     BiometricPrompt.AUTHENTICATION_RESULT_TYPE_DEVICE_CREDENTIAL) {
-                                bpSetDeviceCredentialAllowedButton.setEnabled(false);
+                                mBPSetDeviceCredentialAllowedButton.setEnabled(false);
                                 mBiometricPromptSetDeviceCredentialAllowedPass = true;
                                 updatePassButton();
                             } else {
@@ -165,8 +187,47 @@
         return !mBiometricManagerPass;
     }
 
+    @Override
+    public void onActivityResult(int requestCode, int resultCode, Intent data) {
+        if (requestCode == REQUEST_ENROLL_WHEN_NONE_ENROLLED) {
+            if (resultCode == RESULT_OK) {
+                final BiometricManager bm = getSystemService(BiometricManager.class);
+                final int result = bm.canAuthenticate(Authenticators.DEVICE_CREDENTIAL);
+                if (result == BiometricManager.BIOMETRIC_SUCCESS) {
+                    // Request enrollment one more time. Ensure that we receive RESULT_CANCELED
+                    requestCredentialEnrollment(REQUEST_ENROLL_WHEN_ENROLLED);
+                } else {
+                    showToastAndLog("Unexpected result: " + result + ". Please ensure that tapping"
+                            + " the button sends you to credential enrollment, and that you have"
+                            + " enrolled a credential.");
+                }
+            } else {
+                showToastAndLog("Unexpected result after enroll: " + resultCode);
+            }
+        } else if (requestCode == REQUEST_ENROLL_WHEN_ENROLLED) {
+            if (resultCode == RESULT_CANCELED) {
+                mEnrollPass = true;
+                mEnrollButton.setEnabled(false);
+                mBiometricManagerButton.setEnabled(true);
+                mBPSetAllowedAuthenticatorsButton.setEnabled(true);
+                mBPSetDeviceCredentialAllowedButton.setEnabled(true);
+            } else {
+                showToastAndLog("Unexpected result when requesting enrolling with"
+                        + " pre-existing credential: " + resultCode);
+            }
+        }
+    }
+
+    private void requestCredentialEnrollment(int requestCode) {
+        final Intent enrollIntent = new Intent(Settings.ACTION_BIOMETRIC_ENROLL);
+        enrollIntent.putExtra(Settings.EXTRA_BIOMETRIC_AUTHENTICATORS_ALLOWED,
+                Authenticators.DEVICE_CREDENTIAL);
+
+        startActivityForResult(enrollIntent, requestCode);
+    }
+
     private void updatePassButton() {
-        if (mBiometricManagerPass && mBiometricPromptSetAllowedAuthenticatorsPass
+        if (mEnrollPass && mBiometricManagerPass && mBiometricPromptSetAllowedAuthenticatorsPass
                 && mBiometricPromptSetDeviceCredentialAllowedPass) {
             showToastAndLog("All tests passed");
             getPassButton().setEnabled(true);
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/camera/its/ItsService.java b/apps/CtsVerifier/src/com/android/cts/verifier/camera/its/ItsService.java
index f39b590..e843ce7 100644
--- a/apps/CtsVerifier/src/com/android/cts/verifier/camera/its/ItsService.java
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/camera/its/ItsService.java
@@ -92,6 +92,7 @@
 import java.util.HashMap;
 import java.util.LinkedList;
 import java.util.List;
+import java.util.Locale;
 import java.util.Map;
 import java.util.Set;
 import java.util.concurrent.BlockingQueue;
@@ -664,6 +665,13 @@
 
         public void processSocketCommand(String cmd)
                 throws ItsException {
+            // Default locale must be set to "en-us"
+            Locale locale = Locale.getDefault();
+            if (!Locale.US.equals(locale)) {
+                Logt.e(TAG, "Default language is not set to " + Locale.US + "!");
+                stopSelf();
+            }
+
             // Each command is a serialized JSON object.
             try {
                 JSONObject cmdObj = new JSONObject(cmd);
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/camera/its/ItsTestActivity.java b/apps/CtsVerifier/src/com/android/cts/verifier/camera/its/ItsTestActivity.java
index 7e244a1..66422eb 100644
--- a/apps/CtsVerifier/src/com/android/cts/verifier/camera/its/ItsTestActivity.java
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/camera/its/ItsTestActivity.java
@@ -37,6 +37,7 @@
 import java.util.HashMap;
 import java.util.Iterator;
 import java.util.List;
+import java.util.Locale;
 import java.util.Set;
 import java.util.TreeSet;
 import java.io.BufferedReader;
@@ -361,6 +362,18 @@
                     , 1.0, ResultType.NEUTRAL, ResultUnit.NONE);
             setTestResultAndFinish(true);
         }
+        // Default locale must be set to "en-us"
+        Locale locale = Locale.getDefault();
+        if (!Locale.US.equals(locale)) {
+            String toastMessage = "Unsupported default language " + locale + "! " +
+                    "Please switch the default language to English (United States) in " +
+                    "Settings > Language & input > Languages";
+            Toast.makeText(ItsTestActivity.this, toastMessage, Toast.LENGTH_LONG).show();
+            ItsTestActivity.this.getReportLog().setSummary(
+                    "FAIL: Default language is not set to " + Locale.US,
+                    1.0, ResultType.NEUTRAL, ResultUnit.NONE);
+            setTestResultAndFinish(false);
+        }
         getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
     }
 
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/p2p/testcase/P2pBroadcastReceiverTest.java b/apps/CtsVerifier/src/com/android/cts/verifier/p2p/testcase/P2pBroadcastReceiverTest.java
index 5cc23f1..0e5f356 100644
--- a/apps/CtsVerifier/src/com/android/cts/verifier/p2p/testcase/P2pBroadcastReceiverTest.java
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/p2p/testcase/P2pBroadcastReceiverTest.java
@@ -42,7 +42,7 @@
     private WifiP2pManager mP2pMgr;
     private Channel mChannel;
 
-    private WifiP2pDeviceList mPeers;
+    private WifiP2pDeviceList mPeers = new WifiP2pDeviceList();
     private WifiP2pInfo mP2pInfo;
     private WifiP2pGroup mP2pGroup;
 
@@ -79,12 +79,9 @@
 
         Timeout t = new Timeout(msec);
         while (!t.isTimeout()) {
-            if (mPeers != null) {
-                for (WifiP2pDevice dev: mPeers.getDeviceList()) {
-                    if (dev.deviceAddress.equals(targetAddr)) {
-                        return dev;
-                    }
-                }
+            WifiP2pDevice dev = mPeers.get(targetAddr);
+            if (dev != null) {
+                return dev;
             }
             wait(t.getRemainTime());
         }
@@ -125,14 +122,9 @@
 
         Timeout t = new Timeout(msec);
         while (!t.isTimeout()) {
-            if (mPeers != null) {
-                for (WifiP2pDevice dev: mPeers.getDeviceList()) {
-                    if (dev.deviceAddress.equals(targetAddr)) {
-                        if (dev.status == WifiP2pDevice.CONNECTED) {
-                            return true;
-                        }
-                    }
-                }
+            WifiP2pDevice dev = mPeers.get(targetAddr);
+            if (dev != null && dev.status == WifiP2pDevice.CONNECTED) {
+                return true;
             }
             wait(t.getRemainTime());
         }
@@ -152,21 +144,14 @@
 
         Timeout t = new Timeout(msec);
 
-        boolean devicePresent;
-
         while (!t.isTimeout()) {
-            devicePresent = false;
-            if (mPeers != null) {
-                for (WifiP2pDevice dev: mPeers.getDeviceList()) {
-                    if (dev.deviceAddress.equals(targetAddr)) {
-                        if (dev.status != WifiP2pDevice.CONNECTED) {
-                            return true;
-                        }
-                        devicePresent = true;
-                    }
-                }
+            WifiP2pDevice dev = mPeers.get(targetAddr);
+
+            if (dev == null ) return true;
+
+            if (dev.status != WifiP2pDevice.CONNECTED) {
+                return true;
             }
-            if (!devicePresent) return true;
             wait(t.getRemainTime());
         }
         Log.e(TAG, "Appropriate WIFI_P2P_PEERS_CHANGED_ACTION didn't occur");
@@ -217,7 +202,7 @@
     @Override
     public synchronized void onPeersAvailable(WifiP2pDeviceList peers) {
         Log.d(TAG, "onPeersAvailable()");
-        mPeers = peers;
+        mPeers = new WifiP2pDeviceList(peers);
         notifyAll();
     }
 
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/security/IdentityCredentialAuthentication.java b/apps/CtsVerifier/src/com/android/cts/verifier/security/IdentityCredentialAuthentication.java
index 0493aa7..0e7af05 100644
--- a/apps/CtsVerifier/src/com/android/cts/verifier/security/IdentityCredentialAuthentication.java
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/security/IdentityCredentialAuthentication.java
@@ -168,7 +168,7 @@
         idsProfile0.add(new AccessControlProfileId(0));
         PersonalizationData pd = new PersonalizationData.Builder()
                                  .addAccessControlProfile(acp)
-                                 .setEntry("org.iso.18013-5.2019", "Foo", idsProfile0, barCbor)
+                                 .putEntry("org.iso.18013-5.2019", "Foo", idsProfile0, barCbor)
                                  .build();
         byte[] proofOfProvisioningSignature = wc.personalize(pd);
 
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/wifi/BaseTestActivity.java b/apps/CtsVerifier/src/com/android/cts/verifier/wifi/BaseTestActivity.java
index 3d507cd..4db3766 100644
--- a/apps/CtsVerifier/src/com/android/cts/verifier/wifi/BaseTestActivity.java
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/wifi/BaseTestActivity.java
@@ -118,6 +118,7 @@
             public void run() {
                 if (reason != null) {
                     mWifiInfo.append(reason);
+                    mWifiInfo.append("\n");
                 }
                 getPassButton().setEnabled(false);
                 mWifiInfo.append(getString(R.string.wifi_status_test_failed));
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/wifi/CallbackUtils.java b/apps/CtsVerifier/src/com/android/cts/verifier/wifi/CallbackUtils.java
index facf101..38c2f11 100644
--- a/apps/CtsVerifier/src/com/android/cts/verifier/wifi/CallbackUtils.java
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/wifi/CallbackUtils.java
@@ -17,7 +17,9 @@
 package com.android.cts.verifier.wifi;
 
 import android.net.ConnectivityManager;
+import android.net.LinkProperties;
 import android.net.Network;
+import android.net.NetworkCapabilities;
 import android.util.Log;
 import android.util.Pair;
 
@@ -42,7 +44,11 @@
         private CountDownLatch mOnAvailableBlocker = new CountDownLatch(1);
         private CountDownLatch mOnUnAvailableBlocker = new CountDownLatch(1);
         private CountDownLatch mOnLostBlocker = new CountDownLatch(1);
+        // This is invoked multiple times, so initialize only when waitForCapabilitiesChanged() is
+        // invoked.
+        private CountDownLatch mOnCapabilitiesChangedBlocker = null;
         private Network mNetwork;
+        private NetworkCapabilities mNetworkCapabilities;
 
         public NetworkCallback() {
             mCallbackTimeoutInMs = DEFAULT_CALLBACK_TIMEOUT_MS;
@@ -53,13 +59,23 @@
         }
 
         @Override
-        public void onAvailable(Network network) {
+        public void onAvailable(Network network, NetworkCapabilities networkCapabilities,
+                LinkProperties linkProperties, boolean isBlocked) {
             if (DBG) Log.v(TAG, "onAvailable");
             mNetwork = network;
+            mNetworkCapabilities = networkCapabilities;
             mOnAvailableBlocker.countDown();
         }
 
         @Override
+        public void onCapabilitiesChanged(Network network, NetworkCapabilities networkCapabilities) {
+            if (DBG) Log.v(TAG, "onCapabilitiesChanged");
+            mNetwork = network;
+            mNetworkCapabilities = networkCapabilities;
+            if (mOnCapabilitiesChangedBlocker != null) mOnCapabilitiesChangedBlocker.countDown();
+        }
+
+        @Override
         public void onUnavailable() {
             if (DBG) Log.v(TAG, "onUnavailable");
             mOnUnAvailableBlocker.countDown();
@@ -72,6 +88,14 @@
             mOnLostBlocker.countDown();
         }
 
+        public Network getNetwork() {
+            return mNetwork;
+        }
+
+        public NetworkCapabilities getNetworkCapabilities() {
+            return mNetworkCapabilities;
+        }
+
         /**
          * Wait (blocks) for {@link #onAvailable(Network)} or timeout.
          *
@@ -91,10 +115,7 @@
          * @return true whether the callback was invoked.
          */
         public boolean waitForUnavailable() throws InterruptedException {
-            if (mOnUnAvailableBlocker.await(mCallbackTimeoutInMs, TimeUnit.MILLISECONDS)) {
-                return true;
-            }
-            return false;
+            return mOnUnAvailableBlocker.await(mCallbackTimeoutInMs, TimeUnit.MILLISECONDS);
         }
 
         /**
@@ -103,10 +124,18 @@
          * @return true whether the callback was invoked.
          */
         public boolean waitForLost() throws InterruptedException {
-            if (mOnLostBlocker.await(mCallbackTimeoutInMs, TimeUnit.MILLISECONDS)) {
-                return true;
-            }
-            return false;
+            return mOnLostBlocker.await(mCallbackTimeoutInMs, TimeUnit.MILLISECONDS);
+        }
+
+        /**
+         * Wait (blocks) for {@link #onCapabilitiesChanged(Network, NetworkCapabilities)} or
+         * timeout.
+         *
+         * @return true whether the callback was invoked.
+         */
+        public boolean waitForCapabilitiesChanged() throws InterruptedException {
+            mOnCapabilitiesChangedBlocker = new CountDownLatch(1);
+            return mOnCapabilitiesChangedBlocker.await(mCallbackTimeoutInMs, TimeUnit.MILLISECONDS);
         }
     }
 }
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/wifi/NetworkRequestInvalidCredentialNetworkSpecifierTestActivity.java b/apps/CtsVerifier/src/com/android/cts/verifier/wifi/NetworkRequestInvalidCredentialNetworkSpecifierTestActivity.java
new file mode 100644
index 0000000..17c86a7
--- /dev/null
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/wifi/NetworkRequestInvalidCredentialNetworkSpecifierTestActivity.java
@@ -0,0 +1,42 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.cts.verifier.wifi;
+
+import static com.android.cts.verifier.wifi.testcase.NetworkRequestTestCase.NETWORK_SPECIFIER_INVALID_CREDENTIAL;
+
+import android.content.Context;
+import android.os.Bundle;
+
+import com.android.cts.verifier.R;
+import com.android.cts.verifier.wifi.testcase.NetworkRequestTestCase;
+
+/**
+ * Test activity for specifier with specific ssid/bssid, but with wrong credentials.
+ */
+public class NetworkRequestInvalidCredentialNetworkSpecifierTestActivity extends BaseTestActivity {
+    @Override
+    protected BaseTestCase getTestCase(Context context) {
+        return new NetworkRequestTestCase(context, NETWORK_SPECIFIER_INVALID_CREDENTIAL);
+    }
+
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        setInfoResources(R.string.wifi_test_network_request_invalid_credential,
+                R.string.wifi_test_network_request_invalid_credential_info, 0);
+    }
+}
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/wifi/NetworkSuggestionConnectionFailureTestActivity.java b/apps/CtsVerifier/src/com/android/cts/verifier/wifi/NetworkSuggestionConnectionFailureTestActivity.java
new file mode 100644
index 0000000..d70d5ae
--- /dev/null
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/wifi/NetworkSuggestionConnectionFailureTestActivity.java
@@ -0,0 +1,44 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.cts.verifier.wifi;
+
+import android.content.Context;
+import android.os.Bundle;
+
+import com.android.cts.verifier.R;
+import com.android.cts.verifier.wifi.testcase.NetworkSuggestionTestCase;
+
+/**
+ * Test activity for suggestion with ssid specified, but with wrong credentials.
+ */
+public class NetworkSuggestionConnectionFailureTestActivity extends BaseTestActivity {
+    @Override
+    protected BaseTestCase getTestCase(Context context) {
+        return new NetworkSuggestionTestCase(
+                context,
+                false, /* setBssid */
+                false, /* setRequiresAppInteraction */
+                true /* simulateConnectionFailure */);
+    }
+
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        setInfoResources(R.string.wifi_test_network_suggestion_connection_failure,
+                R.string.wifi_test_network_suggestion_connection_failure_info, 0);
+    }
+}
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/wifi/NetworkSuggestionModificationInPlaceTestActivity.java b/apps/CtsVerifier/src/com/android/cts/verifier/wifi/NetworkSuggestionModificationInPlaceTestActivity.java
new file mode 100644
index 0000000..8a8a390
--- /dev/null
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/wifi/NetworkSuggestionModificationInPlaceTestActivity.java
@@ -0,0 +1,45 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.cts.verifier.wifi;
+
+import android.content.Context;
+import android.os.Bundle;
+
+import com.android.cts.verifier.R;
+import com.android.cts.verifier.wifi.testcase.NetworkSuggestionTestCase;
+
+/**
+ * Test activity for suggestion which is modified while connected to it.
+ */
+public class NetworkSuggestionModificationInPlaceTestActivity extends BaseTestActivity {
+    @Override
+    protected BaseTestCase getTestCase(Context context) {
+        return new NetworkSuggestionTestCase(
+                context,
+                false, /* setBssid */
+                false, /* setRequiresAppInteraction */
+                false, /* simulateConnectionFailure */
+                true /* setMeteredPostConnection */);
+    }
+
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        setInfoResources(R.string.wifi_test_network_suggestion_modification_in_place,
+                R.string.wifi_test_network_suggestion_modification_in_place_info, 0);
+    }
+}
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/wifi/TestListActivity.java b/apps/CtsVerifier/src/com/android/cts/verifier/wifi/TestListActivity.java
index b7c6c8a..852f9af 100644
--- a/apps/CtsVerifier/src/com/android/cts/verifier/wifi/TestListActivity.java
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/wifi/TestListActivity.java
@@ -74,6 +74,11 @@
                 NetworkRequestUnavailableNetworkSpecifierTestActivity.class.getName(),
                 new Intent(this, NetworkRequestUnavailableNetworkSpecifierTestActivity.class),
                 null));
+        adapter.add(TestListAdapter.TestListItem.newTest(this,
+                R.string.wifi_test_network_request_invalid_credential,
+                NetworkRequestInvalidCredentialNetworkSpecifierTestActivity.class.getName(),
+                new Intent(this, NetworkRequestInvalidCredentialNetworkSpecifierTestActivity.class),
+                null));
         adapter.add(TestListAdapter.TestListItem.newCategory(this,
                 R.string.wifi_test_network_suggestion));
         adapter.add(TestListAdapter.TestListItem.newTest(this,
@@ -88,6 +93,14 @@
                 R.string.wifi_test_network_suggestion_ssid_post_connect,
                 NetworkSuggestionSsidPostConnectTestActivity.class.getName(),
                 new Intent(this, NetworkSuggestionSsidPostConnectTestActivity.class), null));
+        adapter.add(TestListAdapter.TestListItem.newTest(this,
+                R.string.wifi_test_network_suggestion_connection_failure,
+                NetworkSuggestionConnectionFailureTestActivity.class.getName(),
+                new Intent(this, NetworkSuggestionConnectionFailureTestActivity.class), null));
+        adapter.add(TestListAdapter.TestListItem.newTest(this,
+                R.string.wifi_test_network_suggestion_modification_in_place,
+                NetworkSuggestionModificationInPlaceTestActivity.class.getName(),
+                new Intent(this, NetworkSuggestionModificationInPlaceTestActivity.class), null));
 
         adapter.registerDataSetObserver(new DataSetObserver() {
             @Override
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/wifi/TestUtils.java b/apps/CtsVerifier/src/com/android/cts/verifier/wifi/TestUtils.java
index 2b7b4b1..dadacd3 100644
--- a/apps/CtsVerifier/src/com/android/cts/verifier/wifi/TestUtils.java
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/wifi/TestUtils.java
@@ -16,6 +16,7 @@
 
 package com.android.cts.verifier.wifi;
 
+import android.annotation.IntDef;
 import android.annotation.NonNull;
 import android.annotation.Nullable;
 import android.content.BroadcastReceiver;
@@ -31,7 +32,10 @@
 
 import com.android.cts.verifier.R;
 
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
 import java.util.List;
+import java.util.Random;
 import java.util.concurrent.CountDownLatch;
 import java.util.concurrent.TimeUnit;
 
@@ -93,8 +97,18 @@
         return true;
     }
 
-    // Helper to check if the scan result corresponds to an open network.
-    private static boolean isScanResultForOpenNetwork(@NonNull ScanResult scanResult) {
+    public static final int SCAN_RESULT_TYPE_OPEN = 0;
+    public static final int SCAN_RESULT_TYPE_PSK = 1;
+
+    @IntDef(prefix = { "SCAN_RESULT_TYPE_" }, value = {
+    })
+    @Retention(RetentionPolicy.SOURCE)
+    public @interface ScanResultType {}
+
+    /**
+     * Helper to check if the scan result corresponds to an open network.
+     */
+    public static boolean isScanResultForOpenNetwork(@NonNull ScanResult scanResult) {
         String capabilities = scanResult.capabilities;
         return !capabilities.contains("PSK") && !capabilities.contains("EAP")
                 && !capabilities.contains("WEP") && !capabilities.contains("SAE")
@@ -102,12 +116,42 @@
     }
 
     /**
-     * Helper method to start a scan and find any open networks in the scan results returned by the
-     * device.
-     * @return ScanResult instance corresponding to an open network if one exists, null if the
-     * scan failed or if there are no open networks found.
+     * Helper to check if the scan result corresponds to a WPA2 PSK network.
      */
-    public @Nullable ScanResult startScanAndFindAnyOpenNetworkInResults()
+    public static boolean isScanResultForWpa2Network(@NonNull ScanResult scanResult) {
+        String capabilities = scanResult.capabilities;
+        return capabilities.contains("PSK");
+    }
+
+    /**
+     * Helper to check if the scan result corresponds to a WPA3 PSK network.
+     */
+    public static boolean isScanResultForWpa3Network(@NonNull ScanResult scanResult) {
+        String capabilities = scanResult.capabilities;
+        return capabilities.contains("SAE");
+    }
+
+    private static boolean doesScanResultMatchType(
+            ScanResult scanResult, @ScanResultType int type) {
+        switch(type) {
+            case SCAN_RESULT_TYPE_OPEN:
+                return isScanResultForOpenNetwork(scanResult);
+            case SCAN_RESULT_TYPE_PSK:
+                return isScanResultForWpa2Network(scanResult)
+                        || isScanResultForWpa3Network(scanResult);
+            default:
+                return false;
+        }
+    }
+
+    /**
+     * Helper method to start a scan and find any type of networks in the scan results returned by
+     * the device.
+     * @return ScanResult instance corresponding to an network of type if one exists, null if the
+     * scan failed or if there are networks found.
+     */
+    public @Nullable ScanResult startScanAndFindAnyMatchingNetworkInResults(
+            @ScanResultType int type)
             throws InterruptedException {
         // Start scan and wait for new results.
         if (!startScanAndWaitForResults()) {
@@ -118,7 +162,7 @@
         for (ScanResult scanResult : scanResults) {
             if (!TextUtils.isEmpty(scanResult.SSID)
                     && !TextUtils.isEmpty(scanResult.BSSID)
-                    && isScanResultForOpenNetwork(scanResult)) {
+                    && doesScanResultMatchType(scanResult, type)) {
                 if (DBG) Log.v(TAG, "Found open network " + scanResult);
                 return scanResult;
             }
@@ -169,5 +213,14 @@
         return true;
     }
 
-
+    /**
+     * Generate random passphrase to use for tests.
+     * @return
+     */
+    public String generateRandomPassphrase() {
+        return new Random().ints('a', 'z' + 1)
+                .limit(45)
+                .collect(StringBuilder::new, StringBuilder::appendCodePoint, StringBuilder::append)
+                .toString();
+    }
 }
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/wifi/testcase/NetworkRequestTestCase.java b/apps/CtsVerifier/src/com/android/cts/verifier/wifi/testcase/NetworkRequestTestCase.java
index 12269a6..96f9547 100644
--- a/apps/CtsVerifier/src/com/android/cts/verifier/wifi/testcase/NetworkRequestTestCase.java
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/wifi/testcase/NetworkRequestTestCase.java
@@ -19,9 +19,11 @@
 import static android.net.NetworkCapabilities.NET_CAPABILITY_INTERNET;
 import static android.net.NetworkCapabilities.TRANSPORT_WIFI;
 
+import static com.android.cts.verifier.wifi.TestUtils.SCAN_RESULT_TYPE_OPEN;
+import static com.android.cts.verifier.wifi.TestUtils.SCAN_RESULT_TYPE_PSK;
+
 import android.annotation.IntDef;
 import android.annotation.NonNull;
-import android.content.BroadcastReceiver;
 import android.content.Context;
 import android.net.ConnectivityManager;
 import android.net.MacAddress;
@@ -37,6 +39,7 @@
 import com.android.cts.verifier.R;
 import com.android.cts.verifier.wifi.BaseTestCase;
 import com.android.cts.verifier.wifi.CallbackUtils;
+import com.android.cts.verifier.wifi.TestUtils;
 
 import java.lang.annotation.Retention;
 import java.lang.annotation.RetentionPolicy;
@@ -57,11 +60,13 @@
     public static final int NETWORK_SPECIFIER_SPECIFIC_SSID_BSSID = 0;
     public static final int NETWORK_SPECIFIER_PATTERN_SSID_BSSID = 1;
     public static final int NETWORK_SPECIFIER_UNAVAILABLE_SSID_BSSID = 2;
+    public static final int NETWORK_SPECIFIER_INVALID_CREDENTIAL = 3;
 
     @IntDef(prefix = { "NETWORK_SPECIFIER_" }, value = {
             NETWORK_SPECIFIER_SPECIFIC_SSID_BSSID,
             NETWORK_SPECIFIER_PATTERN_SSID_BSSID,
             NETWORK_SPECIFIER_UNAVAILABLE_SSID_BSSID,
+            NETWORK_SPECIFIER_INVALID_CREDENTIAL
     })
     @Retention(RetentionPolicy.SOURCE)
     public @interface NetworkSpecifierType{}
@@ -106,6 +111,16 @@
                 configBuilder.setSsid(UNAVAILABLE_SSID);
                 configBuilder.setBssid(bssid);
                 break;
+            case NETWORK_SPECIFIER_INVALID_CREDENTIAL:
+                configBuilder.setSsid(scanResult.SSID);
+                configBuilder.setBssid(MacAddress.fromString(scanResult.BSSID));
+                // Use a random password to simulate connection failure.
+                if (TestUtils.isScanResultForWpa2Network(scanResult)) {
+                    configBuilder.setWpa2Passphrase(mTestUtils.generateRandomPassphrase());
+                } else if (TestUtils.isScanResultForWpa3Network(scanResult)) {
+                    configBuilder.setWpa3Passphrase(mTestUtils.generateRandomPassphrase());
+                }
+                break;
             default:
                 throw new IllegalStateException("Unknown specifier type specifier");
         }
@@ -121,26 +136,28 @@
 
     @Override
     protected boolean executeTest() throws InterruptedException {
-        // Step 1: Scan and find any open network around.
+        // Step: Scan and find any open network around.
         if (DBG) Log.v(TAG, "Scan and find an open network");
-        ScanResult openNetwork = mTestUtils.startScanAndFindAnyOpenNetworkInResults();
-        if (openNetwork == null) {
+        ScanResult testNetwork = mTestUtils.startScanAndFindAnyMatchingNetworkInResults(
+                mNetworkSpecifierType == NETWORK_SPECIFIER_INVALID_CREDENTIAL
+                        ? SCAN_RESULT_TYPE_PSK : SCAN_RESULT_TYPE_OPEN);
+        if (testNetwork == null) {
             setFailureReason(mContext.getString(R.string.wifi_status_scan_failure));
             return false;
         }
 
-        // Step 2: Create a specifier for the chosen open network depending on the type of test.
-        NetworkSpecifier wns = createNetworkSpecifier(openNetwork);
+        // Step: Create a specifier for the chosen open network depending on the type of test.
+        NetworkSpecifier wns = createNetworkSpecifier(testNetwork);
         if (wns == null) return false;
 
-        // Step 3: Create a network request with specifier.
+        // Step: Create a network request with specifier.
         mNetworkRequest = new NetworkRequest.Builder()
                 .addTransportType(TRANSPORT_WIFI)
                 .setNetworkSpecifier(wns)
                 .removeCapability(NET_CAPABILITY_INTERNET)
                 .build();
 
-        // Step 4: Send the network request
+        // Step: Send the network request
         if (DBG) Log.v(TAG, "Request network using " + mNetworkRequest);
         mNetworkCallback = new CallbackUtils.NetworkCallback(CALLBACK_TIMEOUT_MS);
         mListener.onTestMsgReceived(
@@ -148,10 +165,17 @@
         mConnectivityManager.requestNetwork(mNetworkRequest, mNetworkCallback,
                 NETWORK_REQUEST_TIMEOUT_MS);
 
-        // Step 5: Wait for the network available/unavailable callback.
-        if (mNetworkSpecifierType == NETWORK_SPECIFIER_UNAVAILABLE_SSID_BSSID) {
-            mListener.onTestMsgReceived(
-                    mContext.getString(R.string.wifi_status_network_wait_for_unavailable));
+        // Step: Wait for the network available/unavailable callback.
+        if (mNetworkSpecifierType == NETWORK_SPECIFIER_UNAVAILABLE_SSID_BSSID
+                || mNetworkSpecifierType == NETWORK_SPECIFIER_INVALID_CREDENTIAL) {
+            if (mNetworkSpecifierType == NETWORK_SPECIFIER_UNAVAILABLE_SSID_BSSID) {
+                mListener.onTestMsgReceived(
+                        mContext.getString(R.string.wifi_status_network_wait_for_unavailable));
+            } else {
+                mListener.onTestMsgReceived(
+                        mContext.getString(R.string
+                                .wifi_status_network_wait_for_unavailable_invalid_credential));
+            }
             if (DBG) Log.v(TAG, "Waiting for network unavailable callback");
             boolean cbStatusForUnavailable = mNetworkCallback.waitForUnavailable();
             if (!cbStatusForUnavailable) {
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/wifi/testcase/NetworkSuggestionTestCase.java b/apps/CtsVerifier/src/com/android/cts/verifier/wifi/testcase/NetworkSuggestionTestCase.java
index 53bcc4a..68d3bb5 100644
--- a/apps/CtsVerifier/src/com/android/cts/verifier/wifi/testcase/NetworkSuggestionTestCase.java
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/wifi/testcase/NetworkSuggestionTestCase.java
@@ -16,9 +16,13 @@
 
 package com.android.cts.verifier.wifi.testcase;
 
+import static android.net.NetworkCapabilities.NET_CAPABILITY_NOT_METERED;
 import static android.net.NetworkCapabilities.TRANSPORT_WIFI;
 import static android.net.wifi.WifiManager.STATUS_NETWORK_SUGGESTIONS_SUCCESS;
 
+import static com.android.cts.verifier.wifi.TestUtils.SCAN_RESULT_TYPE_OPEN;
+import static com.android.cts.verifier.wifi.TestUtils.SCAN_RESULT_TYPE_PSK;
+
 import android.annotation.NonNull;
 import android.content.BroadcastReceiver;
 import android.content.Context;
@@ -31,15 +35,19 @@
 import android.net.wifi.ScanResult;
 import android.net.wifi.WifiManager;
 import android.net.wifi.WifiNetworkSuggestion;
+import android.os.SystemClock;
 import android.util.Log;
 import android.util.Pair;
 
 import com.android.cts.verifier.R;
 import com.android.cts.verifier.wifi.BaseTestCase;
 import com.android.cts.verifier.wifi.CallbackUtils;
+import com.android.cts.verifier.wifi.TestUtils;
 
 import java.util.ArrayList;
+import java.util.Arrays;
 import java.util.List;
+import java.util.Objects;
 import java.util.concurrent.CountDownLatch;
 import java.util.concurrent.Executors;
 import java.util.concurrent.ScheduledExecutorService;
@@ -55,39 +63,63 @@
 
     private static final int PERIODIC_SCAN_INTERVAL_MS = 10_000;
     private static final int CALLBACK_TIMEOUT_MS = 40_000;
+    private static final int CAPABILITIES_CHANGED_FOR_METERED_TIMEOUT_MS = 80_000;
 
     private final Object mLock = new Object();
     private final ScheduledExecutorService mExecutorService;
     private final List<WifiNetworkSuggestion> mNetworkSuggestions = new ArrayList<>();
+    private final WifiNetworkSuggestion.Builder mNetworkSuggestionBuilder =
+            new WifiNetworkSuggestion.Builder();
 
     private ConnectivityManager mConnectivityManager;
     private NetworkRequest mNetworkRequest;
     private CallbackUtils.NetworkCallback mNetworkCallback;
+    private ConnectionStatusListener mConnectionStatusListener;
     private BroadcastReceiver mBroadcastReceiver;
     private String mFailureReason;
 
     private final boolean mSetBssid;
     private final boolean mSetRequiresAppInteraction;
+    private final boolean mSimulateConnectionFailure;
+    private final boolean mSetMeteredPostConnection;
 
     public NetworkSuggestionTestCase(Context context, boolean setBssid,
-                                     boolean setRequiresAppInteraction) {
+            boolean setRequiresAppInteraction) {
+        this(context, setBssid, setRequiresAppInteraction, false);
+    }
+
+    public NetworkSuggestionTestCase(Context context, boolean setBssid,
+            boolean setRequiresAppInteraction, boolean simulateConnectionFailure) {
+        this(context, setBssid, setRequiresAppInteraction, simulateConnectionFailure, false);
+    }
+
+    public NetworkSuggestionTestCase(Context context, boolean setBssid,
+            boolean setRequiresAppInteraction, boolean simulateConnectionFailure,
+            boolean setMeteredPostConnection) {
         super(context);
         mExecutorService = Executors.newSingleThreadScheduledExecutor();
         mSetBssid = setBssid;
         mSetRequiresAppInteraction = setRequiresAppInteraction;
+        mSimulateConnectionFailure = simulateConnectionFailure;
+        mSetMeteredPostConnection = true;
     }
 
     // Create a network specifier based on the test type.
     private WifiNetworkSuggestion createNetworkSuggestion(@NonNull ScanResult scanResult) {
-        WifiNetworkSuggestion.Builder builder = new WifiNetworkSuggestion.Builder();
-        builder.setSsid(scanResult.SSID);
+        mNetworkSuggestionBuilder.setSsid(scanResult.SSID);
         if (mSetBssid) {
-            builder.setBssid(MacAddress.fromString(scanResult.BSSID));
+            mNetworkSuggestionBuilder.setBssid(MacAddress.fromString(scanResult.BSSID));
         }
         if (mSetRequiresAppInteraction) {
-            builder.setIsAppInteractionRequired(true);
+            mNetworkSuggestionBuilder.setIsAppInteractionRequired(true);
         }
-        return builder.build();
+        // Use a random password to simulate connection failure.
+        if (TestUtils.isScanResultForWpa2Network(scanResult)) {
+            mNetworkSuggestionBuilder.setWpa2Passphrase(mTestUtils.generateRandomPassphrase());
+        } else if (TestUtils.isScanResultForWpa3Network(scanResult)) {
+            mNetworkSuggestionBuilder.setWpa3Passphrase(mTestUtils.generateRandomPassphrase());
+        }
+        return mNetworkSuggestionBuilder.build();
     }
 
     private void setFailureReason(String reason) {
@@ -96,50 +128,96 @@
         }
     }
 
+    private static class ConnectionStatusListener implements
+            WifiManager.SuggestionConnectionStatusListener {
+        private final CountDownLatch mCountDownLatch;
+        public WifiNetworkSuggestion wifiNetworkSuggestion = null;
+        public int failureReason = -1;
+
+        ConnectionStatusListener(CountDownLatch countDownLatch) {
+            mCountDownLatch = countDownLatch;
+        }
+
+        @Override
+        public void onConnectionStatus(
+                WifiNetworkSuggestion wifiNetworkSuggestion, int failureReason) {
+            this.wifiNetworkSuggestion = wifiNetworkSuggestion;
+            this.failureReason = failureReason;
+            mCountDownLatch.countDown();
+        }
+    }
+
+    // TODO(b/150890482): Capabilities changed callback can occur multiple times (for ex: RSSI
+    // change) & the sufficiency checks may result in ths change taking longer to take effect.
+    // This method accounts for both of these situations.
+    private boolean waitForNetworkToBeMetered() throws InterruptedException {
+        long startTimeMillis = SystemClock.elapsedRealtime();
+        while (SystemClock.elapsedRealtime()
+                < startTimeMillis + CAPABILITIES_CHANGED_FOR_METERED_TIMEOUT_MS) {
+            // Network marked metered.
+            if (!mNetworkCallback.getNetworkCapabilities()
+                    .hasCapability(NET_CAPABILITY_NOT_METERED)) {
+                return true;
+            } else {
+                Log.w(TAG, "Network meteredness check failed. "
+                        + mNetworkCallback.getNetworkCapabilities());
+            }
+            // Wait for the suggestion to be marked metered now.
+            if (!mNetworkCallback.waitForCapabilitiesChanged()) {
+                Log.w(TAG, "Network capabilities did not change");
+            }
+        }
+        return false;
+    }
+
     @Override
     protected boolean executeTest() throws InterruptedException {
-        // Step 1: Scan and find any open network around.
-        if (DBG) Log.v(TAG, "Scan and find an open network");
-        ScanResult openNetwork = mTestUtils.startScanAndFindAnyOpenNetworkInResults();
-        if (openNetwork == null) {
+        // Step: Scan and find any open network around.
+        if (DBG) Log.v(TAG, "Scan and find a network");
+        ScanResult testNetwork = mTestUtils.startScanAndFindAnyMatchingNetworkInResults(
+                mSimulateConnectionFailure ? SCAN_RESULT_TYPE_PSK : SCAN_RESULT_TYPE_OPEN);
+        if (testNetwork == null) {
             setFailureReason(mContext.getString(R.string.wifi_status_scan_failure));
             return false;
         }
 
-        // Step 1.a (Optional): Register for the post connection broadcast.
+        // Step (Optional): Register for the post connection broadcast.
         final CountDownLatch countDownLatchForPostConnectionBcast = new CountDownLatch(1);
-        if (mSetRequiresAppInteraction) {
-            IntentFilter intentFilter =
-                    new IntentFilter(WifiManager.ACTION_WIFI_NETWORK_SUGGESTION_POST_CONNECTION);
-            // Post connection broadcast receiver.
-            mBroadcastReceiver = new BroadcastReceiver() {
-                @Override
-                public void onReceive(Context context, Intent intent) {
-                    if (DBG) Log.v(TAG, "Broadcast onReceive " + intent);
-                    if (!intent.getAction().equals(
-                            WifiManager.ACTION_WIFI_NETWORK_SUGGESTION_POST_CONNECTION)) {
-                        return;
-                    }
-                    if (DBG) Log.v(TAG, "Post connection broadcast received");
-                    countDownLatchForPostConnectionBcast.countDown();
+        IntentFilter intentFilter =
+                new IntentFilter(WifiManager.ACTION_WIFI_NETWORK_SUGGESTION_POST_CONNECTION);
+        // Post connection broadcast receiver.
+        mBroadcastReceiver = new BroadcastReceiver() {
+            @Override
+            public void onReceive(Context context, Intent intent) {
+                if (DBG) Log.v(TAG, "Broadcast onReceive " + intent);
+                if (!intent.getAction().equals(
+                        WifiManager.ACTION_WIFI_NETWORK_SUGGESTION_POST_CONNECTION)) {
+                    return;
                 }
-            };
-            // Register the receiver for post connection broadcast.
-            mContext.registerReceiver(mBroadcastReceiver, intentFilter);
-        }
+                if (DBG) Log.v(TAG, "Post connection broadcast received");
+                countDownLatchForPostConnectionBcast.countDown();
+            }
+        };
+        // Register the receiver for post connection broadcast.
+        mContext.registerReceiver(mBroadcastReceiver, intentFilter);
+        final CountDownLatch countDownLatchForConnectionStatusListener = new CountDownLatch(1);
+        mConnectionStatusListener =
+                new ConnectionStatusListener(countDownLatchForConnectionStatusListener);
+        mWifiManager.addSuggestionConnectionStatusListener(
+                Executors.newSingleThreadExecutor(), mConnectionStatusListener);
 
-        // Step 1.b: Register network callback to wait for connection state.
+        // Step: Register network callback to wait for connection state.
         mNetworkRequest = new NetworkRequest.Builder()
                 .addTransportType(TRANSPORT_WIFI)
                 .build();
         mNetworkCallback = new CallbackUtils.NetworkCallback(CALLBACK_TIMEOUT_MS);
         mConnectivityManager.registerNetworkCallback(mNetworkRequest, mNetworkCallback);
 
-        // Step 2: Create a suggestion for the chosen open network depending on the type of test.
-        WifiNetworkSuggestion networkSuggestion = createNetworkSuggestion(openNetwork);
+        // Step: Create a suggestion for the chosen open network depending on the type of test.
+        WifiNetworkSuggestion networkSuggestion = createNetworkSuggestion(testNetwork);
         mNetworkSuggestions.add(networkSuggestion);
 
-        // Step 4: Add a network suggestions.
+        // Step: Add a network suggestions.
         if (DBG) Log.v(TAG, "Adding suggestion");
         mListener.onTestMsgReceived(mContext.getString(R.string.wifi_status_suggestion_add));
         if (mWifiManager.addNetworkSuggestions(mNetworkSuggestions)
@@ -147,8 +225,14 @@
             setFailureReason(mContext.getString(R.string.wifi_status_suggestion_add_failure));
             return false;
         }
+        if (DBG) Log.v(TAG, "Getting suggestion");
+        List<WifiNetworkSuggestion> retrievedSuggestions = mWifiManager.getNetworkSuggestions();
+        if (!Objects.equals(mNetworkSuggestions, retrievedSuggestions)) {
+            setFailureReason(mContext.getString(R.string.wifi_status_suggestion_get_failure));
+            return false;
+        }
 
-        // Step 5: Trigger scans periodically to trigger network selection quicker.
+        // Step: Trigger scans periodically to trigger network selection quicker.
         if (DBG) Log.v(TAG, "Triggering scan periodically");
         mExecutorService.scheduleAtFixedRate(() -> {
             if (!mWifiManager.startScan()) {
@@ -156,33 +240,49 @@
             }
         }, 0, PERIODIC_SCAN_INTERVAL_MS, TimeUnit.MILLISECONDS);
 
-        // Step 6: Wait for connection.
-        if (DBG) Log.v(TAG, "Waiting for connection");
-        mListener.onTestMsgReceived(mContext.getString(
-                R.string.wifi_status_suggestion_wait_for_connect));
-        Pair<Boolean, Network> cbStatusForAvailable = mNetworkCallback.waitForAvailable();
-        if (!cbStatusForAvailable.first) {
-            Log.e(TAG, "Failed to get network available callback");
-            setFailureReason(mContext.getString(R.string.wifi_status_network_cb_timeout));
-            return false;
-        }
-        mListener.onTestMsgReceived(
-                mContext.getString(R.string.wifi_status_suggestion_connect));
-
-        // Step 7: Ensure that we connected to the suggested network (optionally, the correct
-        // BSSID).
-        if (!mTestUtils.isConnected("\"" + openNetwork.SSID + "\"",
-                // TODO: This might fail if there are other BSSID's for the same network & the
-                //  device decided to connect/roam to a different BSSID. We don't turn off roaming
-                //  for suggestions.
-                mSetBssid ? openNetwork.BSSID : null)) {
-            Log.e(TAG, "Failed to connected to a wrong network");
-            setFailureReason(mContext.getString(R.string.wifi_status_connected_to_other_network));
-            return false;
+        // Step: Wait for connection/unavailable.
+        if (!mSimulateConnectionFailure) {
+            if (DBG) Log.v(TAG, "Waiting for connection");
+            mListener.onTestMsgReceived(mContext.getString(
+                    R.string.wifi_status_suggestion_wait_for_connect));
+            Pair<Boolean, Network> cbStatusForAvailable = mNetworkCallback.waitForAvailable();
+            if (!cbStatusForAvailable.first) {
+                Log.e(TAG, "Failed to get network available callback");
+                setFailureReason(mContext.getString(R.string.wifi_status_network_cb_timeout));
+                return false;
+            }
+            mListener.onTestMsgReceived(
+                    mContext.getString(R.string.wifi_status_suggestion_connect));
+        } else {
+            if (DBG) Log.v(TAG, "Ensure no connection");
+            mListener.onTestMsgReceived(mContext.getString(
+                    R.string.wifi_status_suggestion_ensure_no_connect));
+            Pair<Boolean, Network> cbStatusForAvailable = mNetworkCallback.waitForAvailable();
+            if (cbStatusForAvailable.first) {
+                Log.e(TAG, "Unexpectedly got network available callback");
+                setFailureReason(mContext.getString(R.string.wifi_status_network_available_error));
+                return false;
+            }
+            mListener.onTestMsgReceived(
+                    mContext.getString(R.string.wifi_status_suggestion_not_connected));
         }
 
+        // Step: Ensure that we connected to the suggested network (optionally, the correct BSSID).
+        if (!mSimulateConnectionFailure) {
+            if (!mTestUtils.isConnected("\"" + testNetwork.SSID + "\"",
+                    // TODO: This might fail if there are other BSSID's for the same network & the
+                    //  device decided to connect/roam to a different BSSID. We don't turn off
+                    //  roaming for suggestions.
+                    mSetBssid ? testNetwork.BSSID : null)) {
+                Log.e(TAG, "Failed to connected to the network");
+                setFailureReason(
+                        mContext.getString(R.string.wifi_status_connected_to_other_network));
+                return false;
+            }
+        }
+
+        // Step (Optional): Ensure we received the post connect broadcast.
         if (mSetRequiresAppInteraction) {
-            // Step 7 (Optional): Ensure we received the post connect broadcast.
             if (DBG) Log.v(TAG, "Wait for post connection broadcast");
             mListener.onTestMsgReceived(
                     mContext.getString(
@@ -197,8 +297,66 @@
             mListener.onTestMsgReceived(
                     mContext.getString(R.string.wifi_status_suggestion_post_connect_bcast));
         }
+        // Step (Optional): Ensure we received the connection status listener.
+        if (mSimulateConnectionFailure) {
+            if (DBG) Log.v(TAG, "Wait for connection status listener");
+            mListener.onTestMsgReceived(
+                    mContext.getString(
+                            R.string.wifi_status_suggestion_wait_for_connection_status));
+            if (!countDownLatchForConnectionStatusListener.await(
+                    CALLBACK_TIMEOUT_MS, TimeUnit.MILLISECONDS)) {
+                Log.e(TAG, "Failed to receive connection status");
+                setFailureReason(mContext.getString(
+                        R.string.wifi_status_suggestion_connection_status_failure));
+                return false;
+            }
+            if (DBG) Log.v(TAG, "Received connection status");
+            if (!Objects.equals(mConnectionStatusListener.wifiNetworkSuggestion, networkSuggestion)
+                    || mConnectionStatusListener.failureReason
+                    != WifiManager.STATUS_SUGGESTION_CONNECTION_FAILURE_AUTHENTICATION) {
+                Log.e(TAG, "Received wrong connection status for "
+                        + mConnectionStatusListener.wifiNetworkSuggestion
+                        + " with reason: " + mConnectionStatusListener.failureReason);
+                setFailureReason(mContext.getString(
+                        R.string.wifi_status_suggestion_connection_status_failure));
+                return false;
+            }
+            mListener.onTestMsgReceived(
+                    mContext.getString(R.string.wifi_status_suggestion_connection_status));
+        }
 
-        // Step 8: Remove the suggestions from the app.
+        if (mSetMeteredPostConnection) {
+            // ensure that the network is not metered before change.
+            if (!mNetworkCallback.getNetworkCapabilities()
+                    .hasCapability(NET_CAPABILITY_NOT_METERED)) {
+                Log.e(TAG, "Network meteredness check failed "
+                        + mNetworkCallback.getNetworkCapabilities());
+                setFailureReason(mContext.getString(
+                        R.string.wifi_status_suggestion_metered_check_failed));
+                return false;
+            }
+            if (DBG) Log.v(TAG, "Mark suggestion metered after connection");
+            mListener.onTestMsgReceived(
+                    mContext.getString(R.string.wifi_status_suggestion_metered_change));
+            WifiNetworkSuggestion modifiedSuggestion = mNetworkSuggestionBuilder
+                    .setIsMetered(true)
+                    .build();
+            if (mWifiManager.addNetworkSuggestions(Arrays.asList(modifiedSuggestion))
+                    != STATUS_NETWORK_SUGGESTIONS_SUCCESS) {
+                setFailureReason(mContext.getString(R.string.wifi_status_suggestion_add_failure));
+                return false;
+            }
+            if (!waitForNetworkToBeMetered()) {
+                Log.e(TAG, "Network was not marked metered");
+                setFailureReason(mContext.getString(
+                        R.string.wifi_status_suggestion_metered_check_failed));
+                return false;
+            }
+            mListener.onTestMsgReceived(
+                    mContext.getString(R.string.wifi_status_suggestion_metered_changed));
+        }
+
+        // Step: Remove the suggestions from the app.
         if (DBG) Log.v(TAG, "Removing suggestion");
         mListener.onTestMsgReceived(mContext.getString(R.string.wifi_status_suggestion_remove));
         if (mWifiManager.removeNetworkSuggestions(mNetworkSuggestions)
@@ -207,15 +365,19 @@
             return false;
         }
 
-        // Step 9: Ensure we don't disconnect immediately on suggestion removal.
-        mListener.onTestMsgReceived(
-                mContext.getString(R.string.wifi_status_suggestion_wait_for_disconnect));
-        if (DBG) Log.v(TAG, "Ensuring we don't disconnect immediately");
-        boolean cbStatusForLost = mNetworkCallback.waitForLost();
-        if (cbStatusForLost) {
-            Log.e(TAG, "Disconnected from the network immediately");
-            setFailureReason(mContext.getString(R.string.wifi_status_suggestion_disconnected));
-            return false;
+        // Step: Ensure we disconnect immediately on suggestion removal.
+        if (!mSimulateConnectionFailure) {
+            mListener.onTestMsgReceived(
+                    mContext.getString(R.string.wifi_status_suggestion_wait_for_disconnect));
+            if (DBG) Log.v(TAG, "Ensuring we disconnect immediately");
+            boolean cbStatusForLost = mNetworkCallback.waitForLost();
+            if (!cbStatusForLost) {
+                setFailureReason(
+                        mContext.getString(R.string.wifi_status_suggestion_not_disconnected));
+                return false;
+            }
+            mListener.onTestMsgReceived(
+                    mContext.getString(R.string.wifi_status_suggestion_disconnected));
         }
 
         // All done!
@@ -241,6 +403,9 @@
         if (mBroadcastReceiver != null) {
             mContext.unregisterReceiver(mBroadcastReceiver);
         }
+        if (mConnectionStatusListener != null) {
+            mWifiManager.removeSuggestionConnectionStatusListener(mConnectionStatusListener);
+        }
         mWifiManager.removeNetworkSuggestions(new ArrayList<>());
         super.tearDown();
     }
diff --git a/common/device-side/util-axt/src/com/android/compatibility/common/util/NullWebViewUtils.java b/common/device-side/util-axt/src/com/android/compatibility/common/util/NullWebViewUtils.java
index 3153adb..7b27924 100644
--- a/common/device-side/util-axt/src/com/android/compatibility/common/util/NullWebViewUtils.java
+++ b/common/device-side/util-axt/src/com/android/compatibility/common/util/NullWebViewUtils.java
@@ -16,73 +16,20 @@
 
 package com.android.compatibility.common.util;
 
-import android.content.Context;
 import android.content.pm.PackageManager;
 
 /**
  * Utilities to enable the android.webkit.* CTS tests (and others that rely on a functioning
- * android.webkit.WebView implementation) to determine whether a functioning WebView is present
- * on the device or not.
- *
- * Test cases that require android.webkit.* classes should wrap their first usage of WebView in a
- * try catch block, and pass any exception that is thrown to
- * NullWebViewUtils.determineIfWebViewAvailable. The return value of
- * NullWebViewUtils.isWebViewAvailable will then determine if the test should expect to be able to
- * use a WebView.
+ * android.webkit.WebView implementation) to determine whether there should be a WebView
+ * implementation on the device.
  */
 public class NullWebViewUtils {
 
-    private static boolean sWebViewUnavailable;
-
     /**
-     * @param context Current Activity context, used to query the PackageManager.
-     * @param t       An exception thrown by trying to invoke android.webkit.* APIs.
-     */
-    public static void determineIfWebViewAvailable(Context context, Throwable t) {
-        sWebViewUnavailable = !hasWebViewFeature(context) && checkCauseWasUnsupportedOperation(t);
-    }
-
-    /**
-     * After calling determineIfWebViewAvailable, this returns whether a WebView is available on the
-     * device and wheter the test can rely on it.
-     * @return True iff. PackageManager determined that there is no WebView on the device and the
-     *         exception thrown from android.webkit.* was UnsupportedOperationException.
+     * @return true if the device is supposed to have a WebView implementation.
      */
     public static boolean isWebViewAvailable() {
-        return !sWebViewUnavailable;
+        return FeatureUtil.hasSystemFeature(PackageManager.FEATURE_WEBVIEW);
     }
 
-    private static boolean hasWebViewFeature(Context context) {
-        // Query the system property that determins if there is a functional WebView on the device.
-        PackageManager pm = context.getPackageManager();
-        return pm.hasSystemFeature(PackageManager.FEATURE_WEBVIEW);
-    }
-
-    private static boolean checkCauseWasUnsupportedOperation(Throwable t) {
-        if (t == null) return false;
-        while (t.getCause() != null) {
-            t = t.getCause();
-        }
-        return t instanceof UnsupportedOperationException;
-    }
-
-    /**
-     * Some CTS tests (by design) first use android.webkit.* from a background thread. This helper
-     * allows the test to catch the UnsupportedOperationException from that background thread, and
-     * then query the result from the test main thread.
-     */
-    public static class NullWebViewFromThreadExceptionHandler
-            implements Thread.UncaughtExceptionHandler {
-        private Throwable mPendingException;
-
-        @Override
-        public void uncaughtException(Thread t, Throwable e) {
-            mPendingException = e;
-        }
-
-        public boolean isWebViewAvailable(Context context) {
-            return hasWebViewFeature(context) ||
-                    !checkCauseWasUnsupportedOperation(mPendingException);
-        }
-    }
 }
diff --git a/hostsidetests/appcompat/compatchanges/src/com/android/cts/appcompat/CompatChangesValidConfigTest.java b/hostsidetests/appcompat/compatchanges/src/com/android/cts/appcompat/CompatChangesValidConfigTest.java
index f9bdc22..fa1e4ec 100644
--- a/hostsidetests/appcompat/compatchanges/src/com/android/cts/appcompat/CompatChangesValidConfigTest.java
+++ b/hostsidetests/appcompat/compatchanges/src/com/android/cts/appcompat/CompatChangesValidConfigTest.java
@@ -45,19 +45,23 @@
                                                 + "(; name=(?<changeName>[^;]+))?"
                                                 + "(; enableAfterTargetSdk=(?<targetSdk>[0-9]+))?"
                                                 + "(; (?<disabled>disabled))?"
+                                                + "(; (?<loggingOnly>loggingOnly))?"
                                                 + "(; packageOverrides=(?<overrides>[^\\)]+))?"
                                                 + "\\)");
         long changeId;
         String changeName;
         int targetSdk;
         boolean disabled;
+        boolean loggingOnly;
         boolean hasOverrides;
 
-        private Change(long changeId, String changeName, int targetSdk, boolean disabled, boolean hasOverrides) {
+        private Change(long changeId, String changeName, int targetSdk, boolean disabled,
+                boolean loggingOnly, boolean hasOverrides) {
             this.changeId = changeId;
             this.changeName = changeName;
             this.targetSdk = targetSdk;
             this.disabled = disabled;
+            this.loggingOnly = loggingOnly;
             this.hasOverrides = hasOverrides;
         }
 
@@ -66,6 +70,7 @@
             String changeName;
             int targetSdk = 0;
             boolean disabled = false;
+            boolean loggingOnly = false;
             boolean hasOverrides = false;
 
             Matcher matcher = CHANGE_REGEX.matcher(line);
@@ -90,10 +95,13 @@
             if (matcher.group("disabled") != null) {
                 disabled = true;
             }
+            if (matcher.group("loggingOnly") != null) {
+                loggingOnly = true;
+            }
             if (matcher.group("overrides") != null) {
                 hasOverrides = true;
             }
-            return new Change(changeId, changeName, targetSdk, disabled, hasOverrides);
+            return new Change(changeId, changeName, targetSdk, disabled, loggingOnly, hasOverrides);
         }
 
         static Change fromNode(Node node) {
@@ -108,8 +116,12 @@
             if (element.hasAttribute("disabled")) {
                 disabled = true;
             }
+            boolean loggingOnly = false;
+            if (element.hasAttribute("loggingOnly")) {
+                loggingOnly = true;
+            }
             boolean hasOverrides = false;
-            return new Change(changeId, changeName, targetSdk, disabled, hasOverrides);
+            return new Change(changeId, changeName, targetSdk, disabled, loggingOnly, hasOverrides);
         }
         @Override
         public int hashCode() {
@@ -128,6 +140,7 @@
                 && Objects.equals(this.changeName, that.changeName)
                 && this.targetSdk == that.targetSdk
                 && this.disabled == that.disabled
+                && this.loggingOnly == that.loggingOnly
                 && this.hasOverrides == that.hasOverrides;
         }
         @Override
diff --git a/hostsidetests/appsecurity/Android.mk b/hostsidetests/appsecurity/Android.mk
index ee149f0..55d7720 100644
--- a/hostsidetests/appsecurity/Android.mk
+++ b/hostsidetests/appsecurity/Android.mk
@@ -28,6 +28,9 @@
 	truth-prebuilt \
 	hamcrest-library
 
+LOCAL_STATIC_JAVA_LIBRARIES := \
+	CompatChangeGatingTestBase
+
 LOCAL_JAVA_RESOURCE_DIRS := res
 
 LOCAL_CTS_TEST_PACKAGE := android.appsecurity
diff --git a/hostsidetests/appsecurity/src/android/appsecurity/cts/DocumentsTest.java b/hostsidetests/appsecurity/src/android/appsecurity/cts/DocumentsTest.java
index 1465bc3..00ddbb0 100644
--- a/hostsidetests/appsecurity/src/android/appsecurity/cts/DocumentsTest.java
+++ b/hostsidetests/appsecurity/src/android/appsecurity/cts/DocumentsTest.java
@@ -18,6 +18,8 @@
 
 import com.android.compatibility.common.tradefed.build.CompatibilityBuildHelper;
 
+import com.google.common.collect.ImmutableSet;
+
 /**
  * Set of tests that verify behavior of
  * {@link android.provider.DocumentsContract} and related intents.
@@ -27,6 +29,8 @@
     private static final String PROVIDER_APK = "CtsDocumentProvider.apk";
     private static final String DUMMYIME_APK = "CtsDummyIme.apk";
 
+    private static final long RESTRICT_STORAGE_ACCESS_FRAMEWORK = 141600225L;
+
     @Override
     protected void setUp() throws Exception {
         super.setUp();
@@ -65,10 +69,6 @@
         runDeviceTests(CLIENT_PKG, ".DocumentsClientTest", "testTree");
     }
 
-    public void testTree_blockFromTree() throws Exception {
-        runDeviceTests(CLIENT_PKG, ".DocumentsClientTest", "testTree_blockFromTree");
-    }
-
     public void testGetContent_rootsShowing() throws Exception {
         runDeviceTests(CLIENT_PKG, ".DocumentsClientTest", "testGetContent_rootsShowing");
     }
@@ -119,4 +119,18 @@
     public void testEject() throws Exception {
         runDeviceTests(CLIENT_PKG, ".DocumentsClientTest", "testEject");
     }
+
+    public void testRestrictStorageAccessFrameworkEnabled_blockFromTree() throws Exception {
+        runDeviceCompatTest(CLIENT_PKG, ".DocumentsClientTest",
+                "testRestrictStorageAccessFrameworkEnabled_blockFromTree",
+                /* enabledChanges */ ImmutableSet.of(RESTRICT_STORAGE_ACCESS_FRAMEWORK),
+                /* disabledChanges */ ImmutableSet.of());
+    }
+
+    public void testRestrictStorageAccessFrameworkDisabled_notBlockFromTree() throws Exception {
+        runDeviceCompatTest(CLIENT_PKG, ".DocumentsClientTest",
+                "testRestrictStorageAccessFrameworkDisabled_notBlockFromTree",
+                /* enabledChanges */ ImmutableSet.of(),
+                /* disabledChanges */ ImmutableSet.of(RESTRICT_STORAGE_ACCESS_FRAMEWORK));
+    }
 }
diff --git a/hostsidetests/appsecurity/src/android/appsecurity/cts/DocumentsTestCase.java b/hostsidetests/appsecurity/src/android/appsecurity/cts/DocumentsTestCase.java
index 1af0650..d7a9ffc 100644
--- a/hostsidetests/appsecurity/src/android/appsecurity/cts/DocumentsTestCase.java
+++ b/hostsidetests/appsecurity/src/android/appsecurity/cts/DocumentsTestCase.java
@@ -16,23 +16,21 @@
 
 package android.appsecurity.cts;
 
+import android.compat.cts.CompatChangeGatingTestCase;
+
 import com.android.compatibility.common.tradefed.build.CompatibilityBuildHelper;
-import com.android.tradefed.build.IBuildInfo;
 import com.android.tradefed.device.DeviceNotAvailableException;
-import com.android.tradefed.testtype.DeviceTestCase;
 import com.android.tradefed.testtype.IAbi;
 import com.android.tradefed.testtype.IAbiReceiver;
-import com.android.tradefed.testtype.IBuildReceiver;
 
 /**
  * Base class for {@link android.provider.DocumentsContract} and related test cases.
  */
-abstract class DocumentsTestCase extends DeviceTestCase implements IAbiReceiver, IBuildReceiver {
+abstract class DocumentsTestCase extends CompatChangeGatingTestCase implements IAbiReceiver {
     protected static final String CLIENT_PKG = "com.android.cts.documentclient";
     protected static final String CLIENT_APK = "CtsDocumentClient.apk";
 
     protected IAbi mAbi;
-    protected IBuildInfo mCtsBuild;
 
     @Override
     public void setAbi(IAbi abi) {
@@ -40,17 +38,11 @@
     }
 
     @Override
-    public void setBuild(IBuildInfo buildInfo) {
-        mCtsBuild = buildInfo;
-    }
-
-    @Override
     protected void setUp() throws Exception {
         super.setUp();
 
         Utils.prepareSingleUser(getDevice());
         assertNotNull(mAbi);
-        assertNotNull(mCtsBuild);
 
         reinstallClientPackage();
     }
diff --git a/hostsidetests/appsecurity/src/android/appsecurity/cts/ExternalStorageHostTest.java b/hostsidetests/appsecurity/src/android/appsecurity/cts/ExternalStorageHostTest.java
index 38a76d9..ab6e0bd 100644
--- a/hostsidetests/appsecurity/src/android/appsecurity/cts/ExternalStorageHostTest.java
+++ b/hostsidetests/appsecurity/src/android/appsecurity/cts/ExternalStorageHostTest.java
@@ -655,9 +655,6 @@
 
                 runDeviceTests(WRITE_PKG_2, WRITE_PKG + ".WriteGiftTest",
                         "testNotIsExternalStorageLegacy", user);
-                updateAppOp(WRITE_PKG_2, user, "android:request_install_packages", true);
-                runDeviceTests(WRITE_PKG_2, WRITE_PKG + ".WriteGiftTest",
-                        "testIsExternalStorageLegacy", user);
             }
         } finally {
             getDevice().uninstallPackage(WRITE_PKG);
diff --git a/hostsidetests/appsecurity/src/android/appsecurity/cts/SessionReferrerUriTest.java b/hostsidetests/appsecurity/src/android/appsecurity/cts/SessionReferrerUriTest.java
new file mode 100644
index 0000000..7477721
--- /dev/null
+++ b/hostsidetests/appsecurity/src/android/appsecurity/cts/SessionReferrerUriTest.java
@@ -0,0 +1,62 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.appsecurity.cts;
+
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
+
+import android.platform.test.annotations.AppModeFull;
+
+import com.android.tradefed.device.DeviceNotAvailableException;
+import com.android.tradefed.testtype.DeviceJUnit4ClassRunner;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import java.io.File;
+
+@RunWith(DeviceJUnit4ClassRunner.class)
+public class SessionReferrerUriTest extends BaseAppSecurityTest {
+
+    private static final String SESSION_INSPECTOR_A_APK = "CtsSessionInspectorAppA.apk";
+    private static final String SESSION_INSPECTOR_B_APK = "CtsSessionInspectorAppB.apk";
+    private static final String SESSION_INSPECTOR_PKG_A = "com.android.cts.sessioninspector.a";
+    private static final String SESSION_INSPECTOR_PKG_B = "com.android.cts.sessioninspector.b";
+
+    @Before
+    public void setup() throws Exception {
+        new InstallMultiple().addApk(SESSION_INSPECTOR_A_APK).run();
+        new InstallMultiple().addApk(SESSION_INSPECTOR_B_APK).run();
+    }
+
+    @After
+    public void teardown() throws Exception {
+        getDevice().uninstallPackage(SESSION_INSPECTOR_PKG_A);
+        getDevice().uninstallPackage(SESSION_INSPECTOR_PKG_B);
+    }
+
+    @Test
+    @AppModeFull(reason = "Only full apps may install")
+    public void testSessionReferrerUriVisibleToOwner() throws DeviceNotAvailableException {
+        Utils.runDeviceTests(getDevice(), SESSION_INSPECTOR_PKG_A,
+                "com.android.cts.sessioninspector.SessionInspectorTest", "testOnlyOwnerCanSee");
+        Utils.runDeviceTests(getDevice(), SESSION_INSPECTOR_PKG_B,
+                "com.android.cts.sessioninspector.SessionInspectorTest", "testOnlyOwnerCanSee");
+    }
+}
diff --git a/hostsidetests/appsecurity/test-apps/DocumentClient/AndroidManifest.xml b/hostsidetests/appsecurity/test-apps/DocumentClient/AndroidManifest.xml
index c90a6f6..e87cd6f 100644
--- a/hostsidetests/appsecurity/test-apps/DocumentClient/AndroidManifest.xml
+++ b/hostsidetests/appsecurity/test-apps/DocumentClient/AndroidManifest.xml
@@ -16,7 +16,9 @@
 
 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
         package="com.android.cts.documentclient">
-    <application>
+    <uses-sdk android:minSdkVersion="29" android:targetSdkVersion="29"/>
+
+    <application android:debuggable="true" android:forceQueryable="true">
         <uses-library android:name="android.test.runner" />
         <activity android:name=".MyActivity" />
     </application>
diff --git a/hostsidetests/appsecurity/test-apps/DocumentClient/src/com/android/cts/documentclient/DocumentsClientTest.java b/hostsidetests/appsecurity/test-apps/DocumentClient/src/com/android/cts/documentclient/DocumentsClientTest.java
index 1f302dd..40d8ff4 100644
--- a/hostsidetests/appsecurity/test-apps/DocumentClient/src/com/android/cts/documentclient/DocumentsClientTest.java
+++ b/hostsidetests/appsecurity/test-apps/DocumentClient/src/com/android/cts/documentclient/DocumentsClientTest.java
@@ -357,19 +357,58 @@
         }
     }
 
-    public void testTree_blockFromTree() throws Exception {
+    public void testRestrictStorageAccessFrameworkEnabled_blockFromTree() throws Exception {
         if (!supportedHardware()) return;
 
         final Intent intent = new Intent(Intent.ACTION_OPEN_DOCUMENT_TREE);
         mActivity.startActivityForResult(intent, REQUEST_CODE);
 
         mDevice.waitForIdle();
+
+        // save button is disabled for the storage root
+        assertFalse(findSaveButton().isEnabled());
+
+        findDocument("Download").click();
+        mDevice.waitForIdle();
+
+        // save button is disabled for Download folder
+        assertFalse(findSaveButton().isEnabled());
+
         findRoot("CtsCreate").click();
+        mDevice.waitForIdle();
+
+        // save button is disabled for CtsCreate root
+        assertFalse(findSaveButton().isEnabled());
+
+        findDocument("DIR2").click();
+
+        mDevice.waitForIdle();
+        // save button is enabled for dir2
+        assertTrue(findSaveButton().isEnabled());
+    }
+
+    public void testRestrictStorageAccessFrameworkDisabled_notBlockFromTree() throws Exception {
+        if (!supportedHardware()) return;
+
+        final Intent intent = new Intent(Intent.ACTION_OPEN_DOCUMENT_TREE);
+        mActivity.startActivityForResult(intent, REQUEST_CODE);
 
         mDevice.waitForIdle();
 
-        // save button is disabled for root
-        assertFalse(findSaveButton().isEnabled());
+        // save button is enabled for for the storage root
+        assertTrue(findSaveButton().isEnabled());
+
+        findDocument("Download").click();
+        mDevice.waitForIdle();
+
+        // save button is enabled for Download folder
+        assertTrue(findSaveButton().isEnabled());
+
+        findRoot("CtsCreate").click();
+        mDevice.waitForIdle();
+
+        // save button is enabled for CtsCreate root
+        assertTrue(findSaveButton().isEnabled());
 
         findDocument("DIR2").click();
 
@@ -661,14 +700,6 @@
         // assert the default root is internal storage root
         assertToolbarTitleEquals(title);
 
-        // save button is disabled for the root
-        assertFalse(findSaveButton().isEnabled());
-
-        findDocument("Download").click();
-        mDevice.waitForIdle();
-        // save button is disabled for Download folder
-        assertFalse(findSaveButton().isEnabled());
-
         // no Downloads root
         assertFalse(findRoot("Downloads").exists());
     }
diff --git a/hostsidetests/appsecurity/test-apps/DocumentProvider/AndroidManifest.xml b/hostsidetests/appsecurity/test-apps/DocumentProvider/AndroidManifest.xml
index 6e140d7..2b2f1fd 100644
--- a/hostsidetests/appsecurity/test-apps/DocumentProvider/AndroidManifest.xml
+++ b/hostsidetests/appsecurity/test-apps/DocumentProvider/AndroidManifest.xml
@@ -16,7 +16,7 @@
 
 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
           package="com.android.cts.documentprovider">
-    <application>
+    <application android:forceQueryable="true">
         <uses-library android:name="android.test.runner" />
 
         <provider android:name=".MyDocumentsProvider"
diff --git a/hostsidetests/appsecurity/test-apps/EphemeralTestApp/EphemeralApp1/src/com/android/cts/ephemeralapp1/WebViewTestActivity.java b/hostsidetests/appsecurity/test-apps/EphemeralTestApp/EphemeralApp1/src/com/android/cts/ephemeralapp1/WebViewTestActivity.java
index aae2b65..5ee2ea1 100644
--- a/hostsidetests/appsecurity/test-apps/EphemeralTestApp/EphemeralApp1/src/com/android/cts/ephemeralapp1/WebViewTestActivity.java
+++ b/hostsidetests/appsecurity/test-apps/EphemeralTestApp/EphemeralApp1/src/com/android/cts/ephemeralapp1/WebViewTestActivity.java
@@ -29,13 +29,13 @@
 
     @Override
     public void onCreate(Bundle savedInstanceState) {
-        try {
-            super.onCreate(savedInstanceState);
-            mWebView = new WebView(this);
-            setContentView(mWebView);
-        } catch (Exception e) {
-            NullWebViewUtils.determineIfWebViewAvailable(this, e);
-        }
+        super.onCreate(savedInstanceState);
+
+        // Only create the WebView if the device is supposed to have a WebView implementation.
+        if (!NullWebViewUtils.isWebViewAvailable()) return;
+
+        mWebView = new WebView(this);
+        setContentView(mWebView);
     }
 
     public WebView getWebView() {
diff --git a/hostsidetests/appsecurity/test-apps/MediaStorageApp/src/com/android/cts/mediastorageapp/MediaStorageTest.java b/hostsidetests/appsecurity/test-apps/MediaStorageApp/src/com/android/cts/mediastorageapp/MediaStorageTest.java
index 61f342c..0886269 100644
--- a/hostsidetests/appsecurity/test-apps/MediaStorageApp/src/com/android/cts/mediastorageapp/MediaStorageTest.java
+++ b/hostsidetests/appsecurity/test-apps/MediaStorageApp/src/com/android/cts/mediastorageapp/MediaStorageTest.java
@@ -473,8 +473,7 @@
 
         // Some dialogs may have granted access automatically, so we're willing
         // to keep rolling forward if we can't find our grant button
-        final UiSelector grant = new UiSelector()
-                .textMatches("(Allow|Change|Move to trash|Move out of trash|Delete)");
+        final UiSelector grant = new UiSelector().textMatches("Allow");
         if (new UiObject(grant).waitForExists(2_000)) {
             device.findObject(grant).click();
         }
diff --git a/hostsidetests/appsecurity/test-apps/SessionInspector/Android.bp b/hostsidetests/appsecurity/test-apps/SessionInspector/Android.bp
new file mode 100644
index 0000000..421c9de
--- /dev/null
+++ b/hostsidetests/appsecurity/test-apps/SessionInspector/Android.bp
@@ -0,0 +1,42 @@
+// Copyright (C) 2020 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+android_test_helper_app {
+    name: "CtsSessionInspectorAppA",
+    defaults: ["cts_support_defaults"],
+    manifest: "AndroidManifestA.xml",
+    sdk_version: "test_current",
+    srcs: ["src/**/*.java"],
+    static_libs: ["androidx.test.rules"],
+    // tag this module as a cts test artifact
+    test_suites: [
+        "cts",
+        "vts",
+        "general-tests",
+    ],
+}
+android_test_helper_app {
+    name: "CtsSessionInspectorAppB",
+    defaults: ["cts_support_defaults"],
+    manifest: "AndroidManifestB.xml",
+    sdk_version: "test_current",
+    srcs: ["src/**/*.java"],
+    static_libs: ["androidx.test.rules"],
+    // tag this module as a cts test artifact
+    test_suites: [
+        "cts",
+        "vts",
+        "general-tests",
+    ],
+}
diff --git a/tests/tests/jni_vendor/AndroidManifest.xml b/hostsidetests/appsecurity/test-apps/SessionInspector/AndroidManifestA.xml
similarity index 60%
copy from tests/tests/jni_vendor/AndroidManifest.xml
copy to hostsidetests/appsecurity/test-apps/SessionInspector/AndroidManifestA.xml
index 96a1c9e..c68bc67 100644
--- a/tests/tests/jni_vendor/AndroidManifest.xml
+++ b/hostsidetests/appsecurity/test-apps/SessionInspector/AndroidManifestA.xml
@@ -1,5 +1,5 @@
 <?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2017 The Android Open Source Project
+<!-- Copyright (C) 2020 The Android Open Source Project
 
      Licensed under the Apache License, Version 2.0 (the "License");
      you may not use this file except in compliance with the License.
@@ -13,22 +13,18 @@
      See the License for the specific language governing permissions and
      limitations under the License.
 -->
-
 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
-    package="android.jni.vendor.cts">
+       package="com.android.cts.sessioninspector.a">
 
-    <uses-permission android:name="android.permission.DISABLE_KEYGUARD" />
-    <application>
+    <instrumentation android:name="androidx.test.runner.AndroidJUnitRunner"
+                     android:targetPackage="com.android.cts.sessioninspector.a" />
+
+    <uses-permission android:name="android.permission.REQUEST_INSTALL_PACKAGES" />
+
+    <application android:forceQueryable="true">
         <uses-library android:name="android.test.runner" />
+        <activity android:name="com.android.cts.sessioninspector.SessionInspectorActivity"
+                  android:exported="true"/>
     </application>
 
-    <!-- This is a self-instrumenting test package. -->
-    <instrumentation android:name="androidx.test.runner.AndroidJUnitRunner"
-                     android:targetPackage="android.jni.vendor.cts"
-                     android:label="CTS tests of calling native code via Vendor's JNI">
-        <meta-data android:name="listener"
-            android:value="com.android.cts.runner.CtsTestRunListener" />
-    </instrumentation>
-
 </manifest>
-
diff --git a/tests/tests/jni_vendor/AndroidManifest.xml b/hostsidetests/appsecurity/test-apps/SessionInspector/AndroidManifestB.xml
similarity index 60%
rename from tests/tests/jni_vendor/AndroidManifest.xml
rename to hostsidetests/appsecurity/test-apps/SessionInspector/AndroidManifestB.xml
index 96a1c9e..7db8db6 100644
--- a/tests/tests/jni_vendor/AndroidManifest.xml
+++ b/hostsidetests/appsecurity/test-apps/SessionInspector/AndroidManifestB.xml
@@ -1,5 +1,5 @@
 <?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2017 The Android Open Source Project
+<!-- Copyright (C) 2020 The Android Open Source Project
 
      Licensed under the Apache License, Version 2.0 (the "License");
      you may not use this file except in compliance with the License.
@@ -13,22 +13,18 @@
      See the License for the specific language governing permissions and
      limitations under the License.
 -->
-
 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
-    package="android.jni.vendor.cts">
+       package="com.android.cts.sessioninspector.b">
 
-    <uses-permission android:name="android.permission.DISABLE_KEYGUARD" />
-    <application>
+    <instrumentation android:name="androidx.test.runner.AndroidJUnitRunner"
+                     android:targetPackage="com.android.cts.sessioninspector.b" />
+
+    <uses-permission android:name="android.permission.REQUEST_INSTALL_PACKAGES" />
+
+    <application android:forceQueryable="true">
         <uses-library android:name="android.test.runner" />
+        <activity android:name="com.android.cts.sessioninspector.SessionInspectorActivity"
+                  android:exported="true"/>
     </application>
 
-    <!-- This is a self-instrumenting test package. -->
-    <instrumentation android:name="androidx.test.runner.AndroidJUnitRunner"
-                     android:targetPackage="android.jni.vendor.cts"
-                     android:label="CTS tests of calling native code via Vendor's JNI">
-        <meta-data android:name="listener"
-            android:value="com.android.cts.runner.CtsTestRunListener" />
-    </instrumentation>
-
 </manifest>
-
diff --git a/hostsidetests/appsecurity/test-apps/SessionInspector/OWNERS b/hostsidetests/appsecurity/test-apps/SessionInspector/OWNERS
new file mode 100644
index 0000000..9d4a924
--- /dev/null
+++ b/hostsidetests/appsecurity/test-apps/SessionInspector/OWNERS
@@ -0,0 +1,4 @@
+# Bug component: 533114
+patb@google.com
+toddke@google.com
+chiuwinson@google.com
diff --git a/hostsidetests/appsecurity/test-apps/SessionInspector/src/com/android/cts/sessioninspector/Constants.java b/hostsidetests/appsecurity/test-apps/SessionInspector/src/com/android/cts/sessioninspector/Constants.java
new file mode 100644
index 0000000..6957448
--- /dev/null
+++ b/hostsidetests/appsecurity/test-apps/SessionInspector/src/com/android/cts/sessioninspector/Constants.java
@@ -0,0 +1,34 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.cts.sessioninspector;
+
+import android.net.Uri;
+
+public class Constants {
+    private static final String PKG_BASE = "com.android.cts.sessioninspector.";
+
+    public static final String ACTION_CREATE_SESSION = PKG_BASE + "CREATE_SESSION";
+    public static final String ACTION_GET_SESSION = PKG_BASE + "GET_SESSION";
+    public static final String ACTION_ABANDON_SESSION = PKG_BASE + "ABANDON_SESSION";
+
+    public static final String PACKAGE_A = PKG_BASE + "a";
+    public static final String PACKAGE_B = PKG_BASE + "b";
+
+    public static final String ACTIVITY_NAME = PKG_BASE + "SessionInspectorActivity";
+
+    public static final Uri REFERRER_URI = Uri.parse("https://user-sensitive-domain.com/");
+}
diff --git a/hostsidetests/appsecurity/test-apps/SessionInspector/src/com/android/cts/sessioninspector/SessionInspectorActivity.java b/hostsidetests/appsecurity/test-apps/SessionInspector/src/com/android/cts/sessioninspector/SessionInspectorActivity.java
new file mode 100644
index 0000000..edf90f2
--- /dev/null
+++ b/hostsidetests/appsecurity/test-apps/SessionInspector/src/com/android/cts/sessioninspector/SessionInspectorActivity.java
@@ -0,0 +1,73 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.cts.sessioninspector;
+
+import static android.content.Intent.EXTRA_RESULT_RECEIVER;
+import static android.content.pm.PackageInstaller.EXTRA_SESSION;
+import static android.content.pm.PackageInstaller.EXTRA_SESSION_ID;
+import static android.content.pm.PackageInstaller.SessionInfo;
+import static android.content.pm.PackageInstaller.SessionParams;
+import static android.content.pm.PackageInstaller.SessionParams.MODE_FULL_INSTALL;
+
+import static com.android.cts.sessioninspector.Constants.ACTION_ABANDON_SESSION;
+import static com.android.cts.sessioninspector.Constants.ACTION_CREATE_SESSION;
+import static com.android.cts.sessioninspector.Constants.ACTION_GET_SESSION;
+import static com.android.cts.sessioninspector.Constants.REFERRER_URI;
+
+import android.app.Activity;
+import android.os.Bundle;
+import android.os.RemoteCallback;
+
+public class SessionInspectorActivity extends Activity {
+
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        RemoteCallback remoteCallback = getIntent().getParcelableExtra(EXTRA_RESULT_RECEIVER);
+        final Bundle result = new Bundle();
+        String action = getIntent().getAction();
+        try {
+            switch (action) {
+                case ACTION_CREATE_SESSION:
+                    SessionParams params = new SessionParams(MODE_FULL_INSTALL);
+                    params.setReferrerUri(REFERRER_URI);
+                    final int session =
+                            getPackageManager().getPackageInstaller().createSession(params);
+                    result.putInt(EXTRA_SESSION_ID, session);
+                    break;
+                case ACTION_GET_SESSION: {
+                    final int sessionId = getIntent().getIntExtra(EXTRA_SESSION_ID, 0);
+                    final SessionInfo sessionInfo =
+                            getPackageManager().getPackageInstaller().getSessionInfo(sessionId);
+                    result.putParcelable(EXTRA_SESSION, sessionInfo);
+                    break;
+                }
+                case ACTION_ABANDON_SESSION: {
+                    final int sessionId = getIntent().getIntExtra(EXTRA_SESSION_ID, 0);
+                    getPackageManager().getPackageInstaller().abandonSession(sessionId);
+                    break;
+                }
+                default:
+                    throw new IllegalArgumentException("Unrecognized action: " + action);
+            }
+        } catch (Exception e) {
+            result.putSerializable("error", e);
+        }
+        remoteCallback.sendResult(result);
+        finish();
+    }
+}
diff --git a/hostsidetests/appsecurity/test-apps/SessionInspector/src/com/android/cts/sessioninspector/SessionInspectorTest.java b/hostsidetests/appsecurity/test-apps/SessionInspector/src/com/android/cts/sessioninspector/SessionInspectorTest.java
new file mode 100644
index 0000000..8afcdef
--- /dev/null
+++ b/hostsidetests/appsecurity/test-apps/SessionInspector/src/com/android/cts/sessioninspector/SessionInspectorTest.java
@@ -0,0 +1,108 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.cts.sessioninspector;
+
+import static com.android.cts.sessioninspector.Constants.ACTION_ABANDON_SESSION;
+import static com.android.cts.sessioninspector.Constants.ACTION_CREATE_SESSION;
+import static com.android.cts.sessioninspector.Constants.ACTION_GET_SESSION;
+import static com.android.cts.sessioninspector.Constants.ACTIVITY_NAME;
+import static com.android.cts.sessioninspector.Constants.REFERRER_URI;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNull;
+
+import android.content.ComponentName;
+import android.content.Context;
+import android.content.Intent;
+import android.content.pm.PackageInstaller;
+import android.net.Uri;
+import android.os.Bundle;
+import android.os.ConditionVariable;
+import android.os.RemoteCallback;
+
+import androidx.test.InstrumentationRegistry;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.JUnit4;
+
+import java.util.UUID;
+import java.util.concurrent.TimeUnit;
+
+@RunWith(JUnit4.class)
+public class SessionInspectorTest {
+
+    @Test
+    public void testOnlyOwnerCanSee() throws Exception {
+        String myPackage = Constants.PACKAGE_A.equals(getContext().getPackageName())
+                ? Constants.PACKAGE_A : Constants.PACKAGE_B;
+        String otherPackage = Constants.PACKAGE_A.equals(myPackage) ? Constants.PACKAGE_B
+                : Constants.PACKAGE_A;
+
+        int sessionId = createSession(myPackage);
+
+        final PackageInstaller.SessionInfo sessionToMe = getSessionInfo(myPackage, sessionId);
+        final PackageInstaller.SessionInfo sessionToOther = getSessionInfo(otherPackage, sessionId);
+
+        abandonSession(myPackage, sessionId);
+
+        assertEquals(REFERRER_URI, sessionToMe.getReferrerUri());
+        assertNull(sessionToOther.getReferrerUri());
+    }
+
+    private Context getContext() {
+        return InstrumentationRegistry.getContext();
+    }
+
+    private int createSession(String packageName) throws Exception {
+        Bundle result = sendCommand(new Intent(ACTION_CREATE_SESSION).setComponent(
+                new ComponentName(packageName, ACTIVITY_NAME)));
+        return result.getInt(PackageInstaller.EXTRA_SESSION_ID, 0);
+    }
+
+    private PackageInstaller.SessionInfo getSessionInfo(String packageName, int session)
+            throws Exception {
+        Bundle result = sendCommand(new Intent(ACTION_GET_SESSION).putExtra(
+                PackageInstaller.EXTRA_SESSION_ID, session).setComponent(
+                new ComponentName(packageName, ACTIVITY_NAME)));
+        return result.getParcelable(PackageInstaller.EXTRA_SESSION);
+    }
+
+    private void abandonSession(String packageName, int sessionId) throws Exception {
+        sendCommand(new Intent(ACTION_ABANDON_SESSION).putExtra(PackageInstaller.EXTRA_SESSION_ID,
+                sessionId).setComponent(new ComponentName(packageName, ACTIVITY_NAME)));
+    }
+
+    private Bundle sendCommand(Intent intent) throws Exception {
+        ConditionVariable condition = new ConditionVariable();
+        final Bundle[] resultHolder = new Bundle[1];
+        RemoteCallback callback = new RemoteCallback(result -> {
+            resultHolder[0] = result;
+            condition.open();
+        });
+        intent.putExtra(Intent.EXTRA_RESULT_RECEIVER, callback);
+        intent.setData(Uri.parse("https://" + UUID.randomUUID()));
+        intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+        getContext().startActivity(intent);
+        condition.block(TimeUnit.SECONDS.toMillis(10));
+        Bundle result = resultHolder[0];
+        if (result.containsKey("error")) {
+            throw (Exception) result.getSerializable("error");
+        }
+        return result;
+    }
+}
diff --git a/hostsidetests/appsecurity/test-apps/StorageApp/src/com/android/cts/storageapp/Utils.java b/hostsidetests/appsecurity/test-apps/StorageApp/src/com/android/cts/storageapp/Utils.java
index 42ba7f3..46ca3ae 100644
--- a/hostsidetests/appsecurity/test-apps/StorageApp/src/com/android/cts/storageapp/Utils.java
+++ b/hostsidetests/appsecurity/test-apps/StorageApp/src/com/android/cts/storageapp/Utils.java
@@ -134,7 +134,15 @@
 
     public static long getSizeManual(File dir, boolean excludeObb) throws Exception {
         long size = getAllocatedSize(dir);
-        for (File f : dir.listFiles()) {
+        File[] files = dir.listFiles();
+
+        if (files == null) {
+            // This can happen on devices with scoped storage, where we're not allowed
+            // to iterate Android/ anymore.
+            return size;
+        }
+
+        for (File f : files) {
             if (f.isDirectory()) {
                 if (excludeObb && f.getName().equalsIgnoreCase("obb")
                         && f.getParentFile().getName().equalsIgnoreCase("Android")
diff --git a/hostsidetests/appsecurity/test-apps/StorageStatsApp/src/com/android/cts/storagestatsapp/StorageStatsTest.java b/hostsidetests/appsecurity/test-apps/StorageStatsApp/src/com/android/cts/storagestatsapp/StorageStatsTest.java
index 7b1abec..b1d07e2 100644
--- a/hostsidetests/appsecurity/test-apps/StorageStatsApp/src/com/android/cts/storagestatsapp/StorageStatsTest.java
+++ b/hostsidetests/appsecurity/test-apps/StorageStatsApp/src/com/android/cts/storagestatsapp/StorageStatsTest.java
@@ -230,7 +230,11 @@
         // TODO: remove this once 34723223 is fixed
         logCommand("sync");
 
-        final long manualSize = getSizeManual(Environment.getExternalStorageDirectory(), true);
+        long manualSize = getSizeManual(Environment.getExternalStorageDirectory(), true);
+        // Since scoped storage, we can't walk the Android/ tree anymore; so pass in this
+        // app's files and cache dirs directly.
+        manualSize += getSizeManual(getContext().getExternalFilesDir(null), true);
+        manualSize += getSizeManual(getContext().getExternalCacheDir(), true);
         final long statsSize = stats.queryExternalStatsForUser(UUID_DEFAULT, user).getTotalBytes();
 
         assertMostlyEquals(manualSize, statsSize);
diff --git a/hostsidetests/appsecurity/test-apps/V3SigningSchemeRotation/Android.bp b/hostsidetests/appsecurity/test-apps/V3SigningSchemeRotation/Android.bp
index 4481d9e..9de8251 100644
--- a/hostsidetests/appsecurity/test-apps/V3SigningSchemeRotation/Android.bp
+++ b/hostsidetests/appsecurity/test-apps/V3SigningSchemeRotation/Android.bp
@@ -20,6 +20,7 @@
         "cts",
         "vts",
         "general-tests",
+        "sts",
     ],
     srcs: ["src/**/*.java"],
     sdk_version: "current",
diff --git a/hostsidetests/backup/OtherSoundsSettingsApp/Android.bp b/hostsidetests/backup/OtherSoundsSettingsApp/Android.bp
index fac14e6..e34b256 100644
--- a/hostsidetests/backup/OtherSoundsSettingsApp/Android.bp
+++ b/hostsidetests/backup/OtherSoundsSettingsApp/Android.bp
@@ -27,5 +27,8 @@
         "vts",
         "general-tests",
     ],
-    sdk_version: "test_current",
+    // Uncomment when b/78787392 is fixed
+    // sdk_version: "system_test_current",
+    platform_apis: true,
+
 }
diff --git a/hostsidetests/backup/OtherSoundsSettingsApp/src/android/cts/backup/othersoundssettingsapp/OtherSoundsSettingsTest.java b/hostsidetests/backup/OtherSoundsSettingsApp/src/android/cts/backup/othersoundssettingsapp/OtherSoundsSettingsTest.java
index 46e6b95..868dc40 100644
--- a/hostsidetests/backup/OtherSoundsSettingsApp/src/android/cts/backup/othersoundssettingsapp/OtherSoundsSettingsTest.java
+++ b/hostsidetests/backup/OtherSoundsSettingsApp/src/android/cts/backup/othersoundssettingsapp/OtherSoundsSettingsTest.java
@@ -21,9 +21,13 @@
 import static com.android.compatibility.common.util.BackupUtils.LOCAL_TRANSPORT_TOKEN;
 
 import static org.junit.Assert.assertTrue;
+import static org.junit.Assume.assumeTrue;
 
+import android.app.UiAutomation;
 import android.content.ContentResolver;
+import android.content.Context;
 import android.os.ParcelFileDescriptor;
+import android.os.Vibrator;
 import android.platform.test.annotations.AppModeFull;
 import android.provider.Settings;
 
@@ -31,12 +35,15 @@
 
 import com.android.compatibility.common.util.BackupUtils;
 
+import org.junit.After;
 import org.junit.Before;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 
 import java.io.IOException;
 import java.io.InputStream;
+import java.util.HashMap;
+import java.util.Map;
 
 /**
  * Device side routines to be invoked by the host side OtherSoundsSettingsHostSideTest. These
@@ -48,9 +55,12 @@
 public class OtherSoundsSettingsTest {
     /** The name of the package for backup */
     private static final String SETTINGS_PACKAGE_NAME = "com.android.providers.settings";
+    private static final int SETTING_ABSENT_VALUE = -1;
 
     private ContentResolver mContentResolver;
     private BackupUtils mBackupUtils;
+    private Map<String, Integer> mOriginalSettingValues;
+    private UiAutomation mUiAutomation;
 
     @Before
     public void setUp() throws Exception {
@@ -64,6 +74,15 @@
                         return new ParcelFileDescriptor.AutoCloseInputStream(pfd);
                     }
                 };
+        mOriginalSettingValues = new HashMap<>();
+        mUiAutomation = getInstrumentation().getUiAutomation();
+        mUiAutomation.adoptShellPermissionIdentity();
+    }
+
+    @After
+    public void tearDown() throws Exception {
+        restoreOriginalSettingValues();
+        mUiAutomation.dropShellPermissionIdentity();
     }
 
     /**
@@ -78,17 +97,13 @@
      */
     @Test
     public void testOtherSoundsSettings_dialPadTones() throws Exception {
-        int originalValue =
-                Settings.System.getInt(
-                        mContentResolver, Settings.System.DTMF_TONE_WHEN_DIALING, -1);
+        int originalValue = prepareSystemSetting(Settings.System.DTMF_TONE_WHEN_DIALING);
         assertTrue("Dial pad tones does not exist.", originalValue != -1);
 
         mBackupUtils.backupNowAndAssertSuccess(SETTINGS_PACKAGE_NAME);
 
-        boolean ret =
-                Settings.System.putInt(
-                        mContentResolver, Settings.System.DTMF_TONE_WHEN_DIALING,
-                        1 - originalValue);
+        boolean ret = setSystemSetting(Settings.System.DTMF_TONE_WHEN_DIALING,
+                1 - originalValue);
         assertTrue("Toggle Dial pad tones fail.", ret);
 
         mBackupUtils.restoreAndAssertSuccess(LOCAL_TRANSPORT_TOKEN, SETTINGS_PACKAGE_NAME);
@@ -111,16 +126,13 @@
      */
     @Test
     public void testOtherSoundsSettings_touchSounds() throws Exception {
-        int originalValue =
-                Settings.System.getInt(
-                        mContentResolver, Settings.System.SOUND_EFFECTS_ENABLED, -1);
+        int originalValue = prepareSystemSetting(Settings.System.SOUND_EFFECTS_ENABLED);
         assertTrue("Touch sounds does not exist.", originalValue != -1);
 
         mBackupUtils.backupNowAndAssertSuccess(SETTINGS_PACKAGE_NAME);
 
-        boolean ret =
-                Settings.System.putInt(
-                        mContentResolver, Settings.System.SOUND_EFFECTS_ENABLED, 1 - originalValue);
+        boolean ret = setSystemSetting(Settings.System.SOUND_EFFECTS_ENABLED,
+                1 - originalValue);
         assertTrue("Toggle Touch sounds fail.", ret);
 
         mBackupUtils.restoreAndAssertSuccess(LOCAL_TRANSPORT_TOKEN, SETTINGS_PACKAGE_NAME);
@@ -143,17 +155,21 @@
      */
     @Test
     public void testOtherSoundsSettings_touchVibration() throws Exception {
-        int originalValue =
-                Settings.System.getInt(
-                        mContentResolver, Settings.System.HAPTIC_FEEDBACK_ENABLED, -1);
+        Vibrator mVibrator =
+                (Vibrator)
+                        getInstrumentation()
+                                .getTargetContext()
+                                .getSystemService(Context.VIBRATOR_SERVICE);
+        assumeTrue(
+                "Device Under Test does not have a vibrator, skipping.", mVibrator.hasVibrator());
+
+        int originalValue = prepareSystemSetting(Settings.System.HAPTIC_FEEDBACK_ENABLED);
         assertTrue("Touch vibration does not exist.", originalValue != -1);
 
         mBackupUtils.backupNowAndAssertSuccess(SETTINGS_PACKAGE_NAME);
 
-        boolean ret =
-                Settings.System.putInt(
-                        mContentResolver, Settings.System.HAPTIC_FEEDBACK_ENABLED,
-                        1 - originalValue);
+        boolean ret = setSystemSetting(Settings.System.HAPTIC_FEEDBACK_ENABLED,
+                1 - originalValue);
         assertTrue("Toggle Touch vibration fail.", ret);
 
         mBackupUtils.restoreAndAssertSuccess(LOCAL_TRANSPORT_TOKEN, SETTINGS_PACKAGE_NAME);
@@ -163,4 +179,33 @@
                         mContentResolver, Settings.System.HAPTIC_FEEDBACK_ENABLED, -1);
         assertTrue("Touch vibration restore fail.", originalValue == restoreValue);
     }
+
+    private int prepareSystemSetting(String name) throws Exception {
+        int value = Settings.System.getInt(mContentResolver, name, SETTING_ABSENT_VALUE);
+        if (value == SETTING_ABSENT_VALUE) {
+            return SETTING_ABSENT_VALUE;
+        }
+
+        mOriginalSettingValues.put(name, value);
+        clearSystemSettingState(name);
+        setSystemSetting(name, value);
+
+        return value;
+    }
+
+    private boolean setSystemSetting(String name, int value) {
+        return Settings.System.putString(mContentResolver, name, String.valueOf(value),
+                /* overrideableByRestore */ true);
+    }
+
+    private void restoreOriginalSettingValues() throws Exception {
+        for (String settingName : mOriginalSettingValues.keySet()) {
+            clearSystemSettingState(settingName);
+            setSystemSetting(settingName, mOriginalSettingValues.get(settingName));
+        }
+    }
+
+    private void clearSystemSettingState(String setting) throws Exception {
+        mBackupUtils.executeShellCommandSync("settings delete system " + setting);
+    }
 }
\ No newline at end of file
diff --git a/hostsidetests/backup/PreservedSettingsApp/src/android/cts/backup/preservedsettingsapp/PreservedSettingsRestoreTest.java b/hostsidetests/backup/PreservedSettingsApp/src/android/cts/backup/preservedsettingsapp/PreservedSettingsRestoreTest.java
index 52bc651..0f1de51 100644
--- a/hostsidetests/backup/PreservedSettingsApp/src/android/cts/backup/preservedsettingsapp/PreservedSettingsRestoreTest.java
+++ b/hostsidetests/backup/PreservedSettingsApp/src/android/cts/backup/preservedsettingsapp/PreservedSettingsRestoreTest.java
@@ -20,6 +20,7 @@
 
 import static com.google.common.truth.Truth.assertThat;
 
+import android.app.UiAutomation;
 import android.content.ContentResolver;
 import android.content.Context;
 import android.content.SharedPreferences;
@@ -31,6 +32,7 @@
 
 import com.android.compatibility.common.util.SystemUtil;
 
+import org.junit.After;
 import org.junit.Before;
 import org.junit.Test;
 import org.junit.runner.RunWith;
@@ -60,6 +62,7 @@
     private ContentResolver mContentResolver;
     private File mSharedPreferencesFile;
     private SharedPreferences mSharedPreferences;
+    private UiAutomation mUiAutomation;
 
     @Before
     public void setUp() throws Exception {
@@ -69,6 +72,14 @@
         mSharedPreferencesFile.createNewFile();
         mSharedPreferences = mContext.getSharedPreferences(mSharedPreferencesFile,
                 Context.MODE_PRIVATE);
+        mUiAutomation = getInstrumentation().getUiAutomation();
+
+        mUiAutomation.adoptShellPermissionIdentity();
+    }
+
+    @After
+    public void tearDown() {
+        mUiAutomation.dropShellPermissionIdentity();
     }
 
     @Test
@@ -83,10 +94,8 @@
 
     @Test
     public void modifySettings() {
-        SystemUtil.runWithShellPermissionIdentity(() -> {
-                Settings.Secure.putString(mContentResolver, OVERRIDEABLE_SETTING,
-                        OVERRIDEABLE_SETTING_NEW_VALUE, /* overrideableByRestore */ true);
-        });
+        Settings.Secure.putString(mContentResolver, OVERRIDEABLE_SETTING,
+                OVERRIDEABLE_SETTING_NEW_VALUE, /* overrideableByRestore */ true);
         Settings.Secure.putString(mContentResolver, NON_OVERRIDEABLE_SETTING,
                 NON_OVERRIDEABLE_SETTING_NEW_VALUE);
     }
@@ -113,14 +122,17 @@
 
     @Test
     public void cleanupDevice() throws Exception {
-        SystemUtil.runWithShellPermissionIdentity(() -> {
-            Settings.Secure.putString(mContentResolver, OVERRIDEABLE_SETTING,
-                    getOriginalSettingValue(OVERRIDEABLE_SETTING),
-                    /* overrideableByRestore */ true);
-            Settings.Secure.putString(mContentResolver, NON_OVERRIDEABLE_SETTING,
-                    getOriginalSettingValue(NON_OVERRIDEABLE_SETTING),
-                    /* overrideableByRestore */ true);
-        });
+        // "Touch" the affected settings so that we're the last package that modified them.
+        modifySettings();
+        // Reset all secure settings modified by this package.
+        Settings.Secure.resetToDefaults(mContentResolver, null);
+
+        Settings.Secure.putString(mContentResolver, OVERRIDEABLE_SETTING,
+                getOriginalSettingValue(OVERRIDEABLE_SETTING),
+                /* overrideableByRestore */ true);
+        Settings.Secure.putString(mContentResolver, NON_OVERRIDEABLE_SETTING,
+                getOriginalSettingValue(NON_OVERRIDEABLE_SETTING),
+                /* overrideableByRestore */ true);
 
         Settings.Global.putString(mContentResolver,
                 FeatureFlagUtils.SETTINGS_DO_NOT_RESTORE_PRESERVED,
diff --git a/hostsidetests/blobstore/Android.bp b/hostsidetests/blobstore/Android.bp
index aab448e..2baec7f 100644
--- a/hostsidetests/blobstore/Android.bp
+++ b/hostsidetests/blobstore/Android.bp
@@ -42,7 +42,7 @@
       "testng",
   ],
   manifest : "test-apps/BlobStoreHostTestHelper/AndroidManifest.xml",
-  platform_apis: true,
+  sdk_version: "test_current",
   // Tag this module as a cts test artifact
   test_suites: [
     "cts",
diff --git a/hostsidetests/blobstore/src/com/android/cts/host/blob/InstantAppAccessTest.java b/hostsidetests/blobstore/src/com/android/cts/host/blob/InstantAppAccessTest.java
new file mode 100644
index 0000000..0c2c13a
--- /dev/null
+++ b/hostsidetests/blobstore/src/com/android/cts/host/blob/InstantAppAccessTest.java
@@ -0,0 +1,45 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.cts.host.blob;
+
+import com.android.tradefed.testtype.DeviceJUnit4ClassRunner;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+@RunWith(DeviceJUnit4ClassRunner.class)
+public class InstantAppAccessTest extends BaseBlobStoreHostTest {
+    private static final String TEST_CLASS = TARGET_PKG + ".InstantAppAccessTest";
+
+    @Before
+    public void setUp() throws Exception {
+        uninstallPackage(TARGET_PKG);
+        installPackage(TARGET_APK, "--instant");
+    }
+
+    @After
+    public void tearDown() throws Exception {
+        uninstallPackage(TARGET_PKG);
+    }
+
+    @Test
+    public void testInstantAppAccess() throws Exception {
+        runDeviceTest(TARGET_PKG, TEST_CLASS, "testInstantAppAccess");
+    }
+}
diff --git a/hostsidetests/blobstore/test-apps/BlobStoreHostTestHelper/src/com/android/cts/device/blob/DataCleanupTest.java b/hostsidetests/blobstore/test-apps/BlobStoreHostTestHelper/src/com/android/cts/device/blob/DataCleanupTest.java
index 5bb82b9..72b907e 100644
--- a/hostsidetests/blobstore/test-apps/BlobStoreHostTestHelper/src/com/android/cts/device/blob/DataCleanupTest.java
+++ b/hostsidetests/blobstore/test-apps/BlobStoreHostTestHelper/src/com/android/cts/device/blob/DataCleanupTest.java
@@ -34,7 +34,6 @@
 import org.junit.runner.RunWith;
 
 import java.util.Base64;
-import java.util.Random;
 import java.util.concurrent.CompletableFuture;
 import java.util.concurrent.TimeUnit;
 
@@ -59,7 +58,6 @@
     private Context mContext;
     private Instrumentation mInstrumentation;
     private BlobStoreManager mBlobStoreManager;
-    private Random mRandom;
 
     @Before
     public void setUp() {
@@ -67,12 +65,14 @@
         mContext = mInstrumentation.getContext();
         mBlobStoreManager = (BlobStoreManager) mContext.getSystemService(
                 Context.BLOB_STORE_SERVICE);
-        mRandom = new Random(24 /* seed */);
     }
 
     @Test
     public void testCreateSession() throws Exception {
-        final DummyBlobData blobData = new DummyBlobData(mContext, mRandom, "test_data_blob");
+        final DummyBlobData blobData = new DummyBlobData.Builder(mContext)
+                .setRandomSeed(24)
+                .setFileName("test_blob_data")
+                .build();
         blobData.prepare();
 
         final long sessionId = createSession(blobData.getBlobHandle());
@@ -106,8 +106,11 @@
 
     @Test
     public void testCommitBlob() throws Exception {
-        final DummyBlobData blobData = new DummyBlobData(mContext, mRandom,
-                "test_data_blob", "test_data_blob");
+        final DummyBlobData blobData = new DummyBlobData.Builder(mContext)
+                .setRandomSeed(24)
+                .setFileName("test_blob_data")
+                .setLabel("test_data_blob_label")
+                .build();
         blobData.prepare();
 
         final long sessionId = createSession(blobData.getBlobHandle());
diff --git a/hostsidetests/blobstore/test-apps/BlobStoreHostTestHelper/src/com/android/cts/device/blob/DataPersistenceTest.java b/hostsidetests/blobstore/test-apps/BlobStoreHostTestHelper/src/com/android/cts/device/blob/DataPersistenceTest.java
index b4226a6..72c6847 100644
--- a/hostsidetests/blobstore/test-apps/BlobStoreHostTestHelper/src/com/android/cts/device/blob/DataPersistenceTest.java
+++ b/hostsidetests/blobstore/test-apps/BlobStoreHostTestHelper/src/com/android/cts/device/blob/DataPersistenceTest.java
@@ -31,7 +31,6 @@
 import org.junit.runner.RunWith;
 
 import java.util.Base64;
-import java.util.Random;
 import java.util.concurrent.CompletableFuture;
 import java.util.concurrent.TimeUnit;
 
@@ -53,19 +52,20 @@
 
     private Context mContext;
     private BlobStoreManager mBlobStoreManager;
-    private Random mRandom;
 
     @Before
     public void setUp() {
         mContext = InstrumentationRegistry.getInstrumentation().getContext();
         mBlobStoreManager = (BlobStoreManager) mContext.getSystemService(
                 Context.BLOB_STORE_SERVICE);
-        mRandom = new Random(22 /* seed */);
     }
 
     @Test
     public void testCreateSession() throws Exception {
-        final DummyBlobData blobData = new DummyBlobData(mContext, mRandom, "test_data_blob");
+        final DummyBlobData blobData = new DummyBlobData.Builder(mContext)
+                .setRandomSeed(22)
+                .setFileName("test_blob_data")
+                .build();
         blobData.prepare();
 
         final long sessionId = createSession(blobData.getBlobHandle());
@@ -84,7 +84,10 @@
     @Test
     public void testOpenSessionAndWrite() throws Exception {
         final long sessionId = readSessionIdFromDisk();
-        final DummyBlobData blobData = new DummyBlobData(mContext, mRandom, "test_data_blob");
+        final DummyBlobData blobData = new DummyBlobData.Builder(mContext)
+                .setRandomSeed(22)
+                .setFileName("test_blob_data")
+                .build();
         try (BlobStoreManager.Session session = mBlobStoreManager.openSession(sessionId)) {
             assertThat(session.getSize()).isEqualTo(PARTIAL_FILE_LENGTH_BYTES);
             blobData.writeToSession(session, PARTIAL_FILE_LENGTH_BYTES,
diff --git a/hostsidetests/blobstore/test-apps/BlobStoreHostTestHelper/src/com/android/cts/device/blob/InstantAppAccessTest.java b/hostsidetests/blobstore/test-apps/BlobStoreHostTestHelper/src/com/android/cts/device/blob/InstantAppAccessTest.java
new file mode 100644
index 0000000..4d7fd48
--- /dev/null
+++ b/hostsidetests/blobstore/test-apps/BlobStoreHostTestHelper/src/com/android/cts/device/blob/InstantAppAccessTest.java
@@ -0,0 +1,37 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.cts.device.blob;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import android.content.Context;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import androidx.test.ext.junit.runners.AndroidJUnit4;
+import androidx.test.platform.app.InstrumentationRegistry;
+
+@RunWith(AndroidJUnit4.class)
+public class InstantAppAccessTest {
+    @Test
+    public void testInstantAppAccess() {
+        final Context context = InstrumentationRegistry.getInstrumentation().getContext();
+        assertThat(context.getPackageManager().isInstantApp()).isTrue();
+        assertThat(context.getSystemService(Context.BLOB_STORE_SERVICE)).isNull();
+    }
+}
diff --git a/hostsidetests/devicepolicy/app/CorpOwnedManagedProfile/AndroidManifest.xml b/hostsidetests/devicepolicy/app/CorpOwnedManagedProfile/AndroidManifest.xml
index f23a692..b24e8c8 100644
--- a/hostsidetests/devicepolicy/app/CorpOwnedManagedProfile/AndroidManifest.xml
+++ b/hostsidetests/devicepolicy/app/CorpOwnedManagedProfile/AndroidManifest.xml
@@ -45,6 +45,12 @@
         <service android:name=".UnprotectedCrossUserService"
                 android:exported="true">
         </service>
+
+        <receiver android:name=".WipeDataReceiver">
+            <intent-filter>
+                <action android:name="com.android.cts.comp.WIPE_DATA" />
+            </intent-filter>
+        </receiver>
     </application>
 
     <instrumentation android:name="androidx.test.runner.AndroidJUnitRunner"
diff --git a/hostsidetests/devicepolicy/app/CorpOwnedManagedProfile/src/com/android/cts/comp/ManagementTest.java b/hostsidetests/devicepolicy/app/CorpOwnedManagedProfile/src/com/android/cts/comp/ManagementTest.java
index f7636d4..e72a6a1 100644
--- a/hostsidetests/devicepolicy/app/CorpOwnedManagedProfile/src/com/android/cts/comp/ManagementTest.java
+++ b/hostsidetests/devicepolicy/app/CorpOwnedManagedProfile/src/com/android/cts/comp/ManagementTest.java
@@ -72,10 +72,6 @@
                 DevicePolicyManager.ACTION_PROVISION_MANAGED_PROFILE));
     }
 
-    public void testWipeData() {
-        mDevicePolicyManager.wipeData(0);
-    }
-
     public void testCreateSecondaryUser() throws Exception {
         ComponentName admin = AdminReceiver.getComponentName(mContext);
         assertNotNull(mDevicePolicyManager.createAndManageUser(admin, "secondary-user",
diff --git a/hostsidetests/devicepolicy/app/CorpOwnedManagedProfile/src/com/android/cts/comp/WipeDataReceiver.java b/hostsidetests/devicepolicy/app/CorpOwnedManagedProfile/src/com/android/cts/comp/WipeDataReceiver.java
new file mode 100644
index 0000000..741091f
--- /dev/null
+++ b/hostsidetests/devicepolicy/app/CorpOwnedManagedProfile/src/com/android/cts/comp/WipeDataReceiver.java
@@ -0,0 +1,47 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.cts.comp;
+
+import android.app.admin.DevicePolicyManager;
+import android.content.BroadcastReceiver;
+import android.content.Context;
+import android.content.Intent;
+import android.util.Log;
+
+/**
+ * Invoke wipeData(). 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 TAG = "WipeDataReceiver";
+    private static final String ACTION_WIPE_DATA =
+            "com.android.cts.comp.WIPE_DATA";
+
+    @Override
+    public void onReceive(Context context, Intent intent) {
+        final DevicePolicyManager devicePolicyManager = context.getSystemService(
+                DevicePolicyManager.class);
+
+        Log.i(TAG, "WipeDataReceiver received " + intent.getAction());
+        if (ACTION_WIPE_DATA.equals(intent.getAction())) {
+            devicePolicyManager.wipeData(0);
+        }
+    }
+}
\ No newline at end of file
diff --git a/hostsidetests/devicepolicy/app/CrossProfileTestApps/CrossProfileAppsTest/src/com/android/cts/crossprofileappstest/CrossProfileAppsStartActivityTest.java b/hostsidetests/devicepolicy/app/CrossProfileTestApps/CrossProfileAppsTest/src/com/android/cts/crossprofileappstest/CrossProfileAppsStartActivityTest.java
index be5c4b1..57eb0f8 100644
--- a/hostsidetests/devicepolicy/app/CrossProfileTestApps/CrossProfileAppsTest/src/com/android/cts/crossprofileappstest/CrossProfileAppsStartActivityTest.java
+++ b/hostsidetests/devicepolicy/app/CrossProfileTestApps/CrossProfileAppsTest/src/com/android/cts/crossprofileappstest/CrossProfileAppsStartActivityTest.java
@@ -25,6 +25,7 @@
 import static org.junit.Assert.fail;
 
 import android.app.Activity;
+import android.app.ActivityOptions;
 import android.content.ComponentName;
 import android.content.Context;
 import android.content.Intent;
@@ -202,6 +203,32 @@
     }
 
     @Test
+    public void testCanStartMainActivityByIntent_withOptionsBundle() throws Exception {
+        Intent mainActivityIntent = new Intent();
+        mainActivityIntent.setComponent(MainActivity.getComponentName(mContext));
+
+        try {
+            ShellIdentityUtils.invokeMethodWithShellPermissionsNoReturn(
+                    mCrossProfileApps,
+                    crossProfileApps ->
+                            mCrossProfileApps.startActivity(
+                                    mainActivityIntent,
+                                    mTargetUser,
+                                    /* callingActivity= */ null,
+                                    ActivityOptions.makeBasic().toBundle()));
+
+            // Look for the text view to verify that MainActivity is started.
+            UiObject2 textView = mDevice.wait(Until.findObject(By.res(ID_USER_TEXTVIEW)),
+                    TIMEOUT_WAIT_UI);
+            assertNotNull("Failed to start main activity in target user", textView);
+            assertEquals("Main Activity is started in wrong user",
+                    String.valueOf(mUserSerialNumber), textView.getText());
+        } catch (Exception e) {
+            fail("unable to start main activity via CrossProfileApps#startActivity: " + e);
+        }
+    }
+
+    @Test
     public void testCanStartNonMainActivityByIntent() {
         Intent nonMainActivityIntent = new Intent();
         nonMainActivityIntent.setComponent(NonMainActivity.getComponentName(mContext));
@@ -250,8 +277,8 @@
     }
 
     /**
-     * Calls {@link CrossProfileApps#startActivity(Intent, UserHandle, Activity)}. This can then be used by
-     * host-side tests.
+     * Calls {@link CrossProfileApps#startActivity(Intent, UserHandle, Activity)}. This can then be
+     * used by host-side tests.
      */
     @Test
     public void testStartActivityByIntent_noAsserts() throws Exception {
diff --git a/hostsidetests/devicepolicy/app/DeviceAndProfileOwner/src/com/android/cts/deviceandprofileowner/DelegatedCertInstallerHelper.java b/hostsidetests/devicepolicy/app/DeviceAndProfileOwner/src/com/android/cts/deviceandprofileowner/DelegatedCertInstallerHelper.java
index d0af5f4..8e8a6d6 100644
--- a/hostsidetests/devicepolicy/app/DeviceAndProfileOwner/src/com/android/cts/deviceandprofileowner/DelegatedCertInstallerHelper.java
+++ b/hostsidetests/devicepolicy/app/DeviceAndProfileOwner/src/com/android/cts/deviceandprofileowner/DelegatedCertInstallerHelper.java
@@ -76,8 +76,4 @@
     public void testManualClearGeneratedKey() {
         assertTrue(mDpm.removeKeyPair(ADMIN_RECEIVER_COMPONENT, PRE_SELECTED_ALIAS));
     }
-
-    public void testManualWipeProfile() {
-        mDpm.wipeData(0);
-    }
 }
diff --git a/hostsidetests/devicepolicy/app/DeviceAndProfileOwner/src/com/android/cts/deviceandprofileowner/DeviceIdentifiersTest.java b/hostsidetests/devicepolicy/app/DeviceAndProfileOwner/src/com/android/cts/deviceandprofileowner/DeviceIdentifiersTest.java
index 855958c..c44b406 100644
--- a/hostsidetests/devicepolicy/app/DeviceAndProfileOwner/src/com/android/cts/deviceandprofileowner/DeviceIdentifiersTest.java
+++ b/hostsidetests/devicepolicy/app/DeviceAndProfileOwner/src/com/android/cts/deviceandprofileowner/DeviceIdentifiersTest.java
@@ -15,8 +15,6 @@
  */
 package com.android.cts.deviceandprofileowner;
 
-import static org.testng.Assert.assertThrows;
-
 import android.content.Context;
 import android.content.pm.PackageManager;
 import android.os.Build;
@@ -50,24 +48,24 @@
         try {
             assertEquals(String.format(DEVICE_ID_WITH_PERMISSION_ERROR_MESSAGE, "getDeviceId"),
                     ShellIdentityUtils.invokeMethodWithShellPermissions(telephonyManager,
-                            (tm) -> tm.getDeviceId()), telephonyManager.getDeviceId());
+                            TelephonyManager::getDeviceId), telephonyManager.getDeviceId());
             assertEquals(String.format(DEVICE_ID_WITH_PERMISSION_ERROR_MESSAGE, "getImei"),
                     ShellIdentityUtils.invokeMethodWithShellPermissions(telephonyManager,
-                            (tm) -> tm.getImei()), telephonyManager.getImei());
+                            TelephonyManager::getImei), telephonyManager.getImei());
             assertEquals(String.format(DEVICE_ID_WITH_PERMISSION_ERROR_MESSAGE, "getMeid"),
                     ShellIdentityUtils.invokeMethodWithShellPermissions(telephonyManager,
-                            (tm) -> tm.getMeid()), telephonyManager.getMeid());
+                            TelephonyManager::getMeid), telephonyManager.getMeid());
             assertEquals(String.format(DEVICE_ID_WITH_PERMISSION_ERROR_MESSAGE, "getSubscriberId"),
                     ShellIdentityUtils.invokeMethodWithShellPermissions(telephonyManager,
-                            (tm) -> tm.getSubscriberId()), telephonyManager.getSubscriberId());
+                            TelephonyManager::getSubscriberId), telephonyManager.getSubscriberId());
             assertEquals(
                     String.format(DEVICE_ID_WITH_PERMISSION_ERROR_MESSAGE, "getSimSerialNumber"),
                     ShellIdentityUtils.invokeMethodWithShellPermissions(telephonyManager,
-                            (tm) -> tm.getSimSerialNumber()),
+                            TelephonyManager::getSimSerialNumber),
                     telephonyManager.getSimSerialNumber());
             assertEquals(String.format(DEVICE_ID_WITH_PERMISSION_ERROR_MESSAGE, "getNai"),
                     ShellIdentityUtils.invokeMethodWithShellPermissions(telephonyManager,
-                            (tm) -> tm.getNai()), telephonyManager.getNai());
+                            TelephonyManager::getNai), telephonyManager.getNai());
             assertEquals(String.format(DEVICE_ID_WITH_PERMISSION_ERROR_MESSAGE, "Build#getSerial"),
                     ShellIdentityUtils.invokeStaticMethodWithShellPermissions(Build::getSerial),
                     Build.getSerial());
@@ -90,7 +88,7 @@
         }
     }
 
-    public void testProfileOwnerCannotGetDeviceIdentifiersWithoutPermission() throws Exception {
+    public void testProfileOwnerCannotGetDeviceIdentifiersWithoutPermission() {
         // The profile owner without the READ_PHONE_STATE permission should still receive a
         // SecurityException when querying for device identifiers.
         TelephonyManager telephonyManager = (TelephonyManager) mContext.getSystemService(
@@ -98,22 +96,35 @@
         // Allow the APIs to also return null if the telephony feature is not supported.
         boolean hasTelephonyFeature =
                 mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_TELEPHONY);
-        if (hasTelephonyFeature) {
-            assertThrows(SecurityException.class, telephonyManager::getDeviceId);
-            assertThrows(SecurityException.class, telephonyManager::getImei);
-            assertThrows(SecurityException.class, telephonyManager::getMeid);
-            assertThrows(SecurityException.class, telephonyManager::getSubscriberId);
-            assertThrows(SecurityException.class, telephonyManager::getSimSerialNumber);
-            assertThrows(SecurityException.class, telephonyManager::getNai);
-            assertThrows(SecurityException.class, Build::getSerial);
-        } else {
-            assertNull(telephonyManager.getDeviceId());
-            assertNull(telephonyManager.getImei());
-            assertNull(telephonyManager.getMeid());
-            assertNull(telephonyManager.getSubscriberId());
-            assertNull(telephonyManager.getSimSerialNumber());
-            assertNull(telephonyManager.getNai());
-            assertNull(Build.getSerial());
+
+        boolean mayReturnNull = !hasTelephonyFeature;
+
+        assertAccessDenied(telephonyManager::getDeviceId, mayReturnNull);
+        assertAccessDenied(telephonyManager::getImei, mayReturnNull);
+        assertAccessDenied(telephonyManager::getMeid, mayReturnNull);
+        assertAccessDenied(telephonyManager::getSubscriberId, mayReturnNull);
+        assertAccessDenied(telephonyManager::getSimSerialNumber, mayReturnNull);
+        assertAccessDenied(telephonyManager::getNai, mayReturnNull);
+        assertAccessDenied(Build::getSerial, mayReturnNull);
+    }
+
+    private static <T> void assertAccessDenied(ThrowingProvider<T> provider,
+            boolean mayReturnNull) {
+        try {
+            T object = provider.get();
+            if (mayReturnNull) {
+                assertNull(object);
+            } else {
+                fail("Expected SecurityException, received " + object);
+            }
+        } catch (SecurityException ignored) {
+            // assertion succeeded
+        } catch (Throwable th) {
+            fail("Expected SecurityException but was: " + th);
         }
     }
+
+    private interface ThrowingProvider<T> {
+        T get() throws Throwable;
+    }
 }
diff --git a/hostsidetests/devicepolicy/app/DeviceAndProfileOwner/src/com/android/cts/deviceandprofileowner/DevicePolicyLoggingTest.java b/hostsidetests/devicepolicy/app/DeviceAndProfileOwner/src/com/android/cts/deviceandprofileowner/DevicePolicyLoggingTest.java
index 036f4a2..61fdb18 100644
--- a/hostsidetests/devicepolicy/app/DeviceAndProfileOwner/src/com/android/cts/deviceandprofileowner/DevicePolicyLoggingTest.java
+++ b/hostsidetests/devicepolicy/app/DeviceAndProfileOwner/src/com/android/cts/deviceandprofileowner/DevicePolicyLoggingTest.java
@@ -154,11 +154,12 @@
         mDevicePolicyManager.setAutoTimeRequired(ADMIN_RECEIVER_COMPONENT, initialValue);
     }
 
-    public void testSetAutoTime() {
-        final boolean initialValue = mDevicePolicyManager.getAutoTime(ADMIN_RECEIVER_COMPONENT);
-        mDevicePolicyManager.setAutoTime(ADMIN_RECEIVER_COMPONENT, true);
-        mDevicePolicyManager.setAutoTime(ADMIN_RECEIVER_COMPONENT, false);
-        mDevicePolicyManager.setAutoTime(ADMIN_RECEIVER_COMPONENT, initialValue);
+    public void testSetAutoTimeEnabled() {
+        final boolean initialValue = mDevicePolicyManager.getAutoTimeEnabled(
+                ADMIN_RECEIVER_COMPONENT);
+        mDevicePolicyManager.setAutoTimeEnabled(ADMIN_RECEIVER_COMPONENT, true);
+        mDevicePolicyManager.setAutoTimeEnabled(ADMIN_RECEIVER_COMPONENT, false);
+        mDevicePolicyManager.setAutoTimeEnabled(ADMIN_RECEIVER_COMPONENT, initialValue);
     }
 
     public void testEnableSystemAppLogged() {
diff --git a/hostsidetests/devicepolicy/app/DeviceAndProfileOwner/src/com/android/cts/deviceandprofileowner/TimeManagementTest.java b/hostsidetests/devicepolicy/app/DeviceAndProfileOwner/src/com/android/cts/deviceandprofileowner/TimeManagementTest.java
index 24428d8..1f33446 100644
--- a/hostsidetests/devicepolicy/app/DeviceAndProfileOwner/src/com/android/cts/deviceandprofileowner/TimeManagementTest.java
+++ b/hostsidetests/devicepolicy/app/DeviceAndProfileOwner/src/com/android/cts/deviceandprofileowner/TimeManagementTest.java
@@ -39,18 +39,18 @@
         super.tearDown();
     }
 
-    public void testSetAutoTimeZone() {
-        mDevicePolicyManager.setAutoTimeZone(ADMIN_RECEIVER_COMPONENT, true);
+    public void testSetAutoTimeZoneEnabled() {
+        mDevicePolicyManager.setAutoTimeZoneEnabled(ADMIN_RECEIVER_COMPONENT, true);
 
-        assertThat(mDevicePolicyManager.getAutoTimeZone(ADMIN_RECEIVER_COMPONENT)).isTrue();
+        assertThat(mDevicePolicyManager.getAutoTimeZoneEnabled(ADMIN_RECEIVER_COMPONENT)).isTrue();
 
-        mDevicePolicyManager.setAutoTimeZone(ADMIN_RECEIVER_COMPONENT, false);
+        mDevicePolicyManager.setAutoTimeZoneEnabled(ADMIN_RECEIVER_COMPONENT, false);
 
-        assertThat(mDevicePolicyManager.getAutoTimeZone(ADMIN_RECEIVER_COMPONENT)).isFalse();
+        assertThat(mDevicePolicyManager.getAutoTimeZoneEnabled(ADMIN_RECEIVER_COMPONENT)).isFalse();
     }
 
     public void testSetTime() {
-        mDevicePolicyManager.setAutoTime(ADMIN_RECEIVER_COMPONENT, false);
+        mDevicePolicyManager.setAutoTimeEnabled(ADMIN_RECEIVER_COMPONENT, false);
 
         final long estimatedNow = mStartTimeWallClockMillis +
                 TimeUnit.NANOSECONDS.toMillis(System.nanoTime() - mStartTimeElapsedNanos);
@@ -59,20 +59,20 @@
     }
 
     public void testSetTime_failWhenAutoTimeEnabled() {
-        mDevicePolicyManager.setAutoTime(ADMIN_RECEIVER_COMPONENT, true);
+        mDevicePolicyManager.setAutoTimeEnabled(ADMIN_RECEIVER_COMPONENT, true);
 
         assertThat(mDevicePolicyManager.setTime(ADMIN_RECEIVER_COMPONENT, 0)).isFalse();
     }
 
     public void testSetTimeZone() {
-        mDevicePolicyManager.setAutoTimeZone(ADMIN_RECEIVER_COMPONENT, false);
+        mDevicePolicyManager.setAutoTimeZoneEnabled(ADMIN_RECEIVER_COMPONENT, false);
 
         assertThat(
                 mDevicePolicyManager.setTimeZone(ADMIN_RECEIVER_COMPONENT, "Singapore")).isTrue();
     }
 
     public void testSetTimeZone_failIfAutoTimeZoneEnabled() {
-        mDevicePolicyManager.setAutoTimeZone(ADMIN_RECEIVER_COMPONENT, true);
+        mDevicePolicyManager.setAutoTimeZoneEnabled(ADMIN_RECEIVER_COMPONENT, true);
 
         assertThat(
                 mDevicePolicyManager.setTimeZone(ADMIN_RECEIVER_COMPONENT, "Singapore")).isFalse();
@@ -84,12 +84,12 @@
     }
 
     private void restoreTime() {
-        mDevicePolicyManager.setAutoTime(ADMIN_RECEIVER_COMPONENT, false);
+        mDevicePolicyManager.setAutoTimeEnabled(ADMIN_RECEIVER_COMPONENT, false);
 
         final long estimatedNow = mStartTimeWallClockMillis +
                 TimeUnit.NANOSECONDS.toMillis(System.nanoTime() - mStartTimeElapsedNanos);
         mDevicePolicyManager.setTime(ADMIN_RECEIVER_COMPONENT, estimatedNow);
 
-        mDevicePolicyManager.setAutoTime(ADMIN_RECEIVER_COMPONENT, true);
+        mDevicePolicyManager.setAutoTimeEnabled(ADMIN_RECEIVER_COMPONENT, true);
     }
 }
diff --git a/hostsidetests/devicepolicy/app/DeviceOwner/Android.bp b/hostsidetests/devicepolicy/app/DeviceOwner/Android.bp
index 34040d9..70d59d6 100644
--- a/hostsidetests/devicepolicy/app/DeviceOwner/Android.bp
+++ b/hostsidetests/devicepolicy/app/DeviceOwner/Android.bp
@@ -35,7 +35,6 @@
         "compatibility-device-util-axt",
         "androidx.test.rules",
         "cts-security-test-support-library",
-        "testng",
         "truth-prebuilt",
         "androidx.legacy_legacy-support-v4",
     ],
diff --git a/hostsidetests/devicepolicy/app/DeviceOwner/src/com/android/cts/deviceowner/DeviceIdentifiersTest.java b/hostsidetests/devicepolicy/app/DeviceOwner/src/com/android/cts/deviceowner/DeviceIdentifiersTest.java
index 2370cd0..296cf6e 100644
--- a/hostsidetests/devicepolicy/app/DeviceOwner/src/com/android/cts/deviceowner/DeviceIdentifiersTest.java
+++ b/hostsidetests/devicepolicy/app/DeviceOwner/src/com/android/cts/deviceowner/DeviceIdentifiersTest.java
@@ -15,8 +15,6 @@
  */
 package com.android.cts.deviceowner;
 
-import static org.testng.Assert.assertThrows;
-
 import android.content.Context;
 import android.content.pm.PackageManager;
 import android.os.Build;
@@ -35,7 +33,7 @@
             "An unexpected value was received by the device owner with the READ_PHONE_STATE "
                     + "permission when invoking %s";
 
-    public void testDeviceOwnerCanGetDeviceIdentifiersWithPermission() throws Exception {
+    public void testDeviceOwnerCanGetDeviceIdentifiersWithPermission() {
         // The device owner with the READ_PHONE_STATE permission should have access to all device
         // identifiers. However since the TelephonyManager methods can return null this method
         // verifies that the device owner with the READ_PHONE_STATE permission receives the same
@@ -45,25 +43,25 @@
         try {
             assertEquals(String.format(DEVICE_ID_WITH_PERMISSION_ERROR_MESSAGE, "getDeviceId"),
                     ShellIdentityUtils.invokeMethodWithShellPermissions(telephonyManager,
-                            (tm) -> tm.getDeviceId()), telephonyManager.getDeviceId());
+                            TelephonyManager::getDeviceId), telephonyManager.getDeviceId());
             assertEquals(String.format(DEVICE_ID_WITH_PERMISSION_ERROR_MESSAGE, "getImei"),
                     ShellIdentityUtils.invokeMethodWithShellPermissions(telephonyManager,
-                            (tm) -> tm.getImei()), telephonyManager.getImei());
+                            TelephonyManager::getImei), telephonyManager.getImei());
             assertEquals(String.format(DEVICE_ID_WITH_PERMISSION_ERROR_MESSAGE, "getMeid"),
                     ShellIdentityUtils.invokeMethodWithShellPermissions(telephonyManager,
-                            (tm) -> tm.getMeid()), telephonyManager.getMeid());
+                            TelephonyManager::getMeid), telephonyManager.getMeid());
             assertEquals(String.format(DEVICE_ID_WITH_PERMISSION_ERROR_MESSAGE, "getSubscriberId"),
                     ShellIdentityUtils.invokeMethodWithShellPermissions(telephonyManager,
-                            (tm) -> tm.getSubscriberId()), telephonyManager.getSubscriberId());
+                            TelephonyManager::getSubscriberId), telephonyManager.getSubscriberId());
             assertEquals(
                     String.format(DEVICE_ID_WITH_PERMISSION_ERROR_MESSAGE, "getSimSerialNumber"),
                     ShellIdentityUtils.invokeMethodWithShellPermissions(telephonyManager,
-                            (tm) -> tm.getSimSerialNumber()),
+                            TelephonyManager::getSimSerialNumber),
                     telephonyManager.getSimSerialNumber());
             assertEquals(
                     String.format(DEVICE_ID_WITH_PERMISSION_ERROR_MESSAGE, "getNai"),
                     ShellIdentityUtils.invokeMethodWithShellPermissions(telephonyManager,
-                            (tm) -> tm.getNai()), telephonyManager.getNai());
+                            TelephonyManager::getNai), telephonyManager.getNai());
             assertEquals(String.format(DEVICE_ID_WITH_PERMISSION_ERROR_MESSAGE, "Build#getSerial"),
                     ShellIdentityUtils.invokeStaticMethodWithShellPermissions(Build::getSerial),
                     Build.getSerial());
@@ -86,7 +84,7 @@
         }
     }
 
-    public void testDeviceOwnerCannotGetDeviceIdentifiersWithoutPermission() throws Exception {
+    public void testDeviceOwnerCannotGetDeviceIdentifiersWithoutPermission() {
         // The device owner without the READ_PHONE_STATE permission should still receive a
         // SecurityException when querying for device identifiers.
         TelephonyManager telephonyManager = (TelephonyManager) mContext.getSystemService(
@@ -94,22 +92,35 @@
         // Allow the APIs to also return null if the telephony feature is not supported.
         boolean hasTelephonyFeature =
                 mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_TELEPHONY);
-        if (hasTelephonyFeature) {
-            assertThrows(SecurityException.class, telephonyManager::getDeviceId);
-            assertThrows(SecurityException.class, telephonyManager::getImei);
-            assertThrows(SecurityException.class, telephonyManager::getMeid);
-            assertThrows(SecurityException.class, telephonyManager::getSubscriberId);
-            assertThrows(SecurityException.class, telephonyManager::getSimSerialNumber);
-            assertThrows(SecurityException.class, telephonyManager::getNai);
-            assertThrows(SecurityException.class, Build::getSerial);
-        } else {
-            assertNull(telephonyManager.getDeviceId());
-            assertNull(telephonyManager.getImei());
-            assertNull(telephonyManager.getMeid());
-            assertNull(telephonyManager.getSubscriberId());
-            assertNull(telephonyManager.getSimSerialNumber());
-            assertNull(telephonyManager.getNai());
-            assertNull(Build.getSerial());
+
+        boolean mayReturnNull = !hasTelephonyFeature;
+
+        assertAccessDenied(telephonyManager::getDeviceId, mayReturnNull);
+        assertAccessDenied(telephonyManager::getImei, mayReturnNull);
+        assertAccessDenied(telephonyManager::getMeid, mayReturnNull);
+        assertAccessDenied(telephonyManager::getSubscriberId, mayReturnNull);
+        assertAccessDenied(telephonyManager::getSimSerialNumber, mayReturnNull);
+        assertAccessDenied(telephonyManager::getNai, mayReturnNull);
+        assertAccessDenied(Build::getSerial, mayReturnNull);
+    }
+
+    private static <T> void assertAccessDenied(ThrowingProvider<T> provider,
+            boolean mayReturnNull) {
+        try {
+            T object = provider.get();
+            if (mayReturnNull) {
+                assertNull(object);
+            } else {
+                fail("Expected SecurityException, received " + object);
+            }
+        } catch (SecurityException ignored) {
+            // assertion succeeded
+        } catch (Throwable th) {
+            fail("Expected SecurityException but was: " + th);
         }
     }
+
+    private interface ThrowingProvider<T> {
+        T get() throws Throwable;
+    }
 }
diff --git a/hostsidetests/devicepolicy/app/DeviceOwner/src/com/android/cts/deviceowner/SetTimeTest.java b/hostsidetests/devicepolicy/app/DeviceOwner/src/com/android/cts/deviceowner/SetTimeTest.java
index acf142f..d296229 100644
--- a/hostsidetests/devicepolicy/app/DeviceOwner/src/com/android/cts/deviceowner/SetTimeTest.java
+++ b/hostsidetests/devicepolicy/app/DeviceOwner/src/com/android/cts/deviceowner/SetTimeTest.java
@@ -92,7 +92,7 @@
         final BroadcastReceiver receiver = new BroadcastReceiver() {
             @Override
             public void onReceive(Context context, Intent intent) {
-                if (testTimeZone.equals(intent.getStringExtra("time-zone"))) {
+                if (testTimeZone.equals(intent.getStringExtra(Intent.EXTRA_TIMEZONE))) {
                     latch.countDown();
                 }
             }
diff --git a/hostsidetests/devicepolicy/app/DeviceOwner/src/com/android/cts/deviceowner/ProtectedPackagesTest.java b/hostsidetests/devicepolicy/app/DeviceOwner/src/com/android/cts/deviceowner/UserControlDisabledPackagesTest.java
similarity index 71%
rename from hostsidetests/devicepolicy/app/DeviceOwner/src/com/android/cts/deviceowner/ProtectedPackagesTest.java
rename to hostsidetests/devicepolicy/app/DeviceOwner/src/com/android/cts/deviceowner/UserControlDisabledPackagesTest.java
index 4489bdb..91ca612 100644
--- a/hostsidetests/devicepolicy/app/DeviceOwner/src/com/android/cts/deviceowner/ProtectedPackagesTest.java
+++ b/hostsidetests/devicepolicy/app/DeviceOwner/src/com/android/cts/deviceowner/UserControlDisabledPackagesTest.java
@@ -21,13 +21,14 @@
 import android.content.pm.PackageInfo;
 import android.content.pm.PackageManager;
 import java.util.ArrayList;
+import java.util.Collections;
 
 /**
- * Test {@link DevicePolicyManager#setProtectedPackages} and
- * {@link DevicePolicyManager#getProtectedPackages}
+ * Test {@link DevicePolicyManager#setUserControlDisabledPackages} and
+ * {@link DevicePolicyManager#getUserControlDisabledPackages}
  * Hostside test uses "am force-stop" and verifies that app is not stopped.
  */
-public class ProtectedPackagesTest extends BaseDeviceOwnerTest {
+public class UserControlDisabledPackagesTest extends BaseDeviceOwnerTest {
 
     private static final String TEST_APP_APK = "CtsEmptyTestApp.apk";
     private static final String TEST_APP_PKG = "android.packageinstaller.emptytestapp.cts";
@@ -36,10 +37,10 @@
     private static final String SIMPLE_APP_ACTIVITY =
             "com.android.cts.launcherapps.simpleapp.SimpleActivityImmediateExit";
 
-    public void testSetProtectedPackages() throws Exception {
+    public void testSetUserControlDisabledPackages() throws Exception {
         ArrayList<String> protectedPackages= new ArrayList<>();
         protectedPackages.add(SIMPLE_APP_PKG);
-        mDevicePolicyManager.setProtectedPackages(getWho(), protectedPackages);
+        mDevicePolicyManager.setUserControlDisabledPackages(getWho(), protectedPackages);
 
         // Launch app so that the app exits stopped state.
         Intent intent = new Intent(Intent.ACTION_MAIN);
@@ -49,21 +50,23 @@
 
     }
 
-    public void testForceStopForProtectedPackages() throws Exception {
+    public void testForceStopWithUserControlDisabled() throws Exception {
         final ArrayList<String> pkgs = new ArrayList<>();
         pkgs.add(SIMPLE_APP_PKG);
         assertFalse(isPackageStopped(SIMPLE_APP_PKG));
-        assertEquals(pkgs, mDevicePolicyManager.getProtectedPackages(getWho()));
+        assertEquals(pkgs, mDevicePolicyManager.getUserControlDisabledPackages(getWho()));
     }
 
-    public void testClearProtectedPackages() throws Exception {
+    public void testClearSetUserControlDisabledPackages() throws Exception {
         final ArrayList<String> pkgs = new ArrayList<>();
-        mDevicePolicyManager.setProtectedPackages(getWho(), pkgs);
-        assertEquals(pkgs, mDevicePolicyManager.getProtectedPackages(getWho()));
+        mDevicePolicyManager.setUserControlDisabledPackages(getWho(), pkgs);
+        assertEquals(pkgs, mDevicePolicyManager.getUserControlDisabledPackages(getWho()));
     }
 
-    public void testForceStopForUnprotectedPackages() throws Exception {
+    public void testForceStopWithUserControlEnabled() throws Exception {
         assertTrue(isPackageStopped(SIMPLE_APP_PKG));
+        assertEquals(Collections.emptyList(),
+                mDevicePolicyManager.getUserControlDisabledPackages(getWho()));
     }
 
     private boolean isPackageStopped(String packageName) throws Exception {
diff --git a/hostsidetests/devicepolicy/app/ManagedProfile/src/com/android/cts/managedprofile/DeviceIdentifiersTest.java b/hostsidetests/devicepolicy/app/ManagedProfile/src/com/android/cts/managedprofile/DeviceIdentifiersTest.java
index 68c4d3c..efa4a35 100644
--- a/hostsidetests/devicepolicy/app/ManagedProfile/src/com/android/cts/managedprofile/DeviceIdentifiersTest.java
+++ b/hostsidetests/devicepolicy/app/ManagedProfile/src/com/android/cts/managedprofile/DeviceIdentifiersTest.java
@@ -15,8 +15,6 @@
  */
 package com.android.cts.managedprofile;
 
-import static org.testng.Assert.assertThrows;
-
 import android.content.Context;
 import android.content.pm.PackageManager;
 import android.os.Build;
@@ -27,7 +25,7 @@
  */
 public class DeviceIdentifiersTest extends BaseManagedProfileTest {
 
-    public void testProfileOwnerOnPersonalDeviceCannotGetDeviceIdentifiers() throws Exception {
+    public void testProfileOwnerOnPersonalDeviceCannotGetDeviceIdentifiers() {
         // The profile owner with the READ_PHONE_STATE permission should still receive a
         // SecurityException when querying for device identifiers if it's not on an
         // organization-owned device.
@@ -36,22 +34,35 @@
         // Allow the APIs to also return null if the telephony feature is not supported.
         boolean hasTelephonyFeature =
                 mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_TELEPHONY);
-        if (hasTelephonyFeature) {
-            assertThrows(SecurityException.class, telephonyManager::getDeviceId);
-            assertThrows(SecurityException.class, telephonyManager::getImei);
-            assertThrows(SecurityException.class, telephonyManager::getMeid);
-            assertThrows(SecurityException.class, telephonyManager::getSubscriberId);
-            assertThrows(SecurityException.class, telephonyManager::getSimSerialNumber);
-            assertThrows(SecurityException.class, telephonyManager::getNai);
-            assertThrows(SecurityException.class, Build::getSerial);
-        } else {
-            assertNull(telephonyManager.getDeviceId());
-            assertNull(telephonyManager.getImei());
-            assertNull(telephonyManager.getMeid());
-            assertNull(telephonyManager.getSubscriberId());
-            assertNull(telephonyManager.getSimSerialNumber());
-            assertNull(telephonyManager.getNai());
-            assertNull(Build.getSerial());
+
+        boolean mayReturnNull = !hasTelephonyFeature;
+
+        assertAccessDenied(telephonyManager::getDeviceId, mayReturnNull);
+        assertAccessDenied(telephonyManager::getImei, mayReturnNull);
+        assertAccessDenied(telephonyManager::getMeid, mayReturnNull);
+        assertAccessDenied(telephonyManager::getSubscriberId, mayReturnNull);
+        assertAccessDenied(telephonyManager::getSimSerialNumber, mayReturnNull);
+        assertAccessDenied(telephonyManager::getNai, mayReturnNull);
+        assertAccessDenied(Build::getSerial, mayReturnNull);
+    }
+
+    private static <T> void assertAccessDenied(ThrowingProvider<T> provider,
+            boolean mayReturnNull) {
+        try {
+            T object = provider.get();
+            if (mayReturnNull) {
+                assertNull(object);
+            } else {
+                fail("Expected SecurityException, received " + object);
+            }
+        } catch (SecurityException ignored) {
+            // assertion succeeded
+        } catch (Throwable th) {
+            fail("Expected SecurityException but was: " + th);
         }
     }
+
+    private interface ThrowingProvider<T> {
+        T get() throws Throwable;
+    }
 }
diff --git a/hostsidetests/devicepolicy/app/ManagedProfile/src/com/android/cts/managedprofile/ParentProfileTest.java b/hostsidetests/devicepolicy/app/ManagedProfile/src/com/android/cts/managedprofile/ParentProfileTest.java
index 3a3d7fb..5bcf4be 100644
--- a/hostsidetests/devicepolicy/app/ManagedProfile/src/com/android/cts/managedprofile/ParentProfileTest.java
+++ b/hostsidetests/devicepolicy/app/ManagedProfile/src/com/android/cts/managedprofile/ParentProfileTest.java
@@ -85,8 +85,8 @@
             .add("isDeviceIdAttestationSupported")
             .add("isUniqueDeviceAttestationSupported")
             .add("wipeData")
-            .add("getAutoTime")
-            .add("setAutoTime")
+            .add("getAutoTimeEnabled")
+            .add("setAutoTimeEnabled")
             .add("addUserRestriction")
             .add("clearUserRestriction")
             .add("getUserRestrictions")
@@ -169,10 +169,11 @@
 
     public void testCannotCallAutoTimeMethodsOnParentProfile() {
         assertThrows(SecurityException.class,
-                () -> mParentDevicePolicyManager.setAutoTime(ADMIN_RECEIVER_COMPONENT, true));
+                () -> mParentDevicePolicyManager.setAutoTimeEnabled(ADMIN_RECEIVER_COMPONENT,
+                        true));
 
         assertThrows(SecurityException.class,
-                () -> mParentDevicePolicyManager.getAutoTime(ADMIN_RECEIVER_COMPONENT));
+                () -> mParentDevicePolicyManager.getAutoTimeEnabled(ADMIN_RECEIVER_COMPONENT));
     }
 
     public void testCannotCallSetDefaultSmsApplicationOnParentProfile() {
diff --git a/hostsidetests/devicepolicy/app/ManagedProfile/src/com/android/cts/managedprofile/WipeDataTest.java b/hostsidetests/devicepolicy/app/ManagedProfile/src/com/android/cts/managedprofile/WipeDataTest.java
deleted file mode 100644
index 65c7724..0000000
--- a/hostsidetests/devicepolicy/app/ManagedProfile/src/com/android/cts/managedprofile/WipeDataTest.java
+++ /dev/null
@@ -1,51 +0,0 @@
-/*
- * Copyright (C) 2014 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;
-
-public class WipeDataTest extends BaseManagedProfileTest {
-    private static final String TEST_WIPE_DATA_REASON = "cts test for WipeDataWithReason";
-
-    @Override
-    protected void setUp() throws Exception {
-        super.setUp();
-        // Make sure we are running in a managed profile, otherwise risk wiping the primary user's
-        // data.
-        assertTrue(mDevicePolicyManager.isAdminActive(ADMIN_RECEIVER_COMPONENT));
-        assertTrue(mDevicePolicyManager.isProfileOwnerApp(ADMIN_RECEIVER_COMPONENT.getPackageName()));
-    }
-
-    /**
-     * Test wipeData() for use in managed profile. If called from a managed profile, wipeData()
-     * should remove the current managed profile. Also, no erasing of external storage should be
-     * allowed.
-     */
-    public void testWipeData() throws InterruptedException {
-        mDevicePolicyManager.wipeData(0);
-        // The test that the profile will indeed be removed is done in the host.
-    }
-
-    /**
-     * Test wipeDataWithReason() for use in managed profile. If called from a managed profile,
-     * wipeDataWithReason() should remove the current managed profile.In the mean time, it should
-     * send out a notification containing the reason for wiping data to user. Also, no erasing of
-     * external storage should be allowed.
-     */
-    public void testWipeDataWithReason() throws InterruptedException {
-        mDevicePolicyManager.wipeData(0, TEST_WIPE_DATA_REASON);
-        // The test that the profile will indeed be removed is done in the host.
-        // Notification verification is done in another test.
-    }
-}
diff --git a/hostsidetests/devicepolicy/app/SimpleApp/AndroidManifest.xml b/hostsidetests/devicepolicy/app/SimpleApp/AndroidManifest.xml
index 5b561ad..5e563d4 100644
--- a/hostsidetests/devicepolicy/app/SimpleApp/AndroidManifest.xml
+++ b/hostsidetests/devicepolicy/app/SimpleApp/AndroidManifest.xml
@@ -18,6 +18,7 @@
 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
     package="com.android.cts.launcherapps.simpleapp">
 
+    <uses-permission android:name="android.permission.READ_CALENDAR"/>
     <uses-permission android:name="android.permission.READ_CONTACTS"/>
     <uses-permission android:name="android.permission.FOREGROUND_SERVICE"/>
 
@@ -79,6 +80,10 @@
         <receiver android:name=".SimpleRemoteReceiver" android:process=":receiver"
                   android:exported="true">
         </receiver>
+        <provider android:name=".SimpleProvider" android:process=":remote"
+                  android:authorities="com.android.cts.launcherapps.simpleapp.provider"
+                  android:exported="false" >
+        </provider>
     </application>
 
 </manifest>
diff --git a/hostsidetests/devicepolicy/app/SimpleApp/src/com/android/cts/launcherapps/simpleapp/SimpleProvider.java b/hostsidetests/devicepolicy/app/SimpleApp/src/com/android/cts/launcherapps/simpleapp/SimpleProvider.java
new file mode 100644
index 0000000..233ec5b
--- /dev/null
+++ b/hostsidetests/devicepolicy/app/SimpleApp/src/com/android/cts/launcherapps/simpleapp/SimpleProvider.java
@@ -0,0 +1,70 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.cts.launcherapps.simpleapp;
+
+import static com.android.cts.launcherapps.simpleapp.SimpleService4.EXIT_CODE;
+import static com.android.cts.launcherapps.simpleapp.SimpleService4.METHOD_EXIT;
+
+import android.content.ContentProvider;
+import android.content.ContentValues;
+import android.database.Cursor;
+import android.net.Uri;
+import android.os.Bundle;
+
+public class SimpleProvider extends ContentProvider {
+    @Override
+    public boolean onCreate() {
+        return true;
+    }
+
+    @Override
+    public Cursor query(Uri uri, String[] projection,
+            String selection, String[] selectionArgs,
+            String sortOrder) {
+        return null;
+    }
+
+    @Override
+    public String getType(Uri uri) {
+        return null;
+    }
+
+    @Override
+    public Uri insert(Uri uri, ContentValues values) {
+        return null;
+    }
+
+    @Override
+    public int delete(Uri uri, String selection,
+            String[] selectionArgs) {
+        return 0;
+    }
+
+    @Override
+    public int update(Uri uri, ContentValues values,
+            String selection, String[] selectionArgs) {
+        return 0;
+    }
+
+    @Override
+    public Bundle call(String method, String arg, Bundle extras) {
+        if (METHOD_EXIT.equals(method)) {
+            System.exit(EXIT_CODE);
+        }
+        return null;
+    }
+}
diff --git a/hostsidetests/devicepolicy/app/SimpleApp/src/com/android/cts/launcherapps/simpleapp/SimpleService4.java b/hostsidetests/devicepolicy/app/SimpleApp/src/com/android/cts/launcherapps/simpleapp/SimpleService4.java
index 21677e4..43fb201 100644
--- a/hostsidetests/devicepolicy/app/SimpleApp/src/com/android/cts/launcherapps/simpleapp/SimpleService4.java
+++ b/hostsidetests/devicepolicy/app/SimpleApp/src/com/android/cts/launcherapps/simpleapp/SimpleService4.java
@@ -17,6 +17,8 @@
 package com.android.cts.launcherapps.simpleapp;
 
 import android.app.Service;
+import android.content.ContentProviderClient;
+import android.content.ContentResolver;
 import android.content.Context;
 import android.content.Intent;
 import android.os.Bundle;
@@ -41,6 +43,8 @@
     private static final String EXTRA_ACTION = "action";
     private static final String EXTRA_MESSENGER = "messenger";
     private static final String EXTRA_PROCESS_NAME = "process";
+    private static final String STUB_PROVIDER_AUTHORITY =
+            "com.android.cts.launcherapps.simpleapp.provider";
 
     private static final int ACTION_NONE = 0;
     private static final int ACTION_FINISH = 1;
@@ -48,11 +52,18 @@
     private static final int ACTION_ANR = 3;
     private static final int ACTION_NATIVE_CRASH = 4;
     private static final int ACTION_KILL = 5;
-    private static final int EXIT_CODE = 123;
+    private static final int ACTION_ACQUIRE_STABLE_PROVIDER = 6;
+    private static final int ACTION_KILL_PROVIDER = 7;
     private static final int CRASH_SIGNAL = OsConstants.SIGSEGV;
 
+    static final String METHOD_EXIT = "exit";
+    static final int EXIT_CODE = 123;
+
+    private static final int WAITFOR_SETTLE_DOWN = 2000;
+
     private static final int CMD_PID = 1;
     private Handler mHandler;
+    private ContentProviderClient mProviderClient;
 
     @Override
     public void onCreate() {
@@ -62,8 +73,10 @@
     @Override
     public int onStartCommand(Intent intent, int flags, int startId) {
         sendPidBack(intent);
-        // perform the action after return from here.
-        mHandler.post(() -> doAction(intent));
+        // perform the action after return from here,
+        // make a delay, otherwise the system might try to restart the service
+        // if the process dies before the system realize it's asking for START_NOT_STICKY.
+        mHandler.postDelayed(() -> doAction(intent), WAITFOR_SETTLE_DOWN);
         return START_NOT_STICKY;
     }
 
@@ -113,6 +126,17 @@
                 case ACTION_KILL:
                     Process.sendSignal(Process.myPid(), OsConstants.SIGKILL);
                     break; // Shoudln't reachable
+                case ACTION_ACQUIRE_STABLE_PROVIDER:
+                    ContentResolver cr = getContentResolver();
+                    mProviderClient = cr.acquireContentProviderClient(
+                            STUB_PROVIDER_AUTHORITY);
+                    break;
+                case ACTION_KILL_PROVIDER:
+                    try {
+                        mProviderClient.call(METHOD_EXIT, null, null);
+                    } catch (RemoteException e) {
+                    }
+                    break;
                 case ACTION_NONE:
                 default:
                     break;
diff --git a/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/CrossProfileAppsHostSideTest.java b/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/CrossProfileAppsHostSideTest.java
index d427645..345c91e 100644
--- a/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/CrossProfileAppsHostSideTest.java
+++ b/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/CrossProfileAppsHostSideTest.java
@@ -127,6 +127,7 @@
         }
         verifyCrossProfileAppsApi(mProfileId, mPrimaryUserId, START_ACTIVITY_TEST_CLASS, "testCannotStartActivityWithImplicitIntent");
         verifyCrossProfileAppsApi(mProfileId, mPrimaryUserId, START_ACTIVITY_TEST_CLASS, "testCanStartMainActivityByIntent");
+        verifyCrossProfileAppsApi(mProfileId, mPrimaryUserId, START_ACTIVITY_TEST_CLASS, "testCanStartMainActivityByIntent_withOptionsBundle");
         verifyCrossProfileAppsApi(mProfileId, mPrimaryUserId, START_ACTIVITY_TEST_CLASS, "testCanStartNonMainActivityByIntent");
         verifyCrossProfileAppsApi(mProfileId, mPrimaryUserId, START_ACTIVITY_TEST_CLASS, "testCanStartNotExportedActivityByIntent");
         verifyCrossProfileAppsApi(mProfileId, mPrimaryUserId, START_ACTIVITY_TEST_CLASS, "testCannotStartActivityInOtherPackageByIntent");
diff --git a/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/DeviceAndProfileOwnerTest.java b/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/DeviceAndProfileOwnerTest.java
index 6a6b7ef..b23f939 100644
--- a/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/DeviceAndProfileOwnerTest.java
+++ b/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/DeviceAndProfileOwnerTest.java
@@ -53,7 +53,7 @@
  * This class is the base class of MixedProfileOwnerTest, MixedDeviceOwnerTest and
  * MixedManagedProfileOwnerTest and is abstract to avoid running spurious tests.
  *
- * NOTE: Not all tests are executed in the subclasses.  Sometimes, if a test is not applicable to
+ * NOTE: Not all tests are executed in the subclasses. Sometimes, if a test is not applicable to
  * a subclass, they override it with an empty method.
  */
 public abstract class DeviceAndProfileOwnerTest extends BaseDevicePolicyTest {
@@ -84,8 +84,8 @@
             = "com.android.cts.apprestrictions.targetapp";
     private static final String APP_RESTRICTIONS_TARGET_APP_APK = "CtsAppRestrictionsTargetApp.apk";
 
-    private static final String CERT_INSTALLER_PKG = "com.android.cts.certinstaller";
-    private static final String CERT_INSTALLER_APK = "CtsCertInstallerApp.apk";
+    public static final String CERT_INSTALLER_PKG = "com.android.cts.certinstaller";
+    public static final String CERT_INSTALLER_APK = "CtsCertInstallerApp.apk";
 
     protected static final String DELEGATE_APP_PKG = "com.android.cts.delegate";
     private static final String DELEGATE_APP_APK = "CtsDelegateApp.apk";
@@ -1944,12 +1944,12 @@
     }
 
     @Test
-    public void testSetAutoTime() throws Exception {
+    public void testSetAutoTimeEnabled() throws Exception {
         if (!mHasFeature) {
             return;
         }
         assertMetricsLogged(getDevice(), () -> {
-            executeDeviceTestMethod(".DevicePolicyLoggingTest", "testSetAutoTime");
+            executeDeviceTestMethod(".DevicePolicyLoggingTest", "testSetAutoTimeEnabled");
         }, new DevicePolicyEventWrapper.Builder(EventId.SET_AUTO_TIME_VALUE)
                     .setAdminPackageName(DEVICE_ADMIN_PKG)
                     .setBoolean(true)
@@ -1961,12 +1961,12 @@
     }
 
     @Test
-    public void testSetAutoTimeZone() throws Exception {
+    public void testSetAutoTimeZoneEnabled() throws Exception {
         if (!mHasFeature) {
             return;
         }
         assertMetricsLogged(getDevice(), () -> {
-                    executeDeviceTestMethod(".TimeManagementTest", "testSetAutoTimeZone");
+                    executeDeviceTestMethod(".TimeManagementTest", "testSetAutoTimeZoneEnabled");
                 }, new DevicePolicyEventWrapper.Builder(EventId.SET_AUTO_TIME_ZONE_VALUE)
                         .setAdminPackageName(DEVICE_ADMIN_PKG)
                         .setBoolean(true)
diff --git a/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/DeviceOwnerPlusProfileOwnerTest.java b/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/DeviceOwnerPlusProfileOwnerTest.java
index 1a0d63a..d54dea3 100644
--- a/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/DeviceOwnerPlusProfileOwnerTest.java
+++ b/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/DeviceOwnerPlusProfileOwnerTest.java
@@ -195,6 +195,13 @@
         assertCannotCreateManagedProfile(mPrimaryUserId);
     }
 
+    private void sendWipeProfileBroadcast(int userId) throws Exception {
+        final String cmd = "am broadcast --receiver-foreground --user " + userId
+                + " -a com.android.cts.comp.WIPE_DATA"
+                + " com.android.cts.comp/.WipeDataReceiver";
+        getDevice().executeShellCommand(cmd);
+    }
+
     @Test
     public void testWipeData_secondaryUser() throws Exception {
         if (!mHasFeature || !canCreateAdditionalUsers(1)) {
@@ -204,11 +211,7 @@
         addDisallowRemoveUserRestriction();
         // The PO of the managed user should be allowed to delete it, even though the disallow
         // remove user restriction is set.
-        runDeviceTestsAsUser(
-                COMP_DPC_PKG,
-                MANAGEMENT_TEST,
-                "testWipeData",
-                secondaryUserId);
+        sendWipeProfileBroadcast(secondaryUserId);
         waitUntilUserRemoved(secondaryUserId);
     }
 
@@ -220,7 +223,8 @@
         int secondaryUserId = setupManagedSecondaryUser();
         addDisallowRemoveUserRestriction();
         assertMetricsLogged(getDevice(), () -> {
-            runDeviceTestsAsUser(COMP_DPC_PKG, MANAGEMENT_TEST, "testWipeData", secondaryUserId);
+            sendWipeProfileBroadcast(secondaryUserId);
+            waitUntilUserRemoved(secondaryUserId);
         }, WIPE_DATA_WITH_REASON_DEVICE_POLICY_EVENT);
     }
 
diff --git a/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/DeviceOwnerTest.java b/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/DeviceOwnerTest.java
index e45e647..303baec 100644
--- a/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/DeviceOwnerTest.java
+++ b/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/DeviceOwnerTest.java
@@ -967,28 +967,32 @@
     }
 
     @Test
-    public void testSetProtectedPackages() throws Exception {
+    public void testSetUserControlDisabledPackages() throws Exception {
         if (!mHasFeature) {
             return;
         }
         try {
             installAppAsUser(SIMPLE_APP_APK, mPrimaryUserId);
             assertMetricsLogged(getDevice(),
-                    () -> executeDeviceTestMethod(".ProtectedPackagesTest",
-                            "testSetProtectedPackages"),
-                    new DevicePolicyEventWrapper.Builder(EventId.SET_PACKAGES_PROTECTED_VALUE)
+                    () -> executeDeviceTestMethod(".UserControlDisabledPackagesTest",
+                            "testSetUserControlDisabledPackages"),
+                    new DevicePolicyEventWrapper.Builder(
+                            EventId.SET_USER_CONTROL_DISABLED_PACKAGES_VALUE)
                             .setAdminPackageName(DEVICE_OWNER_PKG)
                             .setStrings(new String[] {SIMPLE_APP_PKG})
                             .build());
             forceStopPackageForUser(SIMPLE_APP_PKG, mPrimaryUserId);
-            executeDeviceTestMethod(".ProtectedPackagesTest", "testForceStopForProtectedPackages");
+            executeDeviceTestMethod(".UserControlDisabledPackagesTest",
+                    "testForceStopWithUserControlDisabled");
             // Reboot and verify protected packages are persisted
             rebootAndWaitUntilReady();
-            executeDeviceTestMethod(".ProtectedPackagesTest", "testForceStopForProtectedPackages");
-            executeDeviceTestMethod(".ProtectedPackagesTest", "testClearProtectedPackages");
+            executeDeviceTestMethod(".UserControlDisabledPackagesTest",
+                    "testForceStopWithUserControlDisabled");
+            executeDeviceTestMethod(".UserControlDisabledPackagesTest",
+                    "testClearSetUserControlDisabledPackages");
             forceStopPackageForUser(SIMPLE_APP_PKG, mPrimaryUserId);
-            executeDeviceTestMethod(".ProtectedPackagesTest",
-                    "testForceStopForUnprotectedPackages");
+            executeDeviceTestMethod(".UserControlDisabledPackagesTest",
+                    "testForceStopWithUserControlEnabled");
         } finally {
             getDevice().uninstallPackage(SIMPLE_APP_APK);
         }
diff --git a/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/ManagedProfileCrossProfileTest.java b/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/ManagedProfileCrossProfileTest.java
index 6152f94..4fe211f 100644
--- a/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/ManagedProfileCrossProfileTest.java
+++ b/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/ManagedProfileCrossProfileTest.java
@@ -491,6 +491,9 @@
         }
         installAllDummyApps();
         getDevice().clearLogcat();
+        // Increase logcat size because the test is reading from it.
+        String command = "logcat -G 16M";
+        getDevice().executeShellCommand(command);
 
         runWorkProfileDeviceTest(
                 ".CrossProfileTest",
diff --git a/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/MixedManagedProfileOwnerTest.java b/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/MixedManagedProfileOwnerTest.java
index bb75420..7a61083 100644
--- a/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/MixedManagedProfileOwnerTest.java
+++ b/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/MixedManagedProfileOwnerTest.java
@@ -200,14 +200,14 @@
 
     @Override
     @Test
-    public void testSetAutoTime() {
+    public void testSetAutoTimeEnabled() {
         // Managed profile owner cannot set auto time unless it is called by the profile owner of
         // an organization-owned managed profile.
     }
 
     @Override
     @Test
-    public void testSetAutoTimeZone() {
+    public void testSetAutoTimeZoneEnabled() {
         // Managed profile owner cannot set auto time zone unless it is called by the profile
         // owner of an organization-owned managed profile.
     }
@@ -232,38 +232,24 @@
         if (!mHasFeature) {
             return;
         }
-
         setUpDelegatedCertInstallerAndRunTests(() -> {
             runDeviceTestsAsUser("com.android.cts.certinstaller",
                     ".DelegatedDeviceIdAttestationTest",
                     "testGenerateKeyPairWithDeviceIdAttestationExpectingFailure", mUserId);
-
-            markProfileOwnerOnOrganizationOwnedDevice();
-
-            runDeviceTestsAsUser("com.android.cts.certinstaller",
-                    ".DelegatedDeviceIdAttestationTest",
-                    "testGenerateKeyPairWithDeviceIdAttestationExpectingSuccess", mUserId);
+            // Positive test case lives in
+            // OrgOwnedProfileOwnerTest#testDelegatedCertInstallerDeviceIdAttestation
         });
-
-        // Clean up:
-        runDeviceTestsAsUser(DEVICE_ADMIN_PKG, ".DelegatedCertInstallerHelper",
-                "testManualWipeProfile", mUserId);
     }
     @Test
     public void testDeviceIdAttestationForProfileOwner() throws Exception {
         if (!mHasFeature) {
             return;
         }
-
         // Test that Device ID attestation for the profile owner does not work without grant.
         runDeviceTestsAsUser(DEVICE_ADMIN_PKG, ".DeviceIdAttestationTest",
                 "testFailsWithoutProfileOwnerIdsGrant", mUserId);
-
-        // Test that Device ID attestation for the profile owner works with a grant.
-        markProfileOwnerOnOrganizationOwnedDevice();
-
-        runDeviceTestsAsUser(DEVICE_ADMIN_PKG, ".DeviceIdAttestationTest",
-                "testSucceedsWithProfileOwnerIdsGrant", mUserId);
+        // Positive test case lives in
+        // OrgOwnedProfileOwnerTest#testDeviceIdAttestationForProfileOwner
     }
 
     @Test
diff --git a/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/MixedProfileOwnerTest.java b/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/MixedProfileOwnerTest.java
index 2da4cba..66b2630 100644
--- a/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/MixedProfileOwnerTest.java
+++ b/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/MixedProfileOwnerTest.java
@@ -101,7 +101,7 @@
 
     @Override
     @Test
-    public void testSetAutoTimeZone() {
+    public void testSetAutoTimeZoneEnabled() {
         // Profile owner cannot set auto time zone unless it is called by the profile
         // owner of an organization-owned managed profile or a profile owner on user 0.
     }
diff --git a/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/OrgOwnedProfileOwnerTest.java b/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/OrgOwnedProfileOwnerTest.java
index 5716258..765f675 100644
--- a/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/OrgOwnedProfileOwnerTest.java
+++ b/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/OrgOwnedProfileOwnerTest.java
@@ -39,8 +39,11 @@
  * Tests for organization-owned Profile Owner.
  */
 public class OrgOwnedProfileOwnerTest extends BaseDevicePolicyTest {
-    public static final String DEVICE_ADMIN_PKG = DeviceAndProfileOwnerTest.DEVICE_ADMIN_PKG;
+    private static final String DEVICE_ADMIN_PKG = DeviceAndProfileOwnerTest.DEVICE_ADMIN_PKG;
     private static final String DEVICE_ADMIN_APK = DeviceAndProfileOwnerTest.DEVICE_ADMIN_APK;
+    private static final String CERT_INSTALLER_PKG = DeviceAndProfileOwnerTest.CERT_INSTALLER_PKG;
+    private static final String CERT_INSTALLER_APK = DeviceAndProfileOwnerTest.CERT_INSTALLER_APK;
+
     private static final String ADMIN_RECEIVER_TEST_CLASS =
             DeviceAndProfileOwnerTest.ADMIN_RECEIVER_TEST_CLASS;
     private static final String ACTION_WIPE_DATA =
@@ -607,6 +610,31 @@
         }
     }
 
+    @Test
+    public void testDelegatedCertInstallerDeviceIdAttestation() throws Exception {
+        if (!mHasFeature) {
+            return;
+        }
+        installAppAsUser(CERT_INSTALLER_APK, mUserId);
+
+        runDeviceTestsAsUser(DEVICE_ADMIN_PKG, ".DelegatedCertInstallerHelper",
+                "testManualSetCertInstallerDelegate", mUserId);
+
+        runDeviceTestsAsUser(CERT_INSTALLER_PKG, ".DelegatedDeviceIdAttestationTest",
+                "testGenerateKeyPairWithDeviceIdAttestationExpectingSuccess", mUserId);
+    }
+
+    @Test
+    public void testDeviceIdAttestationForProfileOwner() throws Exception {
+        if (!mHasFeature) {
+            return;
+        }
+        // Test that Device ID attestation works for org-owned profile owner.
+        runDeviceTestsAsUser(DEVICE_ADMIN_PKG, ".DeviceIdAttestationTest",
+                "testSucceedsWithProfileOwnerIdsGrant", mUserId);
+
+    }
+
     private void toggleQuietMode(boolean quietModeEnable) throws Exception {
         final String str = String.format("am start-activity -n %s --ez %s %s",
                 QUIET_MODE_TOGGLE_ACTIVITY, EXTRA_QUIET_MODE_STATE, quietModeEnable);
diff --git a/hostsidetests/gputools/layers/Android.bp b/hostsidetests/gputools/layers/Android.bp
index 9d12a7b..3b3a155 100644
--- a/hostsidetests/gputools/layers/Android.bp
+++ b/hostsidetests/gputools/layers/Android.bp
@@ -25,8 +25,6 @@
     shared_libs: [
         "libandroid",
         "libvulkan",
-        "libEGL",
-        "libGLESv3",
         "liblog",
     ],
     stl: "c++_shared",
@@ -46,8 +44,6 @@
     shared_libs: [
         "libandroid",
         "libvulkan",
-        "libEGL",
-        "libGLESv3",
         "liblog",
     ],
     stl: "c++_shared",
@@ -67,8 +63,6 @@
     shared_libs: [
         "libandroid",
         "libvulkan",
-        "libEGL",
-        "libGLESv3",
         "liblog",
     ],
     stl: "c++_shared",
diff --git a/hostsidetests/gputools/layers/jni/nullLayer.cpp b/hostsidetests/gputools/layers/jni/nullLayer.cpp
index c5f84ca..dac52c9 100644
--- a/hostsidetests/gputools/layers/jni/nullLayer.cpp
+++ b/hostsidetests/gputools/layers/jni/nullLayer.cpp
@@ -22,7 +22,8 @@
 #define xstr(a) str(a)
 #define str(a) #a
 
-#define LOG_TAG "nullLayer" xstr(LAYERNAME)
+#define LAYER_FULL_NAME "VK_LAYER_ANDROID_nullLayer" xstr(LAYERNAME)
+#define LOG_TAG LAYER_FULL_NAME
 
 #define ALOGI(msg, ...) \
     __android_log_print(ANDROID_LOG_INFO, LOG_TAG, (msg), __VA_ARGS__)
@@ -35,8 +36,8 @@
             ALOGI("%s", msg);
     }
 };
-StaticLogMessage g_initMessage("nullLayer" xstr(LAYERNAME) " loaded");
-
+StaticLogMessage
+    g_initMessage("VK_LAYER_ANDROID_nullLayer" xstr(LAYERNAME) " loaded");
 
 namespace {
 
@@ -68,7 +69,10 @@
 }
 
 static const VkLayerProperties LAYER_PROPERTIES = {
-    "VK_LAYER_ANDROID_nullLayer" xstr(LAYERNAME), VK_MAKE_VERSION(1, 0, VK_HEADER_VERSION), 1, "Layer: nullLayer" xstr(LAYERNAME),
+    LAYER_FULL_NAME,
+    VK_MAKE_VERSION(1, 0, VK_HEADER_VERSION),
+    1,
+    "Layer: nullLayer" xstr(LAYERNAME),
 };
 
 VKAPI_ATTR VkResult VKAPI_CALL EnumerateInstanceLayerProperties(uint32_t *pCount, VkLayerProperties *pProperties) {
@@ -97,7 +101,7 @@
 
     VkLayerDeviceCreateInfo *layerCreateInfo = (VkLayerDeviceCreateInfo*)pCreateInfo->pNext;
 
-    const char* msg = "nullCreateDevice called in nullLayer" xstr(LAYERNAME);
+    const char *msg = "nullCreateDevice called in " LAYER_FULL_NAME;
     ALOGI("%s", msg);
 
     // Step through the pNext chain until we get to the link function
@@ -134,7 +138,7 @@
 
     VkLayerInstanceCreateInfo *layerCreateInfo = (VkLayerInstanceCreateInfo *)pCreateInfo->pNext;
 
-    const char* msg = "nullCreateInstance called in nullLayer" xstr(LAYERNAME);
+    const char *msg = "nullCreateInstance called in " LAYER_FULL_NAME;
     ALOGI("%s", msg);
 
     // Step through the pNext chain until we get to the link function
diff --git a/hostsidetests/gputools/src/android/gputools/cts/CtsRootlessGpuDebugHostTest.java b/hostsidetests/gputools/src/android/gputools/cts/CtsRootlessGpuDebugHostTest.java
index fb14756..fc166da 100644
--- a/hostsidetests/gputools/src/android/gputools/cts/CtsRootlessGpuDebugHostTest.java
+++ b/hostsidetests/gputools/src/android/gputools/cts/CtsRootlessGpuDebugHostTest.java
@@ -87,19 +87,16 @@
     // Positive combined tests
     // - Ensure we can load Vulkan and GLES layers at the same time, from multiple external apps (testMultipleExternalApps)
 
-
-
     private static final String CLASS = "RootlessGpuDebugDeviceActivity";
     private static final String ACTIVITY = "android.rootlessgpudebug.app.RootlessGpuDebugDeviceActivity";
-    private static final String LAYER_A = "nullLayerA";
-    private static final String LAYER_B = "nullLayerB";
-    private static final String LAYER_C = "nullLayerC";
-    private static final String LAYER_A_LIB = "libVkLayer_" + LAYER_A + ".so";
-    private static final String LAYER_B_LIB = "libVkLayer_" + LAYER_B + ".so";
-    private static final String LAYER_C_LIB = "libVkLayer_" + LAYER_C + ".so";
-    private static final String LAYER_A_NAME = "VK_LAYER_ANDROID_" + LAYER_A;
-    private static final String LAYER_B_NAME = "VK_LAYER_ANDROID_" + LAYER_B;
-    private static final String LAYER_C_NAME = "VK_LAYER_ANDROID_" + LAYER_C;
+    private static final String VK_LAYER_LIB_PREFIX = "libVkLayer_nullLayer";
+    private static final String VK_LAYER_A_LIB = VK_LAYER_LIB_PREFIX + "A.so";
+    private static final String VK_LAYER_B_LIB = VK_LAYER_LIB_PREFIX + "B.so";
+    private static final String VK_LAYER_C_LIB = VK_LAYER_LIB_PREFIX + "C.so";
+    private static final String VK_LAYER_NAME_PREFIX = "VK_LAYER_ANDROID_nullLayer";
+    private static final String VK_LAYER_A = VK_LAYER_NAME_PREFIX + "A";
+    private static final String VK_LAYER_B = VK_LAYER_NAME_PREFIX + "B";
+    private static final String VK_LAYER_C = VK_LAYER_NAME_PREFIX + "C";
     private static final String DEBUG_APP = "android.rootlessgpudebug.DEBUG.app";
     private static final String RELEASE_APP = "android.rootlessgpudebug.RELEASE.app";
     private static final String INJECT_APP = "android.rootlessgpudebug.INJECT.app";
@@ -117,14 +114,13 @@
     private static final String GLES_LAYER_B_LIB = "libGLES_" + GLES_LAYER_B + ".so";
     private static final String GLES_LAYER_C_LIB = "libGLES_" + GLES_LAYER_C + ".so";
 
-    private static boolean initialized = false;
-
     // This is how long we'll scan the log for a result before giving up. This limit will only
     // be reached if something has gone wrong
     private static final long LOG_SEARCH_TIMEOUT_MS = 5000;
-
     private static final long SETTING_APPLY_TIMEOUT_MS = 5000;
 
+    private static boolean initialized = false;
+
     private String removeWhitespace(String input) {
         return input.replaceAll(System.getProperty("line.separator"), "").trim();
     }
@@ -172,6 +168,32 @@
     }
 
     /**
+     * Check that the layer is loaded by only checking the log after startTime.
+     */
+    private void assertVkLayerLoading(String startTime, String layerName, boolean loaded) throws Exception {
+        String searchString = "nullCreateInstance called in " + layerName;
+        LogScanResult result = scanLog(TAG + "," + layerName, searchString, startTime);
+        if (loaded) {
+            Assert.assertTrue(layerName + " was not loaded", result.found);
+        } else {
+            Assert.assertFalse(layerName + " was loaded", result.found);
+        }
+    }
+
+    /**
+     * Check that the layer is enumerated by only checking the log after startTime.
+     */
+    private void assertVkLayerEnumeration(String startTime, String layerName, boolean enumerated) throws Exception {
+        String searchString = layerName + " loaded";
+        LogScanResult result = scanLog(TAG + "," + layerName, searchString, startTime);
+        if (enumerated) {
+            Assert.assertTrue(layerName + " was not enumerated", result.found);
+        } else {
+            Assert.assertFalse(layerName + " was enumerated", result.found);
+        }
+    }
+
+    /**
      * Simple helper class for returning multiple results
      */
     public class LogScanResult {
@@ -242,9 +264,9 @@
         getDevice().executeAdbCommand("shell", "am", "force-stop", DEBUG_APP);
         getDevice().executeAdbCommand("shell", "am", "force-stop", RELEASE_APP);
         getDevice().executeAdbCommand("shell", "am", "force-stop", INJECT_APP);
-        getDevice().executeAdbCommand("shell", "rm", "-f", "/data/local/tmp/" + LAYER_A_LIB);
-        getDevice().executeAdbCommand("shell", "rm", "-f", "/data/local/tmp/" + LAYER_B_LIB);
-        getDevice().executeAdbCommand("shell", "rm", "-f", "/data/local/tmp/" + LAYER_C_LIB);
+        getDevice().executeAdbCommand("shell", "rm", "-f", "/data/local/tmp/" + VK_LAYER_A_LIB);
+        getDevice().executeAdbCommand("shell", "rm", "-f", "/data/local/tmp/" + VK_LAYER_B_LIB);
+        getDevice().executeAdbCommand("shell", "rm", "-f", "/data/local/tmp/" + VK_LAYER_C_LIB);
         getDevice().executeAdbCommand("shell", "rm", "-f", "/data/local/tmp/" + GLES_LAYER_A_LIB);
         getDevice().executeAdbCommand("shell", "rm", "-f", "/data/local/tmp/" + GLES_LAYER_B_LIB);
         getDevice().executeAdbCommand("shell", "rm", "-f", "/data/local/tmp/" + GLES_LAYER_C_LIB);
@@ -282,20 +304,20 @@
         // Set up layers to be loaded
         applySetting("enable_gpu_debug_layers", "1");
         applySetting("gpu_debug_app", DEBUG_APP);
-        applySetting("gpu_debug_layers", LAYER_A_NAME + ":" + LAYER_B_NAME);
+        applySetting("gpu_debug_layers", VK_LAYER_A + ":" + VK_LAYER_B);
 
         // Copy the layers from our LAYERS APK to tmp
-        setupLayer(LAYER_A_LIB, LAYERS_APP);
-        setupLayer(LAYER_B_LIB, LAYERS_APP);
+        setupLayer(VK_LAYER_A_LIB, LAYERS_APP);
+        setupLayer(VK_LAYER_B_LIB, LAYERS_APP);
 
 
         // Copy them over to our DEBUG app
-        getDevice().executeAdbCommand("shell", "cat", "/data/local/tmp/" + LAYER_A_LIB, "|",
+        getDevice().executeAdbCommand("shell", "cat", "/data/local/tmp/" + VK_LAYER_A_LIB, "|",
                 "run-as", DEBUG_APP, "--user", Integer.toString(getDevice().getCurrentUser()),
-                "sh", "-c", "\'cat", ">", LAYER_A_LIB, ";", "chmod", "700", LAYER_A_LIB + "\'");
-        getDevice().executeAdbCommand("shell", "cat", "/data/local/tmp/" + LAYER_B_LIB, "|",
+                "sh", "-c", "\'cat", ">", VK_LAYER_A_LIB, ";", "chmod", "700", VK_LAYER_A_LIB + "\'");
+        getDevice().executeAdbCommand("shell", "cat", "/data/local/tmp/" + VK_LAYER_B_LIB, "|",
                 "run-as", DEBUG_APP, "--user", Integer.toString(getDevice().getCurrentUser()),
-                "sh", "-c", "\'cat", ">", LAYER_B_LIB, ";", "chmod", "700", LAYER_B_LIB + "\'");
+                "sh", "-c", "\'cat", ">", VK_LAYER_B_LIB, ";", "chmod", "700", VK_LAYER_B_LIB + "\'");
 
 
         // Kick off our DEBUG app
@@ -303,12 +325,12 @@
         getDevice().executeAdbCommand("shell", "am", "start", "-n", DEBUG_APP + "/" + ACTIVITY);
 
         // Check that both layers were loaded, in the correct order
-        String searchStringA = "nullCreateInstance called in " + LAYER_A;
-        LogScanResult resultA = scanLog(TAG + "," + LAYER_A + "," + LAYER_B, searchStringA, appStartTime);
+        String searchStringA = "nullCreateInstance called in " + VK_LAYER_A;
+        LogScanResult resultA = scanLog(TAG + "," + VK_LAYER_A + "," + VK_LAYER_B, searchStringA, appStartTime);
         Assert.assertTrue("LayerA was not loaded", resultA.found);
 
-        String searchStringB = "nullCreateInstance called in " + LAYER_B;
-        LogScanResult resultB = scanLog(TAG + "," + LAYER_A + "," + LAYER_B, searchStringB, appStartTime);
+        String searchStringB = "nullCreateInstance called in " + VK_LAYER_B;
+        LogScanResult resultB = scanLog(TAG + "," + VK_LAYER_A + "," + VK_LAYER_B, searchStringB, appStartTime);
         Assert.assertTrue("LayerB was not loaded", resultB.found);
 
         Assert.assertTrue("LayerA should be loaded before LayerB", resultA.lineNumber < resultB.lineNumber);
@@ -318,24 +340,22 @@
         // Set up a layers to be loaded for RELEASE or INJECT app
         applySetting("enable_gpu_debug_layers", "1");
         applySetting("gpu_debug_app", APP_NAME);
-        applySetting("gpu_debug_layers", LAYER_A_NAME + ":" + LAYER_B_NAME);
+        applySetting("gpu_debug_layers", VK_LAYER_A + ":" + VK_LAYER_B);
 
         // Copy a layer from our LAYERS APK to tmp
-        setupLayer(LAYER_A_LIB, LAYERS_APP);
+        setupLayer(VK_LAYER_A_LIB, LAYERS_APP);
 
         // Attempt to copy them over to our RELEASE or INJECT app (this should fail)
-        getDevice().executeAdbCommand("shell", "cat", "/data/local/tmp/" + LAYER_A_LIB, "|",
+        getDevice().executeAdbCommand("shell", "cat", "/data/local/tmp/" + VK_LAYER_A_LIB, "|",
             "run-as", APP_NAME, "--user", Integer.toString(getDevice().getCurrentUser()),
-            "sh", "-c", "\'cat", ">", LAYER_A_LIB, ";", "chmod", "700", LAYER_A_LIB + "\'", "||", "echo", "run-as", "failed");
+            "sh", "-c", "\'cat", ">", VK_LAYER_A_LIB, ";", "chmod", "700", VK_LAYER_A_LIB + "\'", "||", "echo", "run-as", "failed");
 
         // Kick off our RELEASE app
         String appStartTime = getTime();
         getDevice().executeAdbCommand("shell", "am", "start", "-n", APP_NAME + "/" + ACTIVITY);
 
         // Ensure we don't load the layer in base dir
-        String searchStringA = LAYER_A_NAME + "loaded";
-        LogScanResult resultA = scanLog(TAG + "," + LAYER_A, searchStringA, appStartTime);
-        Assert.assertFalse("LayerA was enumerated", resultA.found);
+        assertVkLayerEnumeration(appStartTime, VK_LAYER_A, false);
     }
 
     /**
@@ -366,24 +386,22 @@
         // Ensure the global layer enable settings is NOT enabled
         applySetting("enable_gpu_debug_layers", "0");
         applySetting("gpu_debug_app", DEBUG_APP);
-        applySetting("gpu_debug_layers", LAYER_A_NAME);
+        applySetting("gpu_debug_layers", VK_LAYER_A);
 
         // Copy a layer from our LAYERS APK to tmp
-        setupLayer(LAYER_A_LIB, LAYERS_APP);
+        setupLayer(VK_LAYER_A_LIB, LAYERS_APP);
 
         // Copy it over to our DEBUG app
-        getDevice().executeAdbCommand("shell", "cat", "/data/local/tmp/" + LAYER_A_LIB, "|",
+        getDevice().executeAdbCommand("shell", "cat", "/data/local/tmp/" + VK_LAYER_A_LIB, "|",
                 "run-as", DEBUG_APP, "--user", Integer.toString(getDevice().getCurrentUser()),
-                "sh", "-c", "\'cat", ">", LAYER_A_LIB, ";", "chmod", "700", LAYER_A_LIB + "\'");
+                "sh", "-c", "\'cat", ">", VK_LAYER_A_LIB, ";", "chmod", "700", VK_LAYER_A_LIB + "\'");
 
         // Kick off our DEBUG app
         String appStartTime = getTime();
         getDevice().executeAdbCommand("shell", "am", "start", "-n", DEBUG_APP + "/" + ACTIVITY);
 
         // Ensure we don't load the layer in base dir
-        String searchStringA = LAYER_A_NAME + "loaded";
-        LogScanResult resultA = scanLog(TAG + "," + LAYER_A, searchStringA, appStartTime);
-        Assert.assertFalse("LayerA was enumerated", resultA.found);
+        assertVkLayerEnumeration(appStartTime, VK_LAYER_A, false);
     }
 
     /**
@@ -396,24 +414,22 @@
         // Ensure the gpu_debug_app does not match what we launch
         applySetting("enable_gpu_debug_layers", "1");
         applySetting("gpu_debug_app", RELEASE_APP);
-        applySetting("gpu_debug_layers", LAYER_A_NAME);
+        applySetting("gpu_debug_layers", VK_LAYER_A);
 
         // Copy a layer from our LAYERS APK to tmp
-        setupLayer(LAYER_A_LIB, LAYERS_APP);
+        setupLayer(VK_LAYER_A_LIB, LAYERS_APP);
 
         // Copy it over to our DEBUG app
-        getDevice().executeAdbCommand("shell", "cat", "/data/local/tmp/" + LAYER_A_LIB, "|",
+        getDevice().executeAdbCommand("shell", "cat", "/data/local/tmp/" + VK_LAYER_A_LIB, "|",
                 "run-as", DEBUG_APP, "--user", Integer.toString(getDevice().getCurrentUser()),
-                "sh", "-c", "\'cat", ">", LAYER_A_LIB, ";", "chmod", "700", LAYER_A_LIB + "\'");
+                "sh", "-c", "\'cat", ">", VK_LAYER_A_LIB, ";", "chmod", "700", VK_LAYER_A_LIB + "\'");
 
         // Kick off our DEBUG app
         String appStartTime = getTime();
         getDevice().executeAdbCommand("shell", "am", "start", "-n", DEBUG_APP + "/" + ACTIVITY);
 
         // Ensure we don't load the layer in base dir
-        String searchStringA = LAYER_A_NAME + "loaded";
-        LogScanResult resultA = scanLog(TAG + "," + LAYER_A, searchStringA, appStartTime);
-        Assert.assertFalse("LayerA was enumerated", resultA.found);
+        assertVkLayerEnumeration(appStartTime, VK_LAYER_A, false);
     }
 
     /**
@@ -429,21 +445,19 @@
         applySetting("gpu_debug_layers", "foo");
 
         // Copy a layer from our LAYERS APK to tmp
-        setupLayer(LAYER_A_LIB, LAYERS_APP);
+        setupLayer(VK_LAYER_A_LIB, LAYERS_APP);
 
         // Copy it over to our DEBUG app
-        getDevice().executeAdbCommand("shell", "cat", "/data/local/tmp/" + LAYER_A_LIB, "|",
+        getDevice().executeAdbCommand("shell", "cat", "/data/local/tmp/" + VK_LAYER_A_LIB, "|",
                 "run-as", DEBUG_APP, "--user", Integer.toString(getDevice().getCurrentUser()),
-                "sh", "-c", "\'cat", ">", LAYER_A_LIB, ";", "chmod", "700", LAYER_A_LIB + "\'");
+                "sh", "-c", "\'cat", ">", VK_LAYER_A_LIB, ";", "chmod", "700", VK_LAYER_A_LIB + "\'");
 
         // Kick off our DEBUG app
         String appStartTime = getTime();
         getDevice().executeAdbCommand("shell", "am", "start", "-n", DEBUG_APP + "/" + ACTIVITY);
 
         // Ensure layerA is not loaded
-        String searchStringA = "nullCreateInstance called in " + LAYER_A;
-        LogScanResult resultA = scanLog(TAG + "," + LAYER_A, searchStringA, appStartTime);
-        Assert.assertFalse("LayerA was loaded", resultA.found);
+        assertVkLayerLoading(appStartTime, VK_LAYER_A, false);
     }
 
     /**
@@ -458,20 +472,15 @@
         deleteSetting("gpu_debug_layers");
 
         // Enable layerC (which is packaged with the RELEASE app) with system properties
-        getDevice().executeAdbCommand("shell", "setprop", "debug.vulkan.layers " + LAYER_C_NAME);
+        getDevice().executeAdbCommand("shell", "setprop", "debug.vulkan.layers " + VK_LAYER_C);
 
         // Kick off our RELEASE app
         String appStartTime = getTime();
         getDevice().executeAdbCommand("shell", "am", "start", "-n", RELEASE_APP + "/" + ACTIVITY);
 
         // Check that only layerC was loaded
-        String searchStringA = LAYER_A_NAME + "loaded";
-        LogScanResult resultA = scanLog(TAG + "," + LAYER_A, searchStringA, appStartTime);
-        Assert.assertFalse("LayerA was enumerated", resultA.found);
-
-        String searchStringC = "nullCreateInstance called in " + LAYER_C;
-        LogScanResult resultC = scanLog(TAG + "," + LAYER_C, searchStringC, appStartTime);
-        Assert.assertTrue("LayerC was not loaded", resultC.found);
+        assertVkLayerEnumeration(appStartTime, VK_LAYER_A, false);
+        assertVkLayerLoading(appStartTime, VK_LAYER_C, true);
     }
 
     /**
@@ -483,35 +492,30 @@
         // Set up layerA to be loaded, but not layerB
         applySetting("enable_gpu_debug_layers", "1");
         applySetting("gpu_debug_app", DEBUG_APP);
-        applySetting("gpu_debug_layers", LAYER_A_NAME);
+        applySetting("gpu_debug_layers", VK_LAYER_A);
 
         // Copy the layers from our LAYERS APK
-        setupLayer(LAYER_A_LIB, LAYERS_APP);
-        setupLayer(LAYER_B_LIB, LAYERS_APP);
+        setupLayer(VK_LAYER_A_LIB, LAYERS_APP);
+        setupLayer(VK_LAYER_B_LIB, LAYERS_APP);
 
         // Copy them over to our DEBUG app
-        getDevice().executeAdbCommand("shell", "cat", "/data/local/tmp/" + LAYER_A_LIB, "|",
+        getDevice().executeAdbCommand("shell", "cat", "/data/local/tmp/" + VK_LAYER_A_LIB, "|",
                 "run-as", DEBUG_APP, "--user", Integer.toString(getDevice().getCurrentUser()),
-                "sh", "-c", "\'cat", ">", LAYER_A_LIB, ";", "chmod", "700", LAYER_A_LIB + "\'");
-        getDevice().executeAdbCommand("shell", "cat", "/data/local/tmp/" + LAYER_B_LIB, "|",
+                "sh", "-c", "\'cat", ">", VK_LAYER_A_LIB, ";", "chmod", "700", VK_LAYER_A_LIB + "\'");
+        getDevice().executeAdbCommand("shell", "cat", "/data/local/tmp/" + VK_LAYER_B_LIB, "|",
                 "run-as", DEBUG_APP, "--user", Integer.toString(getDevice().getCurrentUser()),
-                "sh", "-c", "\'cat", ">", LAYER_B_LIB, ";", "chmod", "700", LAYER_B_LIB + "\'");
+                "sh", "-c", "\'cat", ">", VK_LAYER_B_LIB, ";", "chmod", "700", VK_LAYER_B_LIB + "\'");
 
         // Enable layerB with system properties
-        getDevice().executeAdbCommand("shell", "setprop", "debug.vulkan.layers " + LAYER_B_NAME);
+        getDevice().executeAdbCommand("shell", "setprop", "debug.vulkan.layers " + VK_LAYER_B);
 
         // Kick off our DEBUG app
         String appStartTime = getTime();
         getDevice().executeAdbCommand("shell", "am", "start", "-n", DEBUG_APP + "/" + ACTIVITY);
 
         // Ensure only layerA is loaded
-        String searchStringA = "nullCreateInstance called in " + LAYER_A;
-        LogScanResult resultA = scanLog(TAG + "," + LAYER_A, searchStringA, appStartTime);
-        Assert.assertTrue("LayerA was not loaded", resultA.found);
-
-        String searchStringB = "nullCreateInstance called in " + LAYER_B;
-        LogScanResult resultB = scanLog(TAG + "," + LAYER_B, searchStringB, appStartTime);
-        Assert.assertFalse("LayerB was loaded", resultB.found);
+        assertVkLayerLoading(appStartTime, VK_LAYER_A, true);
+        assertVkLayerLoading(appStartTime, VK_LAYER_B, false);
     }
 
 
@@ -520,7 +524,7 @@
         // Set up layers to be loaded
         applySetting("enable_gpu_debug_layers", "1");
         applySetting("gpu_debug_app", APP_NAME);
-        applySetting("gpu_debug_layers", LAYER_C_NAME);
+        applySetting("gpu_debug_layers", VK_LAYER_C);
 
         // Specify the external app that hosts layers
         applySetting("gpu_debug_layer_app", LAYERS_APP);
@@ -530,9 +534,7 @@
         getDevice().executeAdbCommand("shell", "am", "start", "-n", APP_NAME + "/" + ACTIVITY);
 
         // Check that our external layer was loaded
-        String searchStringC = "nullCreateInstance called in " + LAYER_C;
-        LogScanResult resultC = scanLog(TAG + "," + LAYER_C, searchStringC, appStartTime);
-        Assert.assertTrue("LayerC was not loaded", resultC.found);
+        assertVkLayerLoading(appStartTime, VK_LAYER_C, true);
     }
 
     /**
@@ -820,7 +822,7 @@
         // Set up layers to be loaded
         applySetting("enable_gpu_debug_layers", "1");
         applySetting("gpu_debug_app", DEBUG_APP);
-        applySetting("gpu_debug_layers", LAYER_C_NAME);
+        applySetting("gpu_debug_layers", VK_LAYER_C);
         applySetting("gpu_debug_layers_gles", GLES_LAYER_C_LIB);
 
         // Specify multple external apps that host layers
@@ -831,9 +833,7 @@
         getDevice().executeAdbCommand("shell", "am", "start", "-n", DEBUG_APP + "/" + ACTIVITY);
 
         // Check that external layers were loaded from both apps
-        String vulkanString = "nullCreateInstance called in " + LAYER_C;
-        LogScanResult vulkanResult = scanLog(TAG + "," + LAYER_C, vulkanString, appStartTime);
-        Assert.assertTrue(LAYER_C + " was not loaded", vulkanResult.found);
+        assertVkLayerLoading(appStartTime, VK_LAYER_C, true);
 
         String glesString = "glesLayer_eglChooseConfig called in " + GLES_LAYER_C;
         LogScanResult glesResult = scanLog(TAG + "," + GLES_LAYER_C, glesString, appStartTime);
diff --git a/hostsidetests/security/src/android/security/cts/KernelConfigTest.java b/hostsidetests/security/src/android/security/cts/KernelConfigTest.java
index b379c5f..9eb5241 100644
--- a/hostsidetests/security/src/android/security/cts/KernelConfigTest.java
+++ b/hostsidetests/security/src/android/security/cts/KernelConfigTest.java
@@ -319,4 +319,20 @@
                    + "and it must be empty or start with one of the following "
                    + "prefixes: " + whitelistedPathPrefixExample, pathIsWhitelisted);
     }
+
+    /**
+     * Test that the kernel enables fs-verity and its built-in signature support.
+     */
+    @CddTest(requirement="9.10")
+    public void testConfigFsVerity() throws Exception {
+        if (PropertyUtil.getFirstApiLevel(mDevice) < 30 &&
+                PropertyUtil.getPropertyInt(mDevice, "ro.apk_verity.mode") != 2) {
+            return;
+        }
+        assertTrue("Linux kernel must have fs-verity enabled: CONFIG_FS_VERITY=y",
+                configSet.contains("CONFIG_FS_VERITY=y"));
+        assertTrue("Linux kernel must have fs-verity's builtin signature enabled: "
+                + "CONFIG_FS_VERITY_BUILTIN_SIGNATURES=y",
+                configSet.contains("CONFIG_FS_VERITY_BUILTIN_SIGNATURES=y"));
+    }
 }
diff --git a/hostsidetests/securitybulletin/src/android/security/cts/AdbUtils.java b/hostsidetests/securitybulletin/src/android/security/cts/AdbUtils.java
index b1eeb5e..ac8908b 100644
--- a/hostsidetests/securitybulletin/src/android/security/cts/AdbUtils.java
+++ b/hostsidetests/securitybulletin/src/android/security/cts/AdbUtils.java
@@ -393,9 +393,22 @@
      */
     public static void runPocAssertNoCrashes(String pocName, ITestDevice device,
             String... processPatternStrings) throws Exception {
+        runPocAssertNoCrashes(pocName, device,
+                new CrashUtils.Config().setProcessPatterns(processPatternStrings));
+    }
+
+    /**
+     * Runs the poc binary and asserts that there are no security crashes that match the expected
+     * process pattern.
+     * @param pocName a string path to poc from the /res folder
+     * @param device device to be ran on
+     * @param config a crash parser configuration
+     */
+    public static void runPocAssertNoCrashes(String pocName, ITestDevice device,
+            CrashUtils.Config config) throws Exception {
         AdbUtils.runCommandLine("logcat -c", device);
         AdbUtils.runPocNoOutput(pocName, device, SecurityTestCase.TIMEOUT_NONDETERMINISTIC);
-        assertNoCrashes(device, processPatternStrings);
+        assertNoCrashes(device, config);
     }
 
     /**
@@ -500,27 +513,21 @@
      */
     public static void assertNoCrashes(ITestDevice device, String... processPatternStrings)
             throws Exception {
-        assertNoCrashes(device, true, processPatternStrings);
+        assertNoCrashes(device, new CrashUtils.Config().setProcessPatterns(processPatternStrings));
     }
 
     /**
      * Dumps logcat and asserts that there are no security crashes that match the expected process
      * pattern. Ensure that adb logcat -c is called beforehand.
      * @param device device to be ran on
-     * @param checkMinAddress if the minimum fault address should be respected
-     * @param processPatternStrings a Pattern string to match the crash tombstone process
+     * @param config a crash parser configuration
      */
-    public static void assertNoCrashes(ITestDevice device, boolean checkMinAddress,
-            String... processPatternStrings) throws Exception {
+    public static void assertNoCrashes(ITestDevice device,
+            CrashUtils.Config config) throws Exception {
         String logcat = AdbUtils.runCommandLine("logcat -d *:S DEBUG:V", device);
 
-        Pattern[] processPatterns = new Pattern[processPatternStrings.length];
-        for (int i = 0; i < processPatternStrings.length; i++) {
-            processPatterns[i] = Pattern.compile(processPatternStrings[i]);
-        }
         JSONArray crashes = CrashUtils.addAllCrashes(logcat, new JSONArray());
-        JSONArray securityCrashes =
-                CrashUtils.matchSecurityCrashes(crashes, checkMinAddress, processPatterns);
+        JSONArray securityCrashes = CrashUtils.matchSecurityCrashes(crashes, config);
 
         if (securityCrashes.length() == 0) {
             return; // no security crashes detected
@@ -529,8 +536,8 @@
         StringBuilder error = new StringBuilder();
         error.append("Security crash detected:\n");
         error.append("Process patterns:");
-        for (String pattern : processPatternStrings) {
-            error.append(String.format(" '%s'", pattern));
+        for (Pattern pattern : config.getProcessPatterns()) {
+            error.append(String.format(" '%s'", pattern.toString()));
         }
         error.append("\nCrashes:\n");
         for (int i = 0; i < crashes.length(); i++) {
diff --git a/hostsidetests/securitybulletin/src/android/security/cts/Poc16_04.java b/hostsidetests/securitybulletin/src/android/security/cts/Poc16_04.java
index 25c1373..b0f0ddc 100644
--- a/hostsidetests/securitybulletin/src/android/security/cts/Poc16_04.java
+++ b/hostsidetests/securitybulletin/src/android/security/cts/Poc16_04.java
@@ -1,5 +1,5 @@
 /**
- * Copyright (C) 2018 The Android Open Source Project
+ * Copyright (C) 2020 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -16,13 +16,19 @@
 package android.security.cts;
 
 import android.platform.test.annotations.SecurityTest;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import com.android.tradefed.testtype.DeviceJUnit4ClassRunner;
 
-@SecurityTest
+import static org.junit.Assert.*;
+
+@RunWith(DeviceJUnit4ClassRunner.class)
 public class Poc16_04 extends SecurityTestCase {
 
     /**
      * b/26323455
      */
+    @Test
     @SecurityTest(minPatchLevel = "2016-04")
     public void testPocCVE_2016_2419() throws Exception {
         AdbUtils.runCommandLine("logcat -c" , getDevice());
@@ -34,6 +40,7 @@
     /**
     *  b/26324307
     */
+    @Test
     @SecurityTest(minPatchLevel = "2016-04")
     public void testPocCVE_2016_0844() throws Exception {
         AdbUtils.runPoc("CVE-2016-0844", getDevice(), 60);
@@ -42,6 +49,7 @@
     /**
      * b/26593930
      */
+    @Test
     @SecurityTest(minPatchLevel = "2016-04")
     public void testPocCVE_2016_2412() throws Exception {
         AdbUtils.runPocAssertNoCrashes("CVE-2016-2412", getDevice(), "system_server");
diff --git a/hostsidetests/securitybulletin/src/android/security/cts/Poc16_05.java b/hostsidetests/securitybulletin/src/android/security/cts/Poc16_05.java
index d8df1c6..0895607 100644
--- a/hostsidetests/securitybulletin/src/android/security/cts/Poc16_05.java
+++ b/hostsidetests/securitybulletin/src/android/security/cts/Poc16_05.java
@@ -1,5 +1,5 @@
 /**
- * Copyright (C) 2018 The Android Open Source Project
+ * Copyright (C) 2020 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -17,12 +17,18 @@
 package android.security.cts;
 
 import android.platform.test.annotations.SecurityTest;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import com.android.tradefed.testtype.DeviceJUnit4ClassRunner;
 
-@SecurityTest
+import static org.junit.Assert.*;
+
+@RunWith(DeviceJUnit4ClassRunner.class)
 public class Poc16_05 extends SecurityTestCase {
     /**
      *  b/27555981
      */
+    @Test
     @SecurityTest(minPatchLevel = "2016-05")
     public void testPocCVE_2016_2460() throws Exception {
         AdbUtils.runCommandLine("logcat -c" , getDevice());
@@ -35,6 +41,7 @@
     /**
      *  b/27275324
      */
+    @Test
     @SecurityTest(minPatchLevel = "2016-05")
     public void testPocCVE_2015_1805() throws Exception {
       AdbUtils.runPoc("CVE-2015-1805", getDevice(), TIMEOUT_NONDETERMINISTIC);
diff --git a/hostsidetests/securitybulletin/src/android/security/cts/Poc16_06.java b/hostsidetests/securitybulletin/src/android/security/cts/Poc16_06.java
index b414a55..58c604e 100644
--- a/hostsidetests/securitybulletin/src/android/security/cts/Poc16_06.java
+++ b/hostsidetests/securitybulletin/src/android/security/cts/Poc16_06.java
@@ -1,27 +1,34 @@
 /**
-* 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.
-*/
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
 
 package android.security.cts;
 
 import android.platform.test.annotations.SecurityTest;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import com.android.tradefed.testtype.DeviceJUnit4ClassRunner;
 
+import static org.junit.Assert.*;
+
+@RunWith(DeviceJUnit4ClassRunner.class)
 public class Poc16_06 extends SecurityTestCase {
     /**
      *  b/27661749
      */
+    @Test
     @SecurityTest(minPatchLevel = "2016-06")
     public void testPocCVE_2016_2482() throws Exception {
         AdbUtils.runPocAssertNoCrashes("CVE-2016-2482", getDevice(), "mediaserver");
diff --git a/hostsidetests/securitybulletin/src/android/security/cts/Poc16_07.java b/hostsidetests/securitybulletin/src/android/security/cts/Poc16_07.java
index b634645..4367a61 100644
--- a/hostsidetests/securitybulletin/src/android/security/cts/Poc16_07.java
+++ b/hostsidetests/securitybulletin/src/android/security/cts/Poc16_07.java
@@ -1,5 +1,5 @@
 /**
- * Copyright (C) 2019 The Android Open Source Project
+ * Copyright (C) 2020 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -13,15 +13,22 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
+
 package android.security.cts;
 
 import android.platform.test.annotations.SecurityTest;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import com.android.tradefed.testtype.DeviceJUnit4ClassRunner;
 
-@SecurityTest
+import static org.junit.Assert.*;
+
+@RunWith(DeviceJUnit4ClassRunner.class)
 public class Poc16_07 extends SecurityTestCase {
     /**
      *  b/28740702
      */
+    @Test
     @SecurityTest(minPatchLevel = "2016-07")
     public void testPocCVE_2016_3818() throws Exception {
         AdbUtils.runPoc("CVE-2016-3818", getDevice(), 60);
@@ -30,6 +37,7 @@
     /**
      *  b/27890802
      */
+    @Test
     @SecurityTest(minPatchLevel = "2016-07")
     public void testPocCVE_2016_3746() throws Exception {
         AdbUtils.runPocAssertNoCrashes("CVE-2016-3746", getDevice(), "mediaserver");
@@ -38,6 +46,7 @@
     /**
      *  b/28557020
      */
+    @Test
     @SecurityTest(minPatchLevel = "2016-07")
     public void testPocCVE_2014_9803() throws Exception {
         AdbUtils.runPocAssertExitStatusNotVulnerable("CVE-2014-9803", getDevice(), 60);
@@ -46,6 +55,7 @@
     /**
      * b/27903498
      */
+    @Test
     @SecurityTest(minPatchLevel = "2016-07")
     public void testPocCVE_2016_3747() throws Exception {
         getOomCatcher().setHighMemoryTest();
diff --git a/hostsidetests/securitybulletin/src/android/security/cts/Poc16_09.java b/hostsidetests/securitybulletin/src/android/security/cts/Poc16_09.java
index 3280a68..a253619 100644
--- a/hostsidetests/securitybulletin/src/android/security/cts/Poc16_09.java
+++ b/hostsidetests/securitybulletin/src/android/security/cts/Poc16_09.java
@@ -1,5 +1,5 @@
 /**
- * Copyright (C) 2017 The Android Open Source Project
+ * Copyright (C) 2020 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -13,15 +13,22 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
+
 package android.security.cts;
 
 import android.platform.test.annotations.SecurityTest;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import com.android.tradefed.testtype.DeviceJUnit4ClassRunner;
 
-@SecurityTest
+import static org.junit.Assert.*;
+
+@RunWith(DeviceJUnit4ClassRunner.class)
 public class Poc16_09 extends SecurityTestCase {
     /**
      * b/27773913
      */
+    @Test
     @SecurityTest(minPatchLevel = "2016-09")
     public void testPocCVE_2016_2471() throws Exception {
         AdbUtils.runPoc("CVE-2016-2471", getDevice(), 60);
diff --git a/hostsidetests/securitybulletin/src/android/security/cts/Poc16_10.java b/hostsidetests/securitybulletin/src/android/security/cts/Poc16_10.java
index 6daa385..d1550d2 100644
--- a/hostsidetests/securitybulletin/src/android/security/cts/Poc16_10.java
+++ b/hostsidetests/securitybulletin/src/android/security/cts/Poc16_10.java
@@ -1,5 +1,5 @@
 /**
- * Copyright (C) 2019 The Android Open Source Project
+ * Copyright (C) 2020 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -17,13 +17,19 @@
 package android.security.cts;
 
 import android.platform.test.annotations.SecurityTest;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import com.android.tradefed.testtype.DeviceJUnit4ClassRunner;
 
-@SecurityTest
+import static org.junit.Assert.*;
+
+@RunWith(DeviceJUnit4ClassRunner.class)
 public class Poc16_10 extends SecurityTestCase {
 
     /**
      *  b/30204103
      */
+    @Test
     @SecurityTest(minPatchLevel = "2016-10")
     public void testPocCVE_2016_3913() throws Exception {
         AdbUtils.runPocAssertNoCrashes("CVE-2016-3913", getDevice(), "mediaserver");
diff --git a/hostsidetests/securitybulletin/src/android/security/cts/Poc16_11.java b/hostsidetests/securitybulletin/src/android/security/cts/Poc16_11.java
index bb18b0d..60a15e6 100644
--- a/hostsidetests/securitybulletin/src/android/security/cts/Poc16_11.java
+++ b/hostsidetests/securitybulletin/src/android/security/cts/Poc16_11.java
@@ -1,5 +1,5 @@
 /**
- * Copyright (C) 2018 The Android Open Source Project
+ * Copyright (C) 2020 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -17,13 +17,19 @@
 package android.security.cts;
 
 import android.platform.test.annotations.SecurityTest;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import com.android.tradefed.testtype.DeviceJUnit4ClassRunner;
 
-@SecurityTest
+import static org.junit.Assert.*;
+
+@RunWith(DeviceJUnit4ClassRunner.class)
 public class Poc16_11 extends SecurityTestCase {
 
     /**
      *  b/29149404
      */
+    @Test
     @SecurityTest(minPatchLevel = "2016-11")
     public void testPocCVE_2012_6702() throws Exception {
         AdbUtils.runCommandLine("logcat -c", getDevice());
@@ -35,6 +41,7 @@
     /**
      *  b/30904789
      */
+    @Test
     @SecurityTest(minPatchLevel = "2016-11")
     public void testPocCVE_2016_6730() throws Exception {
         if(containsDriver(getDevice(), "/dev/dri/renderD129")) {
@@ -45,6 +52,7 @@
     /**
      *  b/30906023
      */
+    @Test
     @SecurityTest(minPatchLevel = "2016-11")
     public void testPocCVE_2016_6731() throws Exception {
         if(containsDriver(getDevice(), "/dev/dri/renderD129")) {
@@ -55,6 +63,7 @@
     /**
      *  b/30906599
      */
+    @Test
     @SecurityTest(minPatchLevel = "2016-11")
     public void testPocCVE_2016_6732() throws Exception {
         if(containsDriver(getDevice(), "/dev/dri/renderD129")) {
@@ -65,6 +74,7 @@
     /**
      *  b/30906694
      */
+    @Test
     @SecurityTest(minPatchLevel = "2016-11")
     public void testPocCVE_2016_6733() throws Exception {
         if(containsDriver(getDevice(), "/dev/dri/renderD129")) {
@@ -75,6 +85,7 @@
     /**
      *  b/30907120
      */
+    @Test
     @SecurityTest(minPatchLevel = "2016-11")
     public void testPocCVE_2016_6734() throws Exception {
         if(containsDriver(getDevice(), "/dev/dri/renderD129")) {
@@ -85,6 +96,7 @@
     /**
      *  b/30907701
      */
+    @Test
     @SecurityTest(minPatchLevel = "2016-11")
     public void testPocCVE_2016_6735() throws Exception {
         if(containsDriver(getDevice(), "/dev/dri/renderD129")) {
@@ -95,6 +107,7 @@
     /**
      *  b/30953284
      */
+    @Test
     @SecurityTest(minPatchLevel = "2016-11")
     public void testPocCVE_2016_6736() throws Exception {
         if(containsDriver(getDevice(), "/dev/dri/renderD129")) {
diff --git a/hostsidetests/securitybulletin/src/android/security/cts/Poc16_12.java b/hostsidetests/securitybulletin/src/android/security/cts/Poc16_12.java
index 65a6931..4e2031b 100644
--- a/hostsidetests/securitybulletin/src/android/security/cts/Poc16_12.java
+++ b/hostsidetests/securitybulletin/src/android/security/cts/Poc16_12.java
@@ -1,5 +1,5 @@
 /**
- * Copyright (C) 2016 The Android Open Source Project
+ * Copyright (C) 2020 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -17,14 +17,20 @@
 package android.security.cts;
 
 import android.platform.test.annotations.SecurityTest;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import com.android.tradefed.testtype.DeviceJUnit4ClassRunner;
 
-@SecurityTest
+import static org.junit.Assert.*;
+
+@RunWith(DeviceJUnit4ClassRunner.class)
 public class Poc16_12 extends SecurityTestCase {
 
     //Criticals
     /**
      *  b/31796940
      */
+    @Test
     @SecurityTest(minPatchLevel = "2016-12")
     public void testPocCVE_2016_8406() throws Exception {
         assertNotKernelPointer(() -> {
diff --git a/hostsidetests/securitybulletin/src/android/security/cts/Poc17_01.java b/hostsidetests/securitybulletin/src/android/security/cts/Poc17_01.java
index 107ac45..a7ae370 100644
--- a/hostsidetests/securitybulletin/src/android/security/cts/Poc17_01.java
+++ b/hostsidetests/securitybulletin/src/android/security/cts/Poc17_01.java
@@ -1,5 +1,5 @@
 /**
- * Copyright (C) 2016 The Android Open Source Project
+ * Copyright (C) 2020 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -17,14 +17,20 @@
 package android.security.cts;
 
 import android.platform.test.annotations.SecurityTest;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import com.android.tradefed.testtype.DeviceJUnit4ClassRunner;
 
-@SecurityTest
+import static org.junit.Assert.*;
+
+@RunWith(DeviceJUnit4ClassRunner.class)
 public class Poc17_01 extends SecurityTestCase {
 
     //Criticals
     /**
      *  b/31797770
      */
+    @Test
     @SecurityTest(minPatchLevel = "2017-01")
     public void testPocCVE_2016_8425() throws Exception {
         if(containsDriver(getDevice(), "/dev/nvhost-vic")) {
@@ -35,6 +41,7 @@
     /**
      *  b/31799206
      */
+    @Test
     @SecurityTest(minPatchLevel = "2017-01")
     public void testPocCVE_2016_8426() throws Exception {
         if(containsDriver(getDevice(), "/dev/nvhost-gpu")) {
@@ -45,6 +52,7 @@
     /**
      *  b/31799885
      */
+    @Test
     @SecurityTest(minPatchLevel = "2017-01")
     public void testPocCVE_2016_8427() throws Exception {
         if(containsDriver(getDevice(), "/dev/nvhost-gpu") ||
@@ -56,6 +64,7 @@
     /**
      *  b/31993456
      */
+    @Test
     @SecurityTest(minPatchLevel = "2017-01")
     public void testPocCVE_2016_8428() throws Exception {
         if(containsDriver(getDevice(), "/dev/nvmap")) {
@@ -66,6 +75,7 @@
     /**
      *  b/32160775
      */
+    @Test
     @SecurityTest(minPatchLevel = "2017-01")
     public void testPocCVE_2016_8429() throws Exception {
         if(containsDriver(getDevice(), "/dev/nvmap")) {
@@ -76,6 +86,7 @@
     /**
      *  b/32225180
      */
+    @Test
     @SecurityTest(minPatchLevel = "2017-01")
     public void testPocCVE_2016_8430() throws Exception {
         if(containsDriver(getDevice(), "/dev/nvhost-vic")) {
@@ -86,6 +97,7 @@
    /**
      *  b/32402179
      */
+    @Test
     @SecurityTest(minPatchLevel = "2017-01")
     public void testPocCVE_2016_8431() throws Exception {
         if(containsDriver(getDevice(), "/dev/dri/renderD129")) {
@@ -96,6 +108,7 @@
     /**
      *  b/32447738
      */
+    @Test
     @SecurityTest(minPatchLevel = "2017-01")
     public void testPocCVE_2016_8432() throws Exception {
         if(containsDriver(getDevice(), "/dev/dri/renderD129")) {
@@ -106,6 +119,7 @@
     /**
      *  b/32125137
      */
+    @Test
     @SecurityTest(minPatchLevel = "2017-01")
     public void testPocCVE_2016_8434() throws Exception {
         if(containsDriver(getDevice(), "/dev/kgsl-3d0")) {
@@ -117,6 +131,7 @@
     /**
      *  b/31668540
      */
+    @Test
     @SecurityTest(minPatchLevel = "2017-01")
     public void testPocCVE_2016_8460() throws Exception {
         if(containsDriver(getDevice(), "/dev/nvmap")) {
@@ -128,6 +143,7 @@
     /**
      *  b/32255299
      */
+    @Test
     @SecurityTest(minPatchLevel = "2017-01")
     public void testPocCVE_2017_0386() throws Exception {
         AdbUtils.runPocAssertExitStatusNotVulnerable("CVE-2017-0386", getDevice(), 60);
diff --git a/hostsidetests/securitybulletin/src/android/security/cts/Poc17_02.java b/hostsidetests/securitybulletin/src/android/security/cts/Poc17_02.java
index f9d4e1d..3f94a62 100644
--- a/hostsidetests/securitybulletin/src/android/security/cts/Poc17_02.java
+++ b/hostsidetests/securitybulletin/src/android/security/cts/Poc17_02.java
@@ -1,5 +1,5 @@
 /**
- * Copyright (C) 2018 The Android Open Source Project
+ * Copyright (C) 2020 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -17,30 +17,39 @@
 package android.security.cts;
 
 import android.platform.test.annotations.SecurityTest;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import com.android.tradefed.testtype.DeviceJUnit4ClassRunner;
 
+import static org.junit.Assert.*;
+
+@RunWith(DeviceJUnit4ClassRunner.class)
 public class Poc17_02 extends SecurityTestCase {
-  /**
-   *  b/32799236
-   */
-  @SecurityTest(minPatchLevel = "2017-02")
-  public void testPocCVE_2017_0426() throws Exception {
-      AdbUtils.runCommandLine("logcat -c", getDevice());
-      AdbUtils.runPoc("CVE-2017-0426", getDevice(), 60);
-      String logcatOut = AdbUtils.runCommandLine("logcat -d", getDevice());
-      assertNotMatchesMultiLine("Bugreports file in wrong path", logcatOut);
-  }
+    /**
+     *  b/32799236
+     */
+    @Test
+    @SecurityTest(minPatchLevel = "2017-02")
+    public void testPocCVE_2017_0426() throws Exception {
+        AdbUtils.runCommandLine("logcat -c", getDevice());
+        AdbUtils.runPoc("CVE-2017-0426", getDevice(), 60);
+        String logcatOut = AdbUtils.runCommandLine("logcat -d", getDevice());
+        assertNotMatchesMultiLine("Bugreports file in wrong path", logcatOut);
+    }
 
-   /**
-   *  b/32706020
-   */
-  @SecurityTest(minPatchLevel = "2017-02")
-  public void testPocCVE_2017_0415() throws Exception {
-      AdbUtils.runPocAssertNoCrashes("CVE-2017-0415", getDevice(), "mediaserver");
-  }
+    /**
+     *  b/32706020
+     */
+    @Test
+    @SecurityTest(minPatchLevel = "2017-02")
+    public void testPocCVE_2017_0415() throws Exception {
+        AdbUtils.runPocAssertNoCrashes("CVE-2017-0415", getDevice(), "mediaserver");
+    }
 
     /**
      *  b/31799863
      */
+    @Test
     @SecurityTest(minPatchLevel = "2017-02")
     public void testPocCVE_2016_8482() throws Exception {
         if(containsDriver(getDevice(), "/dev/nvmap")) {
diff --git a/hostsidetests/securitybulletin/src/android/security/cts/Poc17_03.java b/hostsidetests/securitybulletin/src/android/security/cts/Poc17_03.java
index f61e843..3dacc96 100644
--- a/hostsidetests/securitybulletin/src/android/security/cts/Poc17_03.java
+++ b/hostsidetests/securitybulletin/src/android/security/cts/Poc17_03.java
@@ -1,5 +1,5 @@
 /**
- * Copyright (C) 2017 The Android Open Source Project
+ * Copyright (C) 2020 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -16,14 +16,22 @@
 
 package android.security.cts;
 
-import android.platform.test.annotations.SecurityTest;
 import java.util.concurrent.Callable;
 
+import android.platform.test.annotations.SecurityTest;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import com.android.tradefed.testtype.DeviceJUnit4ClassRunner;
+
+import static org.junit.Assert.*;
+
+@RunWith(DeviceJUnit4ClassRunner.class)
 public class Poc17_03 extends SecurityTestCase {
 
     /**
      *  b/31824853
      */
+    @Test
     @SecurityTest(minPatchLevel = "2017-03")
     public void testPocCVE_2016_8479() throws Exception {
         if (containsDriver(getDevice(), "/dev/kgsl-3d0")) {
@@ -37,6 +45,7 @@
     /**
      *  b/33940449
      */
+    @Test
     @SecurityTest(minPatchLevel = "2017-03")
     public void testPocCVE_2017_0508() throws Exception {
         if (containsDriver(getDevice(), "/dev/ion") &&
@@ -51,6 +60,7 @@
     /**
      *  b/33899363
      */
+    @Test
     @SecurityTest(minPatchLevel = "2017-03")
     public void testPocCVE_2017_0333() throws Exception {
         if (containsDriver(getDevice(), "/dev/dri/renderD128")) {
@@ -63,6 +73,7 @@
     /**
      *  b/33245849
      */
+    @Test
     @SecurityTest(minPatchLevel = "2017-03")
     public void testPocCVE_2017_0334() throws Exception {
         if (containsDriver(getDevice(), "/dev/dri/renderD129")) {
@@ -92,6 +103,7 @@
     /**
      * b/32707507
      */
+    @Test
     @SecurityTest(minPatchLevel = "2017-03")
     public void testPocCVE_2017_0479() throws Exception {
         AdbUtils.runPocAssertNoCrashes("CVE-2017-0479", getDevice(), "audioserver");
@@ -100,6 +112,7 @@
     /*
      *  b/33178389
      */
+    @Test
     @SecurityTest(minPatchLevel = "2017-03")
     public void testPocCVE_2017_0490() throws Exception {
         String bootCountBefore =
diff --git a/hostsidetests/securitybulletin/src/android/security/cts/Poc17_04.java b/hostsidetests/securitybulletin/src/android/security/cts/Poc17_04.java
index 248e257..f5c8fe3 100644
--- a/hostsidetests/securitybulletin/src/android/security/cts/Poc17_04.java
+++ b/hostsidetests/securitybulletin/src/android/security/cts/Poc17_04.java
@@ -1,5 +1,5 @@
 /**
- * Copyright (C) 2016 The Android Open Source Project
+ * Copyright (C) 2020 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -17,42 +17,51 @@
 package android.security.cts;
 
 import android.platform.test.annotations.SecurityTest;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import com.android.tradefed.testtype.DeviceJUnit4ClassRunner;
 
-@SecurityTest
+import static org.junit.Assert.*;
+
+@RunWith(DeviceJUnit4ClassRunner.class)
 public class Poc17_04 extends SecurityTestCase {
 
-  /**
-   * b/32342065
-   */
-  @SecurityTest(minPatchLevel = "2017-04")
-  public void testPocCVE_2017_0553() throws Exception {
-    // Error code of 139 represents segmentation fault
-    getDevice().executeShellCommand("chmod +x /data/local/tmp/CVE-2017-0553");
-    assertFalse("Segfault found",
-        AdbUtils.runCommandGetExitCode("/data/local/tmp/CVE-2017-0553", getDevice())==139);
-  }
+    /**
+     * b/32342065
+     */
+    @Test
+    @SecurityTest(minPatchLevel = "2017-04")
+    public void testPocCVE_2017_0553() throws Exception {
+      // Error code of 139 represents segmentation fault
+      getDevice().executeShellCommand("chmod +x /data/local/tmp/CVE-2017-0553");
+      assertFalse("Segfault found",
+          AdbUtils.runCommandGetExitCode("/data/local/tmp/CVE-2017-0553", getDevice())==139);
+    }
 
-  /**
-   * b/72460737
-   */
-  @SecurityTest(minPatchLevel = "2017-04")
-  public void testPocCVE_2014_3145() throws Exception {
-    assertFalse("VULNERABLE DEVICE DETECTED",
-                AdbUtils.runPocCheckExitCode("CVE-2014-3145", getDevice(), 60));
-  }
+    /**
+     * b/72460737
+     */
+    @Test
+    @SecurityTest(minPatchLevel = "2017-04")
+    public void testPocCVE_2014_3145() throws Exception {
+      assertFalse("VULNERABLE DEVICE DETECTED",
+                  AdbUtils.runPocCheckExitCode("CVE-2014-3145", getDevice(), 60));
+    }
 
-  /**
-   * b/32813456
-   */
-  @SecurityTest(minPatchLevel = "2017-04")
-  public void testPocCVE_2016_10229() throws Exception {
-    String out = AdbUtils.runPoc("CVE-2016-10229", getDevice());
-    assertNotMatchesMultiLine("OVERWRITE", out);
-  }
+    /**
+     * b/32813456
+     */
+    @Test
+    @SecurityTest(minPatchLevel = "2017-04")
+    public void testPocCVE_2016_10229() throws Exception {
+      String out = AdbUtils.runPoc("CVE-2016-10229", getDevice());
+      assertNotMatchesMultiLine("OVERWRITE", out);
+    }
 
     /**
      * b/33621647
      */
+    @Test
     @SecurityTest(minPatchLevel = "2017-04")
     public void testPocCVE_2017_0477() throws Exception {
         AdbUtils.pushResource("/CVE-2017-0477.gif", "/data/local/tmp/CVE-2017-0477.gif",
diff --git a/hostsidetests/securitybulletin/src/android/security/cts/Poc17_05.java b/hostsidetests/securitybulletin/src/android/security/cts/Poc17_05.java
index 70e224a..1ec6d89 100644
--- a/hostsidetests/securitybulletin/src/android/security/cts/Poc17_05.java
+++ b/hostsidetests/securitybulletin/src/android/security/cts/Poc17_05.java
@@ -1,5 +1,5 @@
 /**
- * Copyright (C) 2018 The Android Open Source Project
+ * Copyright (C) 2020 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -16,16 +16,23 @@
 
 package android.security.cts;
 
-import android.platform.test.annotations.SecurityTest;
 import java.util.Arrays;
 import java.util.concurrent.Callable;
 
-@SecurityTest
+import android.platform.test.annotations.SecurityTest;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import com.android.tradefed.testtype.DeviceJUnit4ClassRunner;
+
+import static org.junit.Assert.*;
+
+@RunWith(DeviceJUnit4ClassRunner.class)
 public class Poc17_05 extends SecurityTestCase {
 
     /**
      *  b/34277115
      */
+    @Test
     @SecurityTest(minPatchLevel = "2017-05")
     public void testPocCVE_2017_0630() throws Exception {
         if (containsDriver(getDevice(), "/sys/kernel/debug/tracing/printk_formats")) {
@@ -54,6 +61,7 @@
     /*
      * CVE-2016-5862
      */
+    @Test
     @SecurityTest(minPatchLevel = "2017-05")
     public void testPocCVE_2016_5862() throws Exception {
         if (containsDriver(getDevice(), "/dev/snd/controlC0")) {
@@ -64,6 +72,7 @@
     /**
      * CVE-2016-5867
      */
+    @Test
     @SecurityTest(minPatchLevel = "2017-05")
     public void testPocCVE_2016_5867() throws Exception {
         if (containsDriver(getDevice(), "/dev/snd/controlC0")) {
diff --git a/hostsidetests/securitybulletin/src/android/security/cts/Poc17_06.java b/hostsidetests/securitybulletin/src/android/security/cts/Poc17_06.java
index c2c3e29..1f7e5e9 100644
--- a/hostsidetests/securitybulletin/src/android/security/cts/Poc17_06.java
+++ b/hostsidetests/securitybulletin/src/android/security/cts/Poc17_06.java
@@ -1,5 +1,5 @@
 /**
- * Copyright (C) 2018 The Android Open Source Project
+ * Copyright (C) 2020 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -17,14 +17,19 @@
 package android.security.cts;
 
 import android.platform.test.annotations.SecurityTest;
-import java.util.concurrent.TimeUnit;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import com.android.tradefed.testtype.DeviceJUnit4ClassRunner;
 
-@SecurityTest
+import static org.junit.Assert.*;
+
+@RunWith(DeviceJUnit4ClassRunner.class)
 public class Poc17_06 extends SecurityTestCase {
 
     /**
      * b/36392138
      */
+    @Test
     @SecurityTest(minPatchLevel = "2017-06")
     public void testPocCVE_2017_0647() throws Exception {
         AdbUtils.pushResource("/CVE-2017-0647.zip", "/data/local/tmp/CVE-2017-0647.zip",
diff --git a/hostsidetests/securitybulletin/src/android/security/cts/Poc17_07.java b/hostsidetests/securitybulletin/src/android/security/cts/Poc17_07.java
index 29b7a39..d3a086a 100644
--- a/hostsidetests/securitybulletin/src/android/security/cts/Poc17_07.java
+++ b/hostsidetests/securitybulletin/src/android/security/cts/Poc17_07.java
@@ -1,5 +1,5 @@
 /**
- * Copyright (C) 2017 The Android Open Source Project
+ * Copyright (C) 2020 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -17,13 +17,19 @@
 package android.security.cts;
 
 import android.platform.test.annotations.SecurityTest;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import com.android.tradefed.testtype.DeviceJUnit4ClassRunner;
 
-@SecurityTest
+import static org.junit.Assert.*;
+
+@RunWith(DeviceJUnit4ClassRunner.class)
 public class Poc17_07 extends SecurityTestCase {
 
     /**
      * b/35443725
      **/
+    @Test
     @SecurityTest(minPatchLevel = "2017-07")
     public void testPocCVE_2016_2109() throws Exception {
       assertFalse("Overallocation detected!",
diff --git a/hostsidetests/securitybulletin/src/android/security/cts/Poc17_09.java b/hostsidetests/securitybulletin/src/android/security/cts/Poc17_09.java
index 1659397..de7381e 100644
--- a/hostsidetests/securitybulletin/src/android/security/cts/Poc17_09.java
+++ b/hostsidetests/securitybulletin/src/android/security/cts/Poc17_09.java
@@ -1,5 +1,5 @@
 /**
- * Copyright (C) 2016 The Android Open Source Project
+ * Copyright (C) 2020 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -17,13 +17,19 @@
 package android.security.cts;
 
 import android.platform.test.annotations.SecurityTest;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import com.android.tradefed.testtype.DeviceJUnit4ClassRunner;
 
-@SecurityTest
+import static org.junit.Assert.*;
+
+@RunWith(DeviceJUnit4ClassRunner.class)
 public class Poc17_09 extends SecurityTestCase {
 
     /**
      * b/63852675
      */
+    @Test
     @SecurityTest(minPatchLevel = "2017-09")
     public void testPocCve_2017_6983() throws Exception {
       // Error code of 139 represents segmentation fault
@@ -53,14 +59,15 @@
                                       )==139);
     }
 
-  /**
-   * b/38195738
-   * b/36590192
-   */
-  @SecurityTest(minPatchLevel = "2017-09")
-  public void testPocBug_38195738() throws Exception {
-    if(containsDriver(getDevice(), "/dev/kgsl-3d0")) {
-      AdbUtils.runPocNoOutput("Bug-38195738", getDevice(), 60);
+    /**
+     * b/38195738
+     * b/36590192
+     */
+    @Test
+    @SecurityTest(minPatchLevel = "2017-09")
+    public void testPocBug_38195738() throws Exception {
+        if(containsDriver(getDevice(), "/dev/kgsl-3d0")) {
+            AdbUtils.runPocNoOutput("Bug-38195738", getDevice(), 60);
+        }
     }
-  }
 }
diff --git a/hostsidetests/securitybulletin/src/android/security/cts/Poc17_11.java b/hostsidetests/securitybulletin/src/android/security/cts/Poc17_11.java
index 3fbf3d2..e592d0f 100644
--- a/hostsidetests/securitybulletin/src/android/security/cts/Poc17_11.java
+++ b/hostsidetests/securitybulletin/src/android/security/cts/Poc17_11.java
@@ -1,5 +1,5 @@
 /**
- * Copyright (C) 2017 The Android Open Source Project
+ * Copyright (C) 2020 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -17,13 +17,19 @@
 package android.security.cts;
 
 import android.platform.test.annotations.SecurityTest;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import com.android.tradefed.testtype.DeviceJUnit4ClassRunner;
 
-@SecurityTest
+import static org.junit.Assert.*;
+
+@RunWith(DeviceJUnit4ClassRunner.class)
 public class Poc17_11 extends SecurityTestCase {
 
     /**
      * b/36075131
      */
+    @Test
     @SecurityTest(minPatchLevel = "2017-11")
     public void testPocCVE_2017_0859() throws Exception {
         AdbUtils.runCommandLine("logcat -c", getDevice());
diff --git a/hostsidetests/securitybulletin/src/android/security/cts/Poc17_12.java b/hostsidetests/securitybulletin/src/android/security/cts/Poc17_12.java
index fed0ab5..71607c8 100644
--- a/hostsidetests/securitybulletin/src/android/security/cts/Poc17_12.java
+++ b/hostsidetests/securitybulletin/src/android/security/cts/Poc17_12.java
@@ -1,5 +1,5 @@
 /**
- * Copyright (C) 2018 The Android Open Source Project
+ * Copyright (C) 2020 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -17,13 +17,19 @@
 package android.security.cts;
 
 import android.platform.test.annotations.SecurityTest;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import com.android.tradefed.testtype.DeviceJUnit4ClassRunner;
 
-@SecurityTest
+import static org.junit.Assert.*;
+
+@RunWith(DeviceJUnit4ClassRunner.class)
 public class Poc17_12 extends SecurityTestCase {
 
     /**
      * b/38045794
      */
+    @Test
     @SecurityTest(minPatchLevel = "2017-12")
     public void testPocCVE_2017_6262() throws Exception {
         if(containsDriver(getDevice(),"/dev/dri/renderD128")) {
diff --git a/hostsidetests/securitybulletin/src/android/security/cts/Poc18_02.java b/hostsidetests/securitybulletin/src/android/security/cts/Poc18_02.java
index c9f48f9..377e219 100644
--- a/hostsidetests/securitybulletin/src/android/security/cts/Poc18_02.java
+++ b/hostsidetests/securitybulletin/src/android/security/cts/Poc18_02.java
@@ -1,5 +1,5 @@
 /**
- * Copyright (C) 2016 The Android Open Source Project
+ * Copyright (C) 2020 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -17,26 +17,33 @@
 package android.security.cts;
 
 import android.platform.test.annotations.SecurityTest;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import com.android.tradefed.testtype.DeviceJUnit4ClassRunner;
 
-@SecurityTest
+import static org.junit.Assert.*;
+
+@RunWith(DeviceJUnit4ClassRunner.class)
 public class Poc18_02 extends SecurityTestCase {
 
     /**
      * b/68953950
      */
-     @SecurityTest(minPatchLevel = "2018-02")
-     public void testPocCVE_2017_13232() throws Exception {
-       AdbUtils.runCommandLine("logcat -c" , getDevice());
-       AdbUtils.runPocNoOutput("CVE-2017-13232", getDevice(), 60);
-       String logcatOutput = AdbUtils.runCommandLine("logcat -d", getDevice());
-       assertNotMatchesMultiLine("APM_AudioPolicyManager: getOutputForAttr\\(\\) " +
-                                 "invalid attributes: usage=.{1,15} content=.{1,15} " +
-                                 "flags=.{1,15} tags=\\[A{256,}\\]", logcatOutput);
-     }
+    @Test
+    @SecurityTest(minPatchLevel = "2018-02")
+    public void testPocCVE_2017_13232() throws Exception {
+        AdbUtils.runCommandLine("logcat -c" , getDevice());
+        AdbUtils.runPocNoOutput("CVE-2017-13232", getDevice(), 60);
+        String logcatOutput = AdbUtils.runCommandLine("logcat -d", getDevice());
+        assertNotMatchesMultiLine("APM_AudioPolicyManager: getOutputForAttr\\(\\) " +
+                                  "invalid attributes: usage=.{1,15} content=.{1,15} " +
+                                  "flags=.{1,15} tags=\\[A{256,}\\]", logcatOutput);
+    }
 
     /**
      *  b/65853158
      */
+    @Test
     @SecurityTest(minPatchLevel = "2018-02")
     public void testPocCVE_2017_13273() throws Exception {
         AdbUtils.runCommandLine("dmesg -c" ,getDevice());
diff --git a/hostsidetests/securitybulletin/src/android/security/cts/Poc18_03.java b/hostsidetests/securitybulletin/src/android/security/cts/Poc18_03.java
index f916d7e..d5e2b90 100644
--- a/hostsidetests/securitybulletin/src/android/security/cts/Poc18_03.java
+++ b/hostsidetests/securitybulletin/src/android/security/cts/Poc18_03.java
@@ -1,5 +1,5 @@
 /**
- * Copyright (C) 2019 The Android Open Source Project
+ * Copyright (C) 2020 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -17,14 +17,21 @@
 package android.security.cts;
 
 import android.platform.test.annotations.SecurityTest;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import com.android.tradefed.testtype.DeviceJUnit4ClassRunner;
 
+import static org.junit.Assert.*;
+
+@RunWith(DeviceJUnit4ClassRunner.class)
 public class Poc18_03 extends SecurityTestCase {
 
-  /**
-   * CVE-2017-13253
-   */
-  @SecurityTest(minPatchLevel = "2018-03")
-  public void testPocCVE_2017_13253() throws Exception {
-    AdbUtils.runPocAssertExitStatusNotVulnerable("CVE-2017-13253", getDevice(), 300);
-  }
+    /**
+     * b/71389378
+     */
+    @Test
+    @SecurityTest(minPatchLevel = "2018-03")
+    public void testPocCVE_2017_13253() throws Exception {
+        AdbUtils.runPocAssertExitStatusNotVulnerable("CVE-2017-13253", getDevice(), 300);
+    }
 }
diff --git a/hostsidetests/securitybulletin/src/android/security/cts/Poc18_04.java b/hostsidetests/securitybulletin/src/android/security/cts/Poc18_04.java
index 99a4692..44b0d89 100644
--- a/hostsidetests/securitybulletin/src/android/security/cts/Poc18_04.java
+++ b/hostsidetests/securitybulletin/src/android/security/cts/Poc18_04.java
@@ -1,5 +1,5 @@
 /**
- * Copyright (C) 2018 The Android Open Source Project
+ * Copyright (C) 2020 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -17,14 +17,20 @@
 package android.security.cts;
 
 import android.platform.test.annotations.SecurityTest;
+import org.junit.Test;
 import org.junit.runner.RunWith;
+import com.android.tradefed.testtype.DeviceJUnit4ClassRunner;
 
+import static org.junit.Assert.*;
+
+@RunWith(DeviceJUnit4ClassRunner.class)
 public class Poc18_04 extends SecurityTestCase {
     /**
      * b/69683251
      * Does not require root but must be a hostside test to avoid
      * a race condition
      */
+    @Test
     @SecurityTest(minPatchLevel = "2018-04")
     public void testPocCVE_2017_13286() throws Exception {
         getOomCatcher().setHighMemoryTest();
@@ -35,6 +41,7 @@
      * b/69634768
      * Does not require root but must be a hostside test to avoid a race condition
      */
+    @Test
     @SecurityTest(minPatchLevel = "2018-04")
     public void testPocCVE_2017_13288() throws Exception {
         getOomCatcher().setHighMemoryTest();
@@ -45,6 +52,7 @@
      * b/70398564
      * Does not require root but must be a hostside test to avoid a race condition
      */
+    @Test
     @SecurityTest(minPatchLevel = "2018-04")
     public void testPocCVE_2017_13289() throws Exception {
         getOomCatcher().setHighMemoryTest();
diff --git a/hostsidetests/securitybulletin/src/android/security/cts/Poc18_05.java b/hostsidetests/securitybulletin/src/android/security/cts/Poc18_05.java
index 69a4ed5..6b51f0a 100644
--- a/hostsidetests/securitybulletin/src/android/security/cts/Poc18_05.java
+++ b/hostsidetests/securitybulletin/src/android/security/cts/Poc18_05.java
@@ -1,5 +1,5 @@
 /**
- * Copyright (C) 2018 The Android Open Source Project
+ * Copyright (C) 2020 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -17,14 +17,20 @@
 package android.security.cts;
 
 import android.platform.test.annotations.SecurityTest;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import com.android.tradefed.testtype.DeviceJUnit4ClassRunner;
 
-@SecurityTest
+import static org.junit.Assert.*;
+
+@RunWith(DeviceJUnit4ClassRunner.class)
 public class Poc18_05 extends SecurityTestCase {
     /**
      * b/70721937
      * Does not require root but must be a hostside test to avoid a race
      * condition
      */
+    @Test
     @SecurityTest(minPatchLevel = "2018-05")
     public void testPocCVE_2017_13315() throws Exception {
         getOomCatcher().setHighMemoryTest();
@@ -35,6 +41,7 @@
      * b/73085795
      * Does not require root but must be a hostside test to avoid a race condition
      */
+    @Test
     @SecurityTest(minPatchLevel = "2018-05")
     public void testPocCVE_2017_13312() throws Exception {
         getOomCatcher().setHighMemoryTest();
diff --git a/hostsidetests/securitybulletin/src/android/security/cts/Poc18_06.java b/hostsidetests/securitybulletin/src/android/security/cts/Poc18_06.java
index b270c69..c0aab3b 100644
--- a/hostsidetests/securitybulletin/src/android/security/cts/Poc18_06.java
+++ b/hostsidetests/securitybulletin/src/android/security/cts/Poc18_06.java
@@ -1,5 +1,5 @@
 /**
- * Copyright (C) 2019 The Android Open Source Project
+ * Copyright (C) 2020 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -17,31 +17,38 @@
 package android.security.cts;
 
 import android.platform.test.annotations.SecurityTest;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import com.android.tradefed.testtype.DeviceJUnit4ClassRunner;
 
-@SecurityTest
+import static org.junit.Assert.*;
+
+@RunWith(DeviceJUnit4ClassRunner.class)
 public class Poc18_06 extends SecurityTestCase {
 
-  /**
-   * CVE-2018-5884
-   */
-  @SecurityTest(minPatchLevel = "2018-06")
-  public void testPocCVE_2018_5884() throws Exception {
-    String wfd_service = AdbUtils.runCommandLine(
-        "pm list package com.qualcomm.wfd.service", getDevice());
-    if (wfd_service.contains("com.qualcomm.wfd.service")) {
-      String result = AdbUtils.runCommandLine(
-          "am broadcast -a qualcomm.intent.action.WIFI_DISPLAY_BITRATE --ei format 3 --ei value 32",
-          getDevice());
-      assertNotMatchesMultiLine("Broadcast completed", result);
+    /**
+     * CVE-2018-5884
+     */
+    @Test
+    @SecurityTest(minPatchLevel = "2018-06")
+    public void testPocCVE_2018_5884() throws Exception {
+        String wfd_service = AdbUtils.runCommandLine(
+                "pm list package com.qualcomm.wfd.service", getDevice());
+        if (wfd_service.contains("com.qualcomm.wfd.service")) {
+            String result = AdbUtils.runCommandLine(
+                    "am broadcast -a qualcomm.intent.action.WIFI_DISPLAY_BITRATE --ei format 3 --ei value 32",
+            getDevice());
+            assertNotMatchesMultiLine("Broadcast completed", result);
+        }
     }
-  }
 
-  /**
-   *  b/73172817
-   */
-  @SecurityTest
-  public void testPocCVE_2018_9344() throws Exception {
-      AdbUtils.runPocAssertNoCrashes(
-          "CVE-2018-9344", getDevice(), "android\\.hardware\\.drm@\\d\\.\\d-service");
-  }
+    /**
+     *  b/73172817
+     */
+    @Test
+    @SecurityTest
+    public void testPocCVE_2018_9344() throws Exception {
+        AdbUtils.runPocAssertNoCrashes("CVE-2018-9344", getDevice(),
+                "android\\.hardware\\.cas@\\d+?\\.\\d+?-service");
+    }
 }
diff --git a/hostsidetests/securitybulletin/src/android/security/cts/Poc18_07.java b/hostsidetests/securitybulletin/src/android/security/cts/Poc18_07.java
index 173508c..172f0fc 100644
--- a/hostsidetests/securitybulletin/src/android/security/cts/Poc18_07.java
+++ b/hostsidetests/securitybulletin/src/android/security/cts/Poc18_07.java
@@ -1,5 +1,5 @@
 /**
- * Copyright (C) 2018 The Android Open Source Project
+ * Copyright (C) 2020 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -14,17 +14,22 @@
  * limitations under the License.
  */
 
-
 package android.security.cts;
 
 import android.platform.test.annotations.SecurityTest;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import com.android.tradefed.testtype.DeviceJUnit4ClassRunner;
 
-@SecurityTest
+import static org.junit.Assert.*;
+
+@RunWith(DeviceJUnit4ClassRunner.class)
 public class Poc18_07 extends SecurityTestCase {
 
    /**
     * b/76221123
     */
+    @Test
     @SecurityTest(minPatchLevel = "2018-07")
     public void testPocCVE_2018_9424() throws Exception {
         AdbUtils.runPocAssertNoCrashes(
diff --git a/hostsidetests/securitybulletin/src/android/security/cts/Poc18_10.java b/hostsidetests/securitybulletin/src/android/security/cts/Poc18_10.java
index dfc3de0..ef5b726 100644
--- a/hostsidetests/securitybulletin/src/android/security/cts/Poc18_10.java
+++ b/hostsidetests/securitybulletin/src/android/security/cts/Poc18_10.java
@@ -1,5 +1,5 @@
 /**
- * Copyright (C) 2018 The Android Open Source Project
+ * Copyright (C) 2020 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -17,13 +17,19 @@
 package android.security.cts;
 
 import android.platform.test.annotations.SecurityTest;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import com.android.tradefed.testtype.DeviceJUnit4ClassRunner;
 
-@SecurityTest
+import static org.junit.Assert.*;
+
+@RunWith(DeviceJUnit4ClassRunner.class)
 public class Poc18_10 extends SecurityTestCase {
 
     /**
      *  b/111641492
      */
+    @Test
     @SecurityTest(minPatchLevel = "2018-10")
     public void testPocCVE_2018_9515() throws Exception {
         AdbUtils.runCommandLine("rm /sdcard/Android/data/CVE-2018-9515", getDevice());
@@ -40,6 +46,7 @@
     /**
      *  b/111274046
      */
+    @Test
     @SecurityTest
     public void testPocCVE_2018_9490() throws Exception {
         int code = AdbUtils.runProxyAutoConfig("CVE-2018-9490", getDevice());
diff --git a/hostsidetests/securitybulletin/src/android/security/cts/Poc18_11.java b/hostsidetests/securitybulletin/src/android/security/cts/Poc18_11.java
index 81911ed..9699b17 100644
--- a/hostsidetests/securitybulletin/src/android/security/cts/Poc18_11.java
+++ b/hostsidetests/securitybulletin/src/android/security/cts/Poc18_11.java
@@ -1,5 +1,5 @@
 /**
- * Copyright (C) 2018 The Android Open Source Project
+ * Copyright (C) 2020 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -17,15 +17,19 @@
 package android.security.cts;
 
 import android.platform.test.annotations.SecurityTest;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import com.android.tradefed.testtype.DeviceJUnit4ClassRunner;
 
 import static org.junit.Assert.*;
 
-@SecurityTest
+@RunWith(DeviceJUnit4ClassRunner.class)
 public class Poc18_11 extends SecurityTestCase {
 
     /**
      *  b/111330641
      */
+    @Test
     @SecurityTest(minPatchLevel = "2018-11")
     public void testPocCVE_2018_9525() throws Exception {
         assertTrue(AdbUtils.runCommandGetExitCode(
@@ -35,6 +39,7 @@
     /**
      *  b/113027383
      */
+    @Test
     @SecurityTest(minPatchLevel = "2018-11")
     public void testPocCVE_2018_9539() throws Exception {
         AdbUtils.runPocAssertExitStatusNotVulnerable("CVE-2018-9539", getDevice(), 300);
diff --git a/hostsidetests/securitybulletin/src/android/security/cts/Poc19_03.java b/hostsidetests/securitybulletin/src/android/security/cts/Poc19_03.java
index 520c9fc..5977b4a 100644
--- a/hostsidetests/securitybulletin/src/android/security/cts/Poc19_03.java
+++ b/hostsidetests/securitybulletin/src/android/security/cts/Poc19_03.java
@@ -1,5 +1,5 @@
 /**
- * Copyright (C) 2018 The Android Open Source Project
+ * Copyright (C) 2020 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -17,16 +17,18 @@
 package android.security.cts;
 
 import android.platform.test.annotations.SecurityTest;
-import static org.junit.Assert.assertFalse;
-import com.android.tradefed.testtype.DeviceJUnit4ClassRunner;
 import org.junit.Test;
 import org.junit.runner.RunWith;
+import com.android.tradefed.testtype.DeviceJUnit4ClassRunner;
 
-@SecurityTest
+import static org.junit.Assert.*;
+
+@RunWith(DeviceJUnit4ClassRunner.class)
 public class Poc19_03 extends SecurityTestCase {
     /**
      * b/115739809
      */
+    @Test
     @SecurityTest(minPatchLevel = "2019-03")
     public void testPocBug_115739809() throws Exception {
         assertFalse(AdbUtils.runPocCheckExitCode("Bug-115739809", getDevice(), 30));
@@ -35,6 +37,7 @@
     /**
      * b/116855682
      */
+    @Test
     @SecurityTest(minPatchLevel = "2019-03")
     public void testPocCVE_2019_2025() throws Exception {
         AdbUtils.runPocNoOutput("CVE-2019-2025", getDevice(), 300);
diff --git a/hostsidetests/securitybulletin/src/android/security/cts/Poc19_05.java b/hostsidetests/securitybulletin/src/android/security/cts/Poc19_05.java
index b9be0af..fd3b638 100644
--- a/hostsidetests/securitybulletin/src/android/security/cts/Poc19_05.java
+++ b/hostsidetests/securitybulletin/src/android/security/cts/Poc19_05.java
@@ -1,5 +1,5 @@
 /**
- * Copyright (C) 2019 The Android Open Source Project
+ * Copyright (C) 2020 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -18,15 +18,18 @@
 
 import android.platform.test.annotations.SecurityTest;
 import org.junit.Test;
+import org.junit.runner.RunWith;
+import com.android.tradefed.testtype.DeviceJUnit4ClassRunner;
 
-import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.*;
 
-@SecurityTest
+@RunWith(DeviceJUnit4ClassRunner.class)
 public class Poc19_05 extends SecurityTestCase {
 
     /**
      * b/129556464
      */
+    @Test
     @SecurityTest(minPatchLevel = "2019-05")
     public void testPocCVE_2019_2052() throws Exception {
         int code = AdbUtils.runProxyAutoConfig("CVE-2019-2052", getDevice());
@@ -36,6 +39,7 @@
     /**
      * b/129556111
      */
+    @Test
     @SecurityTest(minPatchLevel = "2019-05")
     public void testPocCVE_2019_2045() throws Exception {
         int code = AdbUtils.runProxyAutoConfig("CVE-2019-2045", getDevice());
@@ -45,6 +49,7 @@
     /*
      * b/129556718
      */
+    @Test
     @SecurityTest(minPatchLevel = "2019-05")
     public void testPocCVE_2019_2047() throws Exception {
         int code = AdbUtils.runProxyAutoConfig("CVE-2019-2047", getDevice());
@@ -54,6 +59,7 @@
     /**
      * CVE-2019-2257
      */
+    @Test
     @SecurityTest(minPatchLevel = "2019-05")
     public void testPocCVE_2019_2257() throws Exception {
         String result = AdbUtils.runCommandLine(
@@ -65,6 +71,7 @@
     /**
      * b/117555811
      */
+    @Test
     @SecurityTest(minPatchLevel = "2019-05")
     public void testPocCVE_2019_2051() throws Exception {
         int code = AdbUtils.runProxyAutoConfig("CVE-2019-2051", getDevice());
diff --git a/hostsidetests/securitybulletin/src/android/security/cts/Poc19_06.java b/hostsidetests/securitybulletin/src/android/security/cts/Poc19_06.java
index c3651fb..67986fe 100644
--- a/hostsidetests/securitybulletin/src/android/security/cts/Poc19_06.java
+++ b/hostsidetests/securitybulletin/src/android/security/cts/Poc19_06.java
@@ -1,5 +1,5 @@
 /**
- * Copyright (C) 2019 The Android Open Source Project
+ * Copyright (C) 2020 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -17,13 +17,19 @@
 package android.security.cts;
 
 import android.platform.test.annotations.SecurityTest;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import com.android.tradefed.testtype.DeviceJUnit4ClassRunner;
 
-@SecurityTest
+import static org.junit.Assert.*;
+
+@RunWith(DeviceJUnit4ClassRunner.class)
 public class Poc19_06 extends SecurityTestCase {
 
     /**
      * b/129556445
      */
+    @Test
     @SecurityTest(minPatchLevel = "2019-06")
     public void testPocCVE_2019_2097() throws Exception {
         int code = AdbUtils.runProxyAutoConfig("CVE-2019-2097", getDevice());
diff --git a/hostsidetests/securitybulletin/src/android/security/cts/Poc19_07.java b/hostsidetests/securitybulletin/src/android/security/cts/Poc19_07.java
index 77400a7..3d729f6 100644
--- a/hostsidetests/securitybulletin/src/android/security/cts/Poc19_07.java
+++ b/hostsidetests/securitybulletin/src/android/security/cts/Poc19_07.java
@@ -16,15 +16,19 @@
 
 package android.security.cts;
 
-import static org.junit.Assert.assertTrue;
-
 import android.platform.test.annotations.SecurityTest;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import com.android.tradefed.testtype.DeviceJUnit4ClassRunner;
 
-@SecurityTest
+import static org.junit.Assert.*;
+
+@RunWith(DeviceJUnit4ClassRunner.class)
 public class Poc19_07 extends SecurityTestCase {
     /**
      * Bug-137282168
      */
+    @Test
     @SecurityTest(minPatchLevel = "2019-07")
     public void testPocBug_137282168() throws Exception {
         assertFalse("Heap buffer overflow encountered",
@@ -34,6 +38,7 @@
     /**
      * Bug-137878930
      */
+    @Test
     @SecurityTest(minPatchLevel = "2019-07")
     public void testPocBug_137878930() throws Exception {
         assertFalse("Heap use after free encountered",
diff --git a/hostsidetests/securitybulletin/src/android/security/cts/Poc19_08.java b/hostsidetests/securitybulletin/src/android/security/cts/Poc19_08.java
index b7fd2f2..c2ce29d 100644
--- a/hostsidetests/securitybulletin/src/android/security/cts/Poc19_08.java
+++ b/hostsidetests/securitybulletin/src/android/security/cts/Poc19_08.java
@@ -1,5 +1,5 @@
 /**
- * Copyright (C) 2019 The Android Open Source Project
+ * Copyright (C) 2020 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -17,13 +17,19 @@
 package android.security.cts;
 
 import android.platform.test.annotations.SecurityTest;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import com.android.tradefed.testtype.DeviceJUnit4ClassRunner;
 
-@SecurityTest
+import static org.junit.Assert.*;
+
+@RunWith(DeviceJUnit4ClassRunner.class)
 public class Poc19_08 extends SecurityTestCase {
 
     /**
      * b/129556445
      */
+    @Test
     @SecurityTest(minPatchLevel = "2019-08")
     public void testPocCVE_2019_2130() throws Exception {
         int code = AdbUtils.runProxyAutoConfig("CVE-2019-2130", getDevice());
diff --git a/hostsidetests/securitybulletin/src/android/security/cts/Poc19_11.java b/hostsidetests/securitybulletin/src/android/security/cts/Poc19_11.java
index 07257fa..a79e2b1 100644
--- a/hostsidetests/securitybulletin/src/android/security/cts/Poc19_11.java
+++ b/hostsidetests/securitybulletin/src/android/security/cts/Poc19_11.java
@@ -1,5 +1,5 @@
 /**
- * Copyright (C) 2019 The Android Open Source Project
+ * Copyright (C) 2020 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -18,15 +18,18 @@
 
 import android.platform.test.annotations.SecurityTest;
 import org.junit.Test;
+import org.junit.runner.RunWith;
+import com.android.tradefed.testtype.DeviceJUnit4ClassRunner;
 
-import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.*;
 
-@SecurityTest
+@RunWith(DeviceJUnit4ClassRunner.class)
 public class Poc19_11 extends SecurityTestCase {
 
     /**
      * b/138441919
      */
+    @Test
     @SecurityTest(minPatchLevel = "2019-11")
     public void testPocBug_138441919() throws Exception {
         int code = AdbUtils.runProxyAutoConfig("bug_138441919", getDevice());
@@ -36,6 +39,7 @@
     /**
      * b/139806216
      */
+    @Test
     @SecurityTest(minPatchLevel = "2019-11")
     public void testPocBug_139806216() throws Exception {
         int code = AdbUtils.runProxyAutoConfig("bug_139806216", getDevice());
diff --git a/hostsidetests/securitybulletin/src/android/security/cts/SecurityTestCase.java b/hostsidetests/securitybulletin/src/android/security/cts/SecurityTestCase.java
index ee38deb..a605358 100644
--- a/hostsidetests/securitybulletin/src/android/security/cts/SecurityTestCase.java
+++ b/hostsidetests/securitybulletin/src/android/security/cts/SecurityTestCase.java
@@ -16,19 +16,27 @@
 
 package android.security.cts;
 
+import com.android.tradefed.testtype.junit4.BaseHostJUnit4Test;
 import com.android.tradefed.device.DeviceNotAvailableException;
 import com.android.tradefed.device.ITestDevice;
 import com.android.tradefed.device.NativeDevice;
-import com.android.tradefed.testtype.DeviceTestCase;
 import com.android.tradefed.log.LogUtil.CLog;
+import com.android.tradefed.testtype.DeviceJUnit4ClassRunner;
+import com.android.ddmlib.Log;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.runner.RunWith;
 
 import java.util.regex.Pattern;
 import java.util.regex.Matcher;
-import com.android.ddmlib.Log;
 import java.util.concurrent.Callable;
 import java.math.BigInteger;
 
-public class SecurityTestCase extends DeviceTestCase {
+import static org.junit.Assert.*;
+import static org.junit.Assume.*;
+
+public class SecurityTestCase extends BaseHostJUnit4Test {
 
     private static final String LOG_TAG = "SecurityTestCase";
     private static final int RADIX_HEX = 16;
@@ -45,10 +53,8 @@
     /**
      * Waits for device to be online, marks the most recent boottime of the device
      */
-    @Override
+    @Before
     public void setUp() throws Exception {
-        super.setUp();
-
         getDevice().waitForDeviceAvailable();
         getDevice().disableAdbRoot();
         updateKernelStartTime();
@@ -62,7 +68,7 @@
      * Makes sure the phone is online, and the ensure the current boottime is within 2 seconds
      * (due to rounding) of the previous boottime to check if The phone has crashed.
      */
-    @Override
+    @After
     public void tearDown() throws Exception {
         oomCatcher.stop(getDevice().getSerialNumber());
 
diff --git a/hostsidetests/securitybulletin/src/android/security/cts/TestMedia.java b/hostsidetests/securitybulletin/src/android/security/cts/TestMedia.java
index 4dcb055..03a49b7 100644
--- a/hostsidetests/securitybulletin/src/android/security/cts/TestMedia.java
+++ b/hostsidetests/securitybulletin/src/android/security/cts/TestMedia.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2019 The Android Open Source Project
+ * Copyright (C) 2020 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License"); you may not
  * use this file except in compliance with the License. You may obtain a copy of
@@ -18,10 +18,15 @@
 
 import com.android.tradefed.device.ITestDevice;
 import com.android.tradefed.log.LogUtil.CLog;
-import android.platform.test.annotations.SecurityTest;
-import java.util.regex.Pattern;
 
-@SecurityTest
+import android.platform.test.annotations.SecurityTest;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import com.android.tradefed.testtype.DeviceJUnit4ClassRunner;
+
+import static org.junit.Assert.*;
+
+@RunWith(DeviceJUnit4ClassRunner.class)
 public class TestMedia extends SecurityTestCase {
 
 
@@ -30,7 +35,6 @@
      * existing test methods
      ******************************************************************************/
 
-
     /******************************************************************************
      * To prevent merge conflicts, add tests for O below this comment, before any
      * existing test methods
diff --git a/hostsidetests/statsd/apps/statsdapp/AndroidManifest.xml b/hostsidetests/statsd/apps/statsdapp/AndroidManifest.xml
index 6f3a6e9..68148d8 100644
--- a/hostsidetests/statsd/apps/statsdapp/AndroidManifest.xml
+++ b/hostsidetests/statsd/apps/statsdapp/AndroidManifest.xml
@@ -15,7 +15,8 @@
 -->
 
 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
-          package="com.android.server.cts.device.statsd" >
+          package="com.android.server.cts.device.statsd"
+          android:versionCode="10" >
     <uses-permission android:name="android.permission.ACCESS_BACKGROUND_LOCATION" />
     <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
     <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
diff --git a/hostsidetests/statsd/apps/statsdapp/src/com/android/server/cts/device/statsd/AtomTests.java b/hostsidetests/statsd/apps/statsdapp/src/com/android/server/cts/device/statsd/AtomTests.java
index 7458be5..fa74b7f 100644
--- a/hostsidetests/statsd/apps/statsdapp/src/com/android/server/cts/device/statsd/AtomTests.java
+++ b/hostsidetests/statsd/apps/statsdapp/src/com/android/server/cts/device/statsd/AtomTests.java
@@ -60,6 +60,7 @@
 import android.os.SystemClock;
 import android.os.VibrationEffect;
 import android.os.Vibrator;
+import android.util.ArrayMap;
 import android.util.Log;
 
 import androidx.test.InstrumentationRegistry;
@@ -70,6 +71,7 @@
 
 import java.util.Arrays;
 import java.util.List;
+import java.util.Map;
 import java.util.concurrent.CountDownLatch;
 import java.util.concurrent.TimeUnit;
 
@@ -78,6 +80,108 @@
 
     private static final String MY_PACKAGE_NAME = "com.android.server.cts.device.statsd";
 
+    private static final Map<String, Integer> APP_OPS_ENUM_MAP = new ArrayMap<>();
+    static {
+        APP_OPS_ENUM_MAP.put(AppOpsManager.OPSTR_COARSE_LOCATION, 0);
+        APP_OPS_ENUM_MAP.put(AppOpsManager.OPSTR_FINE_LOCATION, 1);
+        APP_OPS_ENUM_MAP.put(AppOpsManager.OPSTR_GPS, 2);
+        APP_OPS_ENUM_MAP.put(AppOpsManager.OPSTR_VIBRATE, 3);
+        APP_OPS_ENUM_MAP.put(AppOpsManager.OPSTR_READ_CONTACTS, 4);
+        APP_OPS_ENUM_MAP.put(AppOpsManager.OPSTR_WRITE_CONTACTS, 5);
+        APP_OPS_ENUM_MAP.put(AppOpsManager.OPSTR_READ_CALL_LOG, 6);
+        APP_OPS_ENUM_MAP.put(AppOpsManager.OPSTR_WRITE_CALL_LOG, 7);
+        APP_OPS_ENUM_MAP.put(AppOpsManager.OPSTR_READ_CALENDAR, 8);
+        APP_OPS_ENUM_MAP.put(AppOpsManager.OPSTR_WRITE_CALENDAR, 9);
+        APP_OPS_ENUM_MAP.put(AppOpsManager.OPSTR_WIFI_SCAN, 10);
+        APP_OPS_ENUM_MAP.put(AppOpsManager.OPSTR_POST_NOTIFICATION, 11);
+        APP_OPS_ENUM_MAP.put(AppOpsManager.OPSTR_NEIGHBORING_CELLS, 12);
+        APP_OPS_ENUM_MAP.put(AppOpsManager.OPSTR_CALL_PHONE, 13);
+        APP_OPS_ENUM_MAP.put(AppOpsManager.OPSTR_READ_SMS, 14);
+        APP_OPS_ENUM_MAP.put(AppOpsManager.OPSTR_WRITE_SMS, 15);
+        APP_OPS_ENUM_MAP.put(AppOpsManager.OPSTR_RECEIVE_SMS, 16);
+        APP_OPS_ENUM_MAP.put(AppOpsManager.OPSTR_RECEIVE_EMERGENCY_BROADCAST, 17);
+        APP_OPS_ENUM_MAP.put(AppOpsManager.OPSTR_RECEIVE_MMS, 18);
+        APP_OPS_ENUM_MAP.put(AppOpsManager.OPSTR_RECEIVE_WAP_PUSH, 19);
+        APP_OPS_ENUM_MAP.put(AppOpsManager.OPSTR_SEND_SMS, 20);
+        APP_OPS_ENUM_MAP.put(AppOpsManager.OPSTR_READ_ICC_SMS, 21);
+        APP_OPS_ENUM_MAP.put(AppOpsManager.OPSTR_WRITE_ICC_SMS, 22);
+        APP_OPS_ENUM_MAP.put(AppOpsManager.OPSTR_WRITE_SETTINGS, 23);
+        APP_OPS_ENUM_MAP.put(AppOpsManager.OPSTR_SYSTEM_ALERT_WINDOW, 24);
+        APP_OPS_ENUM_MAP.put(AppOpsManager.OPSTR_ACCESS_NOTIFICATIONS, 25);
+        APP_OPS_ENUM_MAP.put(AppOpsManager.OPSTR_CAMERA, 26);
+        APP_OPS_ENUM_MAP.put(AppOpsManager.OPSTR_RECORD_AUDIO, 27);
+        APP_OPS_ENUM_MAP.put(AppOpsManager.OPSTR_PLAY_AUDIO, 28);
+        APP_OPS_ENUM_MAP.put(AppOpsManager.OPSTR_READ_CLIPBOARD, 29);
+        APP_OPS_ENUM_MAP.put(AppOpsManager.OPSTR_WRITE_CLIPBOARD, 30);
+        APP_OPS_ENUM_MAP.put(AppOpsManager.OPSTR_TAKE_MEDIA_BUTTONS, 31);
+        APP_OPS_ENUM_MAP.put(AppOpsManager.OPSTR_TAKE_AUDIO_FOCUS, 32);
+        APP_OPS_ENUM_MAP.put(AppOpsManager.OPSTR_AUDIO_MASTER_VOLUME, 33);
+        APP_OPS_ENUM_MAP.put(AppOpsManager.OPSTR_AUDIO_VOICE_VOLUME, 34);
+        APP_OPS_ENUM_MAP.put(AppOpsManager.OPSTR_AUDIO_RING_VOLUME, 35);
+        APP_OPS_ENUM_MAP.put(AppOpsManager.OPSTR_AUDIO_MEDIA_VOLUME, 36);
+        APP_OPS_ENUM_MAP.put(AppOpsManager.OPSTR_AUDIO_ALARM_VOLUME, 37);
+        APP_OPS_ENUM_MAP.put(AppOpsManager.OPSTR_AUDIO_NOTIFICATION_VOLUME, 38);
+        APP_OPS_ENUM_MAP.put(AppOpsManager.OPSTR_AUDIO_BLUETOOTH_VOLUME, 39);
+        APP_OPS_ENUM_MAP.put(AppOpsManager.OPSTR_WAKE_LOCK, 40);
+        APP_OPS_ENUM_MAP.put(AppOpsManager.OPSTR_MONITOR_LOCATION, 41);
+        APP_OPS_ENUM_MAP.put(AppOpsManager.OPSTR_MONITOR_HIGH_POWER_LOCATION, 42);
+        APP_OPS_ENUM_MAP.put(AppOpsManager.OPSTR_GET_USAGE_STATS, 43);
+        APP_OPS_ENUM_MAP.put(AppOpsManager.OPSTR_MUTE_MICROPHONE, 44);
+        APP_OPS_ENUM_MAP.put(AppOpsManager.OPSTR_TOAST_WINDOW, 45);
+        APP_OPS_ENUM_MAP.put(AppOpsManager.OPSTR_PROJECT_MEDIA, 46);
+        APP_OPS_ENUM_MAP.put(AppOpsManager.OPSTR_ACTIVATE_VPN, 47);
+        APP_OPS_ENUM_MAP.put(AppOpsManager.OPSTR_WRITE_WALLPAPER, 48);
+        APP_OPS_ENUM_MAP.put(AppOpsManager.OPSTR_ASSIST_STRUCTURE, 49);
+        APP_OPS_ENUM_MAP.put(AppOpsManager.OPSTR_ASSIST_SCREENSHOT, 50);
+        APP_OPS_ENUM_MAP.put(AppOpsManager.OPSTR_READ_PHONE_STATE, 51);
+        APP_OPS_ENUM_MAP.put(AppOpsManager.OPSTR_ADD_VOICEMAIL, 52);
+        APP_OPS_ENUM_MAP.put(AppOpsManager.OPSTR_USE_SIP, 53);
+        APP_OPS_ENUM_MAP.put(AppOpsManager.OPSTR_PROCESS_OUTGOING_CALLS, 54);
+        APP_OPS_ENUM_MAP.put(AppOpsManager.OPSTR_USE_FINGERPRINT, 55);
+        APP_OPS_ENUM_MAP.put(AppOpsManager.OPSTR_BODY_SENSORS, 56);
+        APP_OPS_ENUM_MAP.put(AppOpsManager.OPSTR_READ_CELL_BROADCASTS, 57);
+        APP_OPS_ENUM_MAP.put(AppOpsManager.OPSTR_MOCK_LOCATION, 58);
+        APP_OPS_ENUM_MAP.put(AppOpsManager.OPSTR_READ_EXTERNAL_STORAGE, 59);
+        APP_OPS_ENUM_MAP.put(AppOpsManager.OPSTR_WRITE_EXTERNAL_STORAGE, 60);
+        APP_OPS_ENUM_MAP.put(AppOpsManager.OPSTR_TURN_SCREEN_ON, 61);
+        APP_OPS_ENUM_MAP.put(AppOpsManager.OPSTR_GET_ACCOUNTS, 62);
+        APP_OPS_ENUM_MAP.put(AppOpsManager.OPSTR_RUN_IN_BACKGROUND, 63);
+        APP_OPS_ENUM_MAP.put(AppOpsManager.OPSTR_AUDIO_ACCESSIBILITY_VOLUME, 64);
+        APP_OPS_ENUM_MAP.put(AppOpsManager.OPSTR_READ_PHONE_NUMBERS, 65);
+        APP_OPS_ENUM_MAP.put(AppOpsManager.OPSTR_REQUEST_INSTALL_PACKAGES, 66);
+        APP_OPS_ENUM_MAP.put(AppOpsManager.OPSTR_PICTURE_IN_PICTURE, 67);
+        APP_OPS_ENUM_MAP.put(AppOpsManager.OPSTR_INSTANT_APP_START_FOREGROUND, 68);
+        APP_OPS_ENUM_MAP.put(AppOpsManager.OPSTR_ANSWER_PHONE_CALLS, 69);
+        APP_OPS_ENUM_MAP.put(AppOpsManager.OPSTR_RUN_ANY_IN_BACKGROUND, 70);
+        APP_OPS_ENUM_MAP.put(AppOpsManager.OPSTR_CHANGE_WIFI_STATE, 71);
+        APP_OPS_ENUM_MAP.put(AppOpsManager.OPSTR_REQUEST_DELETE_PACKAGES, 72);
+        APP_OPS_ENUM_MAP.put(AppOpsManager.OPSTR_BIND_ACCESSIBILITY_SERVICE, 73);
+        APP_OPS_ENUM_MAP.put(AppOpsManager.OPSTR_ACCEPT_HANDOVER, 74);
+        APP_OPS_ENUM_MAP.put(AppOpsManager.OPSTR_MANAGE_IPSEC_TUNNELS, 75);
+        APP_OPS_ENUM_MAP.put(AppOpsManager.OPSTR_START_FOREGROUND, 76);
+        APP_OPS_ENUM_MAP.put(AppOpsManager.OPSTR_BLUETOOTH_SCAN, 77);
+        APP_OPS_ENUM_MAP.put(AppOpsManager.OPSTR_USE_BIOMETRIC, 78);
+        APP_OPS_ENUM_MAP.put(AppOpsManager.OPSTR_ACTIVITY_RECOGNITION, 79);
+        APP_OPS_ENUM_MAP.put(AppOpsManager.OPSTR_SMS_FINANCIAL_TRANSACTIONS, 80);
+        APP_OPS_ENUM_MAP.put(AppOpsManager.OPSTR_READ_MEDIA_AUDIO, 81);
+        APP_OPS_ENUM_MAP.put(AppOpsManager.OPSTR_WRITE_MEDIA_AUDIO, 82);
+        APP_OPS_ENUM_MAP.put(AppOpsManager.OPSTR_READ_MEDIA_VIDEO, 83);
+        APP_OPS_ENUM_MAP.put(AppOpsManager.OPSTR_WRITE_MEDIA_VIDEO, 84);
+        APP_OPS_ENUM_MAP.put(AppOpsManager.OPSTR_READ_MEDIA_IMAGES, 85);
+        APP_OPS_ENUM_MAP.put(AppOpsManager.OPSTR_WRITE_MEDIA_IMAGES, 86);
+        APP_OPS_ENUM_MAP.put(AppOpsManager.OPSTR_LEGACY_STORAGE, 87);
+        APP_OPS_ENUM_MAP.put(AppOpsManager.OPSTR_ACCESS_ACCESSIBILITY, 88);
+        APP_OPS_ENUM_MAP.put(AppOpsManager.OPSTR_READ_DEVICE_IDENTIFIERS, 89);
+        APP_OPS_ENUM_MAP.put(AppOpsManager.OPSTR_ACCESS_MEDIA_LOCATION, 90);
+        APP_OPS_ENUM_MAP.put(AppOpsManager.OPSTR_QUERY_ALL_PACKAGES, 91);
+        APP_OPS_ENUM_MAP.put(AppOpsManager.OPSTR_MANAGE_EXTERNAL_STORAGE, 92);
+        APP_OPS_ENUM_MAP.put(AppOpsManager.OPSTR_INTERACT_ACROSS_PROFILES, 93);
+        APP_OPS_ENUM_MAP.put(AppOpsManager.OPSTR_ACTIVATE_PLATFORM_VPN, 94);
+        APP_OPS_ENUM_MAP.put(AppOpsManager.OPSTR_LOADER_USAGE_STATS, 95);
+        APP_OPS_ENUM_MAP.put(AppOpsManager.OPSTR_ACCESS_CALL_AUDIO, 96);
+        APP_OPS_ENUM_MAP.put(AppOpsManager.OPSTR_AUTO_REVOKE_PERMISSIONS_IF_UNUSED, 97);
+    }
+
     @Test
     public void testAudioState() {
         // TODO: This should surely be getTargetContext(), here and everywhere, but test first.
@@ -244,6 +348,7 @@
 
         // No foreground service session
         noteAppOp(appOpsManager, AppOpsManager.OPSTR_COARSE_LOCATION, true);
+        sleep(500);
 
         // Foreground service session 1
         context.startService(fgsIntent);
@@ -255,14 +360,34 @@
         noteAppOp(appOpsManager, AppOpsManager.OPSTR_CAMERA, true);
         noteAppOp(appOpsManager, AppOpsManager.OPSTR_RECORD_AUDIO, false);
         noteAppOp(appOpsManager, AppOpsManager.OPSTR_RECORD_AUDIO, true);
+        sleep(500);
         context.stopService(fgsIntent);
 
         // No foreground service session
         noteAppOp(appOpsManager, AppOpsManager.OPSTR_COARSE_LOCATION, true);
+        sleep(500);
 
         // TODO(b/149098800): Start fgs a second time and log OPSTR_CAMERA again
     }
 
+    @Test
+    public void testAppOps() throws Exception {
+        Context context = InstrumentationRegistry.getContext();
+        AppOpsManager appOpsManager = context.getSystemService(AppOpsManager.class);
+
+        String[] opsList = appOpsManager.getOpStrs();
+
+        for (int i = 0; i < opsList.length; i++) {
+            String op = opsList[i];
+            int noteCount = APP_OPS_ENUM_MAP.getOrDefault(op, opsList.length) + 1;
+            for (int j = 0; j < noteCount; j++) {
+                try {
+                    noteAppOp(appOpsManager, opsList[i], true);
+                } catch (SecurityException e) {}
+            }
+        }
+    }
+
     /** @param doNote true if should use noteOp; false if should use startOp. */
     private void noteAppOp(AppOpsManager appOpsManager, String opStr, boolean doNote) {
         if (doNote) {
@@ -274,7 +399,6 @@
                     (aom) -> aom.startOp(opStr, android.os.Process.myUid(),
                             MY_PACKAGE_NAME, null, "statsdTest"));
         }
-        sleep(500);
     }
 
     /** Check if service is running. */
diff --git a/hostsidetests/statsd/src/android/cts/statsd/atom/DeviceAtomTestCase.java b/hostsidetests/statsd/src/android/cts/statsd/atom/DeviceAtomTestCase.java
index 8394006..e6eda6e 100644
--- a/hostsidetests/statsd/src/android/cts/statsd/atom/DeviceAtomTestCase.java
+++ b/hostsidetests/statsd/src/android/cts/statsd/atom/DeviceAtomTestCase.java
@@ -36,6 +36,7 @@
     public static final String DEVICE_SIDE_TEST_APK = "CtsStatsdApp.apk";
     public static final String DEVICE_SIDE_TEST_PACKAGE =
             "com.android.server.cts.device.statsd";
+    public static final long DEVICE_SIDE_TEST_PACKAGE_VERSION = 10;
     public static final String DEVICE_SIDE_TEST_FOREGROUND_SERVICE_NAME =
             "com.android.server.cts.device.statsd.StatsdCtsForegroundService";
     private static final String DEVICE_SIDE_BG_SERVICE_COMPONENT =
diff --git a/hostsidetests/statsd/src/android/cts/statsd/atom/UidAtomTests.java b/hostsidetests/statsd/src/android/cts/statsd/atom/UidAtomTests.java
index 58a537e..15d5bb6 100644
--- a/hostsidetests/statsd/src/android/cts/statsd/atom/UidAtomTests.java
+++ b/hostsidetests/statsd/src/android/cts/statsd/atom/UidAtomTests.java
@@ -15,9 +15,11 @@
  */
 package android.cts.statsd.atom;
 
+import static com.android.os.AtomsProto.IntegrityCheckResultReported.Response.ALLOWED;
 import static com.google.common.truth.Truth.assertThat;
 import static com.google.common.truth.Truth.assertWithMessage;
 
+import android.app.AppOpEnum;
 import android.net.wifi.WifiModeEnum;
 import android.os.WakeLockLevelEnum;
 import android.server.ErrorSource;
@@ -30,6 +32,7 @@
 import com.android.os.AtomsProto.AppStartOccurred;
 import com.android.os.AtomsProto.Atom;
 import com.android.os.AtomsProto.AttributionNode;
+import com.android.os.AtomsProto.AttributedAppOps;
 import com.android.os.AtomsProto.AudioStateChanged;
 import com.android.os.AtomsProto.BinderCalls;
 import com.android.os.AtomsProto.BleScanResultReceived;
@@ -43,14 +46,15 @@
 import com.android.os.AtomsProto.ForegroundServiceStateChanged;
 import com.android.os.AtomsProto.GpsScanStateChanged;
 import com.android.os.AtomsProto.HiddenApiUsed;
+import com.android.os.AtomsProto.IntegrityCheckResultReported;
 import com.android.os.AtomsProto.IonHeapSize;
 import com.android.os.AtomsProto.LmkKillOccurred;
 import com.android.os.AtomsProto.LooperStats;
 import com.android.os.AtomsProto.MediaCodecStateChanged;
 import com.android.os.AtomsProto.OverlayStateChanged;
-import com.android.os.AtomsProto.PackageNotificationPreferences;
-import com.android.os.AtomsProto.PackageNotificationChannelPreferences;
 import com.android.os.AtomsProto.PackageNotificationChannelGroupPreferences;
+import com.android.os.AtomsProto.PackageNotificationChannelPreferences;
+import com.android.os.AtomsProto.PackageNotificationPreferences;
 import com.android.os.AtomsProto.PictureInPictureStateChanged;
 import com.android.os.AtomsProto.ProcessMemoryHighWaterMark;
 import com.android.os.AtomsProto.ProcessMemorySnapshot;
@@ -70,7 +74,6 @@
 
 import com.google.common.collect.Range;
 
-import java.lang.ProcessBuilder;
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.HashSet;
@@ -84,8 +87,13 @@
 
     private static final String TAG = "Statsd.UidAtomTests";
 
+    private static final String TEST_PACKAGE_NAME = "com.android.server.cts.device.statsd";
+
     private static final boolean DAVEY_ENABLED = false;
 
+    private static final int NUM_APP_OPS = AttributedAppOps.getDefaultInstance().getOp().
+            getDescriptorForType().getValues().size() - 1;
+
     @Override
     protected void setUp() throws Exception {
         super.setUp();
@@ -170,7 +178,7 @@
             .isEqualTo(AppCrashOccurred.InstantApp.FALSE_VALUE);
         assertThat(atom.getForegroundState().getNumber())
             .isEqualTo(AppCrashOccurred.ForegroundState.FOREGROUND_VALUE);
-        assertThat(atom.getPackageName()).isEqualTo("com.android.server.cts.device.statsd");
+        assertThat(atom.getPackageName()).isEqualTo(TEST_PACKAGE_NAME);
     }
 
     public void testAppStartOccurred() throws Exception {
@@ -188,7 +196,7 @@
         List<EventMetricData> data = getEventMetricDataList();
 
         AppStartOccurred atom = data.get(0).getAtom().getAppStartOccurred();
-        assertThat(atom.getPkgName()).isEqualTo("com.android.server.cts.device.statsd");
+        assertThat(atom.getPkgName()).isEqualTo(TEST_PACKAGE_NAME);
         assertThat(atom.getActivityName())
             .isEqualTo("com.android.server.cts.device.statsd.StatsdCtsForegroundActivity");
         assertThat(atom.getIsInstantApp()).isFalse();
@@ -569,22 +577,21 @@
             final int count = acceptances + rejections;
             int expectedCount = 0;
             switch (opName) {
-                case ForegroundServiceAppOpSessionEnded.AppOpName.OP_CAMERA_VALUE:
+                case AppOpEnum.APP_OP_CAMERA_VALUE:
                     expectedCount = 2;
                     break;
-                case ForegroundServiceAppOpSessionEnded.AppOpName.OP_FINE_LOCATION_VALUE:
+                case AppOpEnum.APP_OP_FINE_LOCATION_VALUE:
                     expectedCount = 1;
                     break;
-                case ForegroundServiceAppOpSessionEnded.AppOpName.OP_RECORD_AUDIO_VALUE:
+                case AppOpEnum.APP_OP_RECORD_AUDIO_VALUE:
                     expectedCount = 2;
                     break;
-                case ForegroundServiceAppOpSessionEnded.AppOpName.OP_COARSE_LOCATION_VALUE:
+                case AppOpEnum.APP_OP_COARSE_LOCATION_VALUE:
                     // fall-through
                 default:
                     fail("Unexpected opName " + opName);
             }
             assertWithMessage("Wrong count for " + opName).that(count).isEqualTo(expectedCount);
-
         }
     }
 
@@ -1559,20 +1566,38 @@
         StatsdConfig.Builder config = getPulledConfig();
         addGaugeAtomWithDimensions(config, Atom.APP_OPS_FIELD_NUMBER, null);
         uploadConfig(config);
+
+        runDeviceTests(DEVICE_SIDE_TEST_PACKAGE, ".AtomTests", "testAppOps");
         Thread.sleep(WAIT_TIME_SHORT);
 
         // Pull a report
         setAppBreadcrumbPredicate();
         Thread.sleep(WAIT_TIME_SHORT);
 
-        long accessInstancesRecorded = 0;
-
-        for (Atom atom : getGaugeMetricDataList()) {
-            AppOps appOps = atom.getAppOps();
-            accessInstancesRecorded += appOps.getTrustedForegroundGrantedCount();
+        ArrayList<Integer> expectedOps = new ArrayList<>();
+        for (int i = 0; i < NUM_APP_OPS; i++) {
+            expectedOps.add(i);
         }
 
-        assertThat(accessInstancesRecorded).isAtLeast(1l);
+        for (Atom atom : getGaugeMetricDataList()) {
+
+            AppOps appOps = atom.getAppOps();
+            if (appOps.getPackageName().equals(TEST_PACKAGE_NAME)) {
+                if (appOps.getOpId().getNumber() == -1) {
+                    continue;
+                }
+                long totalNoted = appOps.getTrustedForegroundGrantedCount()
+                        + appOps.getTrustedBackgroundGrantedCount()
+                        + appOps.getTrustedForegroundRejectedCount()
+                        + appOps.getTrustedBackgroundRejectedCount();
+                assertWithMessage("Operation in APP_OPS_ENUM_MAP: " + appOps.getOpId().getNumber())
+                        .that(totalNoted - 1).isEqualTo(appOps.getOpId().getNumber());
+                assertWithMessage("Unexpected Op reported").that(expectedOps).contains(
+                        appOps.getOpId().getNumber());
+                expectedOps.remove(expectedOps.indexOf(appOps.getOpId().getNumber()));
+            }
+        }
+        assertWithMessage("Logging app op ids are missing in report.").that(expectedOps).isEmpty();
     }
 
     public void testANROccurred() throws Exception {
@@ -1810,4 +1835,29 @@
         }
         assertTrue(foundTestPackagePreferences);
     }
+
+    public void testIntegrityCheckAtomReportedDuringInstall() throws Exception {
+        if (statsdDisabled()) {
+            return;
+        }
+
+        createAndUploadConfig(AtomsProto.Atom.INTEGRITY_CHECK_RESULT_REPORTED_FIELD_NUMBER);
+
+        getDevice().uninstallPackage(DEVICE_SIDE_TEST_PACKAGE);
+        installTestApp();
+
+        List<EventMetricData> data = getEventMetricDataList();
+
+        assertThat(data.size()).isEqualTo(1);
+        assertThat(data.get(0).getAtom().hasIntegrityCheckResultReported()).isTrue();
+        IntegrityCheckResultReported result = data.get(0)
+                .getAtom().getIntegrityCheckResultReported();
+        assertThat(result.getPackageName()).isEqualTo(DEVICE_SIDE_TEST_PACKAGE);
+        // we do not assert on certificates since it seem to differ by device.
+        assertThat(result.getInstallerPackageName()).isEqualTo("adb");
+        assertThat(result.getVersionCode()).isEqualTo(DEVICE_SIDE_TEST_PACKAGE_VERSION);
+        assertThat(result.getResponse()).isEqualTo(ALLOWED);
+        assertThat(result.getCausedByAppCertRule()).isFalse();
+        assertThat(result.getCausedByInstallerRule()).isFalse();
+    }
 }
diff --git a/hostsidetests/telephonyprovider/devicetest/AndroidManifest.xml b/hostsidetests/telephonyprovider/devicetest/AndroidManifest.xml
index 0e78e46..99980a1 100644
--- a/hostsidetests/telephonyprovider/devicetest/AndroidManifest.xml
+++ b/hostsidetests/telephonyprovider/devicetest/AndroidManifest.xml
@@ -15,8 +15,8 @@
 -->
 
 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
-          package="android.telephonyprovider.host.cts">
-    <uses-sdk android:targetSdkVersion="30"/>
+          package="android.telephonyprovider.device.cts">
+    <uses-sdk android:targetSdkVersion="28"/>
     <application
         android:debuggable="true">
         <uses-library android:name="android.test.runner" />
@@ -24,6 +24,6 @@
 
     <instrumentation
         android:name="androidx.test.runner.AndroidJUnitRunner"
-        android:targetPackage="android.telephonyprovider.host.cts" />
+        android:targetPackage="android.telephonyprovider.device.cts" />
 
 </manifest>
diff --git a/hostsidetests/telephonyprovider/devicetest/src/android/telephonyprovider/cts/TelephonyProviderTest.java b/hostsidetests/telephonyprovider/devicetest/src/android/telephonyprovider/device/cts/TelephonyProviderTest.java
similarity index 98%
rename from hostsidetests/telephonyprovider/devicetest/src/android/telephonyprovider/cts/TelephonyProviderTest.java
rename to hostsidetests/telephonyprovider/devicetest/src/android/telephonyprovider/device/cts/TelephonyProviderTest.java
index 8230213..2549483 100644
--- a/hostsidetests/telephonyprovider/devicetest/src/android/telephonyprovider/cts/TelephonyProviderTest.java
+++ b/hostsidetests/telephonyprovider/devicetest/src/android/telephonyprovider/device/cts/TelephonyProviderTest.java
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package android.telephonyprovider.host.cts;
+package android.telephonyprovider.device.cts;
 
 import android.content.ContentResolver;
 import android.database.Cursor;
diff --git a/hostsidetests/telephonyprovider/src/android/telephonyprovider/cts/TelephonyProviderHostTest.java b/hostsidetests/telephonyprovider/src/android/telephonyprovider/cts/TelephonyProviderHostTest.java
index b3b91c8..6e226d1 100644
--- a/hostsidetests/telephonyprovider/src/android/telephonyprovider/cts/TelephonyProviderHostTest.java
+++ b/hostsidetests/telephonyprovider/src/android/telephonyprovider/cts/TelephonyProviderHostTest.java
@@ -27,7 +27,7 @@
 public class TelephonyProviderHostTest extends CompatChangeGatingTestCase {
 
     protected static final String TEST_APK = "TelephonyProviderDeviceTest.apk";
-    protected static final String TEST_PKG = "android.telephonyprovider.cts";
+    protected static final String TEST_PKG = "android.telephonyprovider.device.cts";
 
     private static final long APN_READING_PERMISSION_CHANGE_ID = 124107808L;
 
diff --git a/hostsidetests/theme/app/src/android/theme/app/TestConfiguration.java b/hostsidetests/theme/app/src/android/theme/app/TestConfiguration.java
index 1d450cd..552b819 100644
--- a/hostsidetests/theme/app/src/android/theme/app/TestConfiguration.java
+++ b/hostsidetests/theme/app/src/android/theme/app/TestConfiguration.java
@@ -212,8 +212,10 @@
             //        new ViewPressedModifier()),
             //new LayoutInfo(R.layout.ratingbar_5, "ratingbar_5_pressed",
             //        new ViewPressedModifier()),
-            new LayoutInfo(R.layout.searchview, "searchview_query",
-                    new SearchViewModifier(SearchViewModifier.QUERY)),
+            // Temporarily remove tests for the SearchView widget with no hint. The "X" icon has
+            // indeterminate rendering behavior on 480dpi devices, but we don't know why yet.
+            //new LayoutInfo(R.layout.searchview, "searchview_query",
+            //        new SearchViewModifier(SearchViewModifier.QUERY)),
             new LayoutInfo(R.layout.searchview, "searchview_query_hint",
                     new SearchViewModifier(SearchViewModifier.QUERY_HINT)),
             new LayoutInfo(R.layout.seekbar_0, "seekbar_0"),
diff --git a/hostsidetests/webkit/app/src/com/android/cts/webkit/WebViewDeviceSideStartupTest.java b/hostsidetests/webkit/app/src/com/android/cts/webkit/WebViewDeviceSideStartupTest.java
index fae440b..dfee062 100644
--- a/hostsidetests/webkit/app/src/com/android/cts/webkit/WebViewDeviceSideStartupTest.java
+++ b/hostsidetests/webkit/app/src/com/android/cts/webkit/WebViewDeviceSideStartupTest.java
@@ -71,6 +71,10 @@
 
     @UiThreadTest
     public void testCookieManagerBlockingUiThread() throws Throwable {
+        if (!NullWebViewUtils.isWebViewAvailable()) {
+            return;
+        }
+
         // Instant app can only have https connection.
         CtsTestServer server = new CtsTestServer(mActivity, true);
         final String url = server.getCookieUrl("death.html");
@@ -87,17 +91,10 @@
                 Log.i(TAG, "done setting cookie before creating webview");
             }
         });
-        NullWebViewUtils.NullWebViewFromThreadExceptionHandler h =
-                new NullWebViewUtils.NullWebViewFromThreadExceptionHandler();
 
-        background.setUncaughtExceptionHandler(h);
         background.start();
         background.join();
 
-        if (!h.isWebViewAvailable(mActivity)) {
-            return;
-        }
-
         // Now create WebView and test that setting the cookie beforehand really worked.
         mActivity.createAndAttachWebView();
         WebView webView = mActivity.getWebView();
@@ -165,6 +162,10 @@
 
     @UiThreadTest
     public void testStrictModeNotViolatedOnStartup() throws Throwable {
+        if (!NullWebViewUtils.isWebViewAvailable()) {
+            return;
+        }
+
         StrictMode.ThreadPolicy oldThreadPolicy = StrictMode.getThreadPolicy();
         StrictMode.VmPolicy oldVmPolicy = StrictMode.getVmPolicy();
         StrictMode.setThreadPolicy(new StrictMode.ThreadPolicy.Builder()
@@ -174,8 +175,6 @@
                 .build());
         StrictMode.setVmPolicy(new StrictMode.VmPolicy.Builder()
                 .detectAll()
-                // TODO(b/149790106): Fix and remove.
-                .permitIncorrectContextUse()
                 .penaltyLog()
                 .penaltyDeath()
                 .build());
@@ -195,23 +194,8 @@
     }
 
     private void createWebViewAndNavigate() {
-        try {
-            mActivity.createAndAttachWebView();
-        } catch (Throwable t) {
-            NullWebViewUtils.determineIfWebViewAvailable(mActivity, t);
-            if (NullWebViewUtils.isWebViewAvailable()) {
-                // Rethrow t if WebView is available (because then we failed in some way that
-                // indicates that the device supports WebView but couldn't load it for some reason).
-                throw t;
-            } else {
-                // No WebView available - bail out!
-                return;
-            }
-        }
-
-        // WebView is available, so try to call some WebView APIs to ensure they don't cause
-        // strictmode violations
-
+        // Try to call some WebView APIs to ensure they don't cause strictmode violations
+        mActivity.createAndAttachWebView();
         WebViewSyncLoader syncLoader = new WebViewSyncLoader(mActivity.getWebView());
         syncLoader.loadUrlAndWaitForCompletion("about:blank");
         syncLoader.loadUrlAndWaitForCompletion("");
@@ -220,8 +204,9 @@
 
     @UiThreadTest
     public void testGetWebViewLooperOnUiThread() {
-        PackageManager pm = mActivity.getPackageManager();
-        if (!pm.hasSystemFeature(PackageManager.FEATURE_WEBVIEW)) return;
+        if (!NullWebViewUtils.isWebViewAvailable()) {
+            return;
+        }
 
         createAndCheckWebViewLooper();
     }
@@ -231,8 +216,9 @@
      * This ensures WebView.getWebViewLooper() is not implemented as 'return Looper.myLooper();'.
      */
     public void testGetWebViewLooperCreatedOnUiThreadFromInstrThread() {
-        PackageManager pm = mActivity.getPackageManager();
-        if (!pm.hasSystemFeature(PackageManager.FEATURE_WEBVIEW)) return;
+        if (!NullWebViewUtils.isWebViewAvailable()) {
+            return;
+        }
 
         // Create the WebView on the UI thread and then ensure webview.getWebViewLooper() returns
         // the UI thread.
@@ -250,8 +236,9 @@
      */
     public void testGetWebViewLooperCreatedOnBackgroundThreadFromInstThread()
             throws InterruptedException {
-        PackageManager pm = mActivity.getPackageManager();
-        if (!pm.hasSystemFeature(PackageManager.FEATURE_WEBVIEW)) return;
+        if (!NullWebViewUtils.isWebViewAvailable()) {
+            return;
+        }
 
         // Create a WebView on a background thread, check it from the UI thread
         final WebView webviewHolder[] = new WebView[1];
diff --git a/tests/BlobStore/Android.bp b/tests/BlobStore/Android.bp
index 61d34e4..5bd782a 100644
--- a/tests/BlobStore/Android.bp
+++ b/tests/BlobStore/Android.bp
@@ -40,6 +40,7 @@
     name: "CtsBlobStoreTestHelper",
     defaults: ["cts_defaults"],
     static_libs: [
+        "androidx.test.ext.junit",
         "truth-prebuilt",
         "BlobStoreTestUtils",
     ],
@@ -60,6 +61,7 @@
     name: "CtsBlobStoreTestHelperDiffSig",
     defaults: ["cts_defaults"],
     static_libs: [
+        "androidx.test.ext.junit",
         "truth-prebuilt",
         "BlobStoreTestUtils",
     ],
@@ -84,6 +86,7 @@
     name: "CtsBlobStoreTestHelperDiffSig2",
     defaults: ["cts_defaults"],
     static_libs: [
+        "androidx.test.ext.junit",
         "truth-prebuilt",
         "BlobStoreTestUtils",
     ],
diff --git a/tests/BlobStore/AndroidTest.xml b/tests/BlobStore/AndroidTest.xml
index 7ec3304..f74e2d6 100644
--- a/tests/BlobStore/AndroidTest.xml
+++ b/tests/BlobStore/AndroidTest.xml
@@ -19,6 +19,7 @@
     <option name="config-descriptor:metadata" key="parameter" value="not_instant_app" />
     <option name="config-descriptor:metadata" key="parameter" value="not_multi_abi" />
     <option name="config-descriptor:metadata" key="parameter" value="secondary_user" />
+
     <target_preparer class="com.android.tradefed.targetprep.suite.SuiteApkInstaller">
         <option name="cleanup-apks" value="true" />
         <option name="test-file-name" value="CtsBlobStoreTestCases.apk" />
@@ -26,6 +27,11 @@
         <option name="test-file-name" value="CtsBlobStoreTestHelperDiffSig.apk" />
         <option name="test-file-name" value="CtsBlobStoreTestHelperDiffSig2.apk" />
     </target_preparer>
+
+    <target_preparer class="com.android.tradefed.targetprep.RunCommandTargetPreparer">
+        <option name="teardown-command" value="cmd blob_store idle-maintenance" />
+    </target_preparer>
+
     <test class="com.android.tradefed.testtype.AndroidJUnitTest" >
         <option name="package" value="com.android.cts.blob" />
     </test>
diff --git a/tests/BlobStore/helper-app/src/com/android/cts/blob/helper/BlobStoreTestService.java b/tests/BlobStore/helper-app/src/com/android/cts/blob/helper/BlobStoreTestService.java
index ce8cd6c..5f3547d 100644
--- a/tests/BlobStore/helper-app/src/com/android/cts/blob/helper/BlobStoreTestService.java
+++ b/tests/BlobStore/helper-app/src/com/android/cts/blob/helper/BlobStoreTestService.java
@@ -29,8 +29,10 @@
 import android.content.Intent;
 import android.content.pm.PackageManager.NameNotFoundException;
 import android.os.IBinder;
+import android.os.Parcel;
 import android.os.ParcelFileDescriptor;
 import android.os.Process;
+import android.os.RemoteException;
 
 import com.android.cts.blob.ICommandReceiver;
 import com.android.utils.blob.Utils;
@@ -66,7 +68,7 @@
                     return callback.get(timeoutSec, TimeUnit.SECONDS);
                 }
             } catch (IOException | InterruptedException | TimeoutException | ExecutionException e) {
-                throw new RuntimeException(e);
+                throw new IllegalStateException(e);
             }
         }
 
@@ -77,7 +79,7 @@
             try {
                 return blobStoreManager.openBlob(blobHandle);
             } catch (IOException e) {
-                throw new RuntimeException(e);
+                throw new IllegalStateException(e);
             }
         }
 
@@ -90,7 +92,7 @@
                     assertThat(session).isNotNull();
                 }
             } catch (IOException e) {
-                throw new RuntimeException(e);
+                throw new IllegalStateException(e);
             }
         }
 
@@ -99,9 +101,10 @@
             final BlobStoreManager blobStoreManager = getSystemService(
                     BlobStoreManager.class);
             try {
-                blobStoreManager.acquireLease(blobHandle, "Test description");
+                Utils.acquireLease(BlobStoreTestService.this, blobHandle, "Test description");
+                assertThat(blobStoreManager.getLeasedBlobs()).contains(blobHandle);
             } catch (IOException e) {
-                throw new RuntimeException(e);
+                throw new IllegalStateException(e);
             }
         }
 
@@ -110,9 +113,10 @@
             final BlobStoreManager blobStoreManager = getSystemService(
                     BlobStoreManager.class);
             try {
-                blobStoreManager.releaseLease(blobHandle);
+                Utils.releaseLease(BlobStoreTestService.this, blobHandle);
+                assertThat(blobStoreManager.getLeasedBlobs()).doesNotContain(blobHandle);
             } catch (IOException e) {
-                throw new RuntimeException(e);
+                throw new IllegalStateException(e);
             }
         }
 
@@ -124,7 +128,7 @@
                 return storageStatsManager
                         .queryStatsForPackage(UUID_DEFAULT, getPackageName(), getUser());
             } catch (IOException | NameNotFoundException e) {
-                throw new RuntimeException(e);
+                throw new IllegalStateException(e);
             }
         }
 
@@ -136,7 +140,17 @@
                 return storageStatsManager
                         .queryStatsForUid(UUID_DEFAULT, Process.myUid());
             } catch (IOException e) {
-                throw new RuntimeException(e);
+                throw new IllegalStateException(e);
+            }
+        }
+
+        @Override
+        public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
+                throws RemoteException {
+            try {
+                return super.onTransact(code, data, reply, flags);
+            } catch (AssertionError e) {
+                throw new IllegalStateException(e);
             }
         }
     }
diff --git a/tests/BlobStore/src/com/android/cts/blob/BlobStoreManagerTest.java b/tests/BlobStore/src/com/android/cts/blob/BlobStoreManagerTest.java
index 4633807..ec893bd 100644
--- a/tests/BlobStore/src/com/android/cts/blob/BlobStoreManagerTest.java
+++ b/tests/BlobStore/src/com/android/cts/blob/BlobStoreManagerTest.java
@@ -17,12 +17,14 @@
 
 import static android.os.storage.StorageManager.UUID_DEFAULT;
 
-import static com.android.compatibility.common.util.SystemUtil.runShellCommand;
+import static com.android.utils.blob.Utils.acquireLease;
+import static com.android.utils.blob.Utils.assertLeasedBlobs;
+import static com.android.utils.blob.Utils.assertNoLeasedBlobs;
+import static com.android.utils.blob.Utils.releaseLease;
 
 import static com.google.common.truth.Truth.assertThat;
 
 import static org.testng.Assert.assertThrows;
-import static org.testng.Assert.expectThrows;
 
 import android.app.blob.BlobHandle;
 import android.app.blob.BlobStoreManager;
@@ -41,13 +43,11 @@
 import com.android.cts.blob.ICommandReceiver;
 import com.android.utils.blob.DummyBlobData;
 
-import org.junit.After;
 import org.junit.Before;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 
 import java.io.IOException;
-import java.util.ArrayList;
 import java.util.concurrent.BlockingQueue;
 import java.util.concurrent.CompletableFuture;
 import java.util.concurrent.LinkedBlockingQueue;
@@ -80,8 +80,6 @@
     private Context mContext;
     private BlobStoreManager mBlobStoreManager;
 
-    private final ArrayList<Long> mCreatedSessionIds = new ArrayList<>();
-
     private static final byte[] EMPTY_BYTE_ARRAY = new byte[0];
 
     @Before
@@ -89,25 +87,14 @@
         mContext = InstrumentationRegistry.getInstrumentation().getContext();
         mBlobStoreManager = (BlobStoreManager) mContext.getSystemService(
                 Context.BLOB_STORE_SERVICE);
-        clearAllBlobsData();
-    }
-
-    @After
-    public void tearDown() {
-        clearAllBlobsData();
-    }
-
-    private void clearAllBlobsData() {
-        executeCmd("cmd blob_store clear-all-sessions");
-        executeCmd("cmd blob_store clear-all-blobs");
     }
 
     @Test
     public void testGetCreateSession() throws Exception {
-        final DummyBlobData blobData = new DummyBlobData(mContext);
+        final DummyBlobData blobData = new DummyBlobData.Builder(mContext).build();
         blobData.prepare();
         try {
-            final long sessionId = createSession(blobData.getBlobHandle());
+            final long sessionId = mBlobStoreManager.createSession(blobData.getBlobHandle());
             assertThat(sessionId).isGreaterThan(0L);
             assertThat(mBlobStoreManager.openSession(sessionId)).isNotNull();
         } finally {
@@ -117,7 +104,7 @@
 
     @Test
     public void testCreateBlobHandle_invalidArguments() throws Exception {
-        final DummyBlobData blobData = new DummyBlobData(mContext);
+        final DummyBlobData blobData = new DummyBlobData.Builder(mContext).build();
         blobData.prepare();
         final BlobHandle handle = blobData.getBlobHandle();
         try {
@@ -147,21 +134,21 @@
     }
 
     @Test
-    public void testDeleteSession_invalidArguments() throws Exception {
-        assertThrows(IllegalArgumentException.class, () -> mBlobStoreManager.openSession(-1));
+    public void testAbandonSession_invalidArguments() throws Exception {
+        assertThrows(IllegalArgumentException.class, () -> mBlobStoreManager.abandonSession(-1));
     }
 
     @Test
-    public void testDeleteSession() throws Exception {
-        final DummyBlobData blobData = new DummyBlobData(mContext);
+    public void testAbandonSession() throws Exception {
+        final DummyBlobData blobData = new DummyBlobData.Builder(mContext).build();
         blobData.prepare();
         try {
-            final long sessionId = createSession(blobData.getBlobHandle());
+            final long sessionId = mBlobStoreManager.createSession(blobData.getBlobHandle());
             assertThat(sessionId).isGreaterThan(0L);
             // Verify that session can be opened.
             assertThat(mBlobStoreManager.openSession(sessionId)).isNotNull();
 
-            mBlobStoreManager.deleteSession(sessionId);
+            mBlobStoreManager.abandonSession(sessionId);
             // Verify that trying to open session after it is deleted will throw.
             assertThrows(SecurityException.class, () -> mBlobStoreManager.openSession(sessionId));
         } finally {
@@ -171,10 +158,10 @@
 
     @Test
     public void testOpenReadWriteSession() throws Exception {
-        final DummyBlobData blobData = new DummyBlobData(mContext);
+        final DummyBlobData blobData = new DummyBlobData.Builder(mContext).build();
         blobData.prepare();
         try {
-            final long sessionId = createSession(blobData.getBlobHandle());
+            final long sessionId = mBlobStoreManager.createSession(blobData.getBlobHandle());
             assertThat(sessionId).isGreaterThan(0L);
             try (BlobStoreManager.Session session = mBlobStoreManager.openSession(sessionId)) {
                 blobData.writeToSession(session, 0, blobData.getFileSize());
@@ -193,10 +180,10 @@
 
     @Test
     public void testOpenSession_fromAnotherPkg() throws Exception {
-        final DummyBlobData blobData = new DummyBlobData(mContext);
+        final DummyBlobData blobData = new DummyBlobData.Builder(mContext).build();
         blobData.prepare();
         try {
-            final long sessionId = createSession(blobData.getBlobHandle());
+            final long sessionId = mBlobStoreManager.createSession(blobData.getBlobHandle());
             assertThat(sessionId).isGreaterThan(0L);
             try (BlobStoreManager.Session session = mBlobStoreManager.openSession(sessionId)) {
                 assertThat(session).isNotNull();
@@ -218,11 +205,11 @@
     }
 
     @Test
-    public void testAbandonSession() throws Exception {
-        final DummyBlobData blobData = new DummyBlobData(mContext);
+    public void testOpenSessionAndAbandon() throws Exception {
+        final DummyBlobData blobData = new DummyBlobData.Builder(mContext).build();
         blobData.prepare();
         try {
-            final long sessionId = createSession(blobData.getBlobHandle());
+            final long sessionId = mBlobStoreManager.createSession(blobData.getBlobHandle());
             assertThat(sessionId).isGreaterThan(0L);
 
             try (BlobStoreManager.Session session = mBlobStoreManager.openSession(sessionId)) {
@@ -244,10 +231,10 @@
 
     @Test
     public void testCloseSession() throws Exception {
-        final DummyBlobData blobData = new DummyBlobData(mContext);
+        final DummyBlobData blobData = new DummyBlobData.Builder(mContext).build();
         blobData.prepare();
         try {
-            final long sessionId = createSession(blobData.getBlobHandle());
+            final long sessionId = mBlobStoreManager.createSession(blobData.getBlobHandle());
             assertThat(sessionId).isGreaterThan(0L);
 
             // Verify session can be opened for read/write.
@@ -280,21 +267,16 @@
 
     @Test
     public void testAllowPublicAccess() throws Exception {
-        final DummyBlobData blobData = new DummyBlobData(mContext);
+        final DummyBlobData blobData = new DummyBlobData.Builder(mContext).build();
         blobData.prepare();
         try {
-            final long sessionId = createSession(blobData.getBlobHandle());
+            final long sessionId = mBlobStoreManager.createSession(blobData.getBlobHandle());
             assertThat(sessionId).isGreaterThan(0L);
 
-            try (BlobStoreManager.Session session = mBlobStoreManager.openSession(sessionId)) {
-                blobData.writeToSession(session);
+            commitBlob(blobData, session -> {
                 session.allowPublicAccess();
-
-                final CompletableFuture<Integer> callback = new CompletableFuture<>();
-                session.commit(mContext.getMainExecutor(), callback::complete);
-                assertThat(callback.get(TIMEOUT_COMMIT_CALLBACK_SEC, TimeUnit.SECONDS))
-                        .isEqualTo(0);
-            }
+                assertThat(session.isPublicAccessAllowed()).isTrue();
+            });
 
             assertPkgCanAccess(blobData, HELPER_PKG);
             assertPkgCanAccess(blobData, HELPER_PKG2);
@@ -306,10 +288,10 @@
 
     @Test
     public void testAllowPublicAccess_abandonedSession() throws Exception {
-        final DummyBlobData blobData = new DummyBlobData(mContext);
+        final DummyBlobData blobData = new DummyBlobData.Builder(mContext).build();
         blobData.prepare();
         try {
-            final long sessionId = createSession(blobData.getBlobHandle());
+            final long sessionId = mBlobStoreManager.createSession(blobData.getBlobHandle());
             assertThat(sessionId).isGreaterThan(0L);
 
             try (BlobStoreManager.Session session = mBlobStoreManager.openSession(sessionId)) {
@@ -329,21 +311,16 @@
 
     @Test
     public void testAllowSameSignatureAccess() throws Exception {
-        final DummyBlobData blobData = new DummyBlobData(mContext);
+        final DummyBlobData blobData = new DummyBlobData.Builder(mContext).build();
         blobData.prepare();
         try {
-            final long sessionId = createSession(blobData.getBlobHandle());
+            final long sessionId = mBlobStoreManager.createSession(blobData.getBlobHandle());
             assertThat(sessionId).isGreaterThan(0L);
 
-            try (BlobStoreManager.Session session = mBlobStoreManager.openSession(sessionId)) {
-                blobData.writeToSession(session);
+            commitBlob(blobData, session -> {
                 session.allowSameSignatureAccess();
-
-                final CompletableFuture<Integer> callback = new CompletableFuture<>();
-                session.commit(mContext.getMainExecutor(), callback::complete);
-                assertThat(callback.get(TIMEOUT_COMMIT_CALLBACK_SEC, TimeUnit.SECONDS))
-                        .isEqualTo(0);
-            }
+                assertThat(session.isSameSignatureAccessAllowed()).isTrue();
+            });
 
             assertPkgCanAccess(blobData, HELPER_PKG);
             assertPkgCannotAccess(blobData, HELPER_PKG2);
@@ -355,10 +332,10 @@
 
     @Test
     public void testAllowSameSignatureAccess_abandonedSession() throws Exception {
-        final DummyBlobData blobData = new DummyBlobData(mContext);
+        final DummyBlobData blobData = new DummyBlobData.Builder(mContext).build();
         blobData.prepare();
         try {
-            final long sessionId = createSession(blobData.getBlobHandle());
+            final long sessionId = mBlobStoreManager.createSession(blobData.getBlobHandle());
             assertThat(sessionId).isGreaterThan(0L);
 
             try (BlobStoreManager.Session session = mBlobStoreManager.openSession(sessionId)) {
@@ -378,21 +355,17 @@
 
     @Test
     public void testAllowPackageAccess() throws Exception {
-        final DummyBlobData blobData = new DummyBlobData(mContext);
+        final DummyBlobData blobData = new DummyBlobData.Builder(mContext).build();
         blobData.prepare();
         try {
-            final long sessionId = createSession(blobData.getBlobHandle());
+            final long sessionId = mBlobStoreManager.createSession(blobData.getBlobHandle());
             assertThat(sessionId).isGreaterThan(0L);
 
-            try (BlobStoreManager.Session session = mBlobStoreManager.openSession(sessionId)) {
-                blobData.writeToSession(session);
+            commitBlob(blobData, session -> {
                 session.allowPackageAccess(HELPER_PKG2, HELPER_PKG2_CERT_SHA256);
-
-                final CompletableFuture<Integer> callback = new CompletableFuture<>();
-                session.commit(mContext.getMainExecutor(), callback::complete);
-                assertThat(callback.get(TIMEOUT_COMMIT_CALLBACK_SEC, TimeUnit.SECONDS))
-                        .isEqualTo(0);
-            }
+                assertThat(session.isPackageAccessAllowed(HELPER_PKG2, HELPER_PKG2_CERT_SHA256))
+                        .isTrue();
+            });
 
             assertPkgCannotAccess(blobData, HELPER_PKG);
             assertPkgCanAccess(blobData, HELPER_PKG2);
@@ -404,22 +377,20 @@
 
     @Test
     public void testAllowPackageAccess_allowMultiple() throws Exception {
-        final DummyBlobData blobData = new DummyBlobData(mContext);
+        final DummyBlobData blobData = new DummyBlobData.Builder(mContext).build();
         blobData.prepare();
         try {
-            final long sessionId = createSession(blobData.getBlobHandle());
+            final long sessionId = mBlobStoreManager.createSession(blobData.getBlobHandle());
             assertThat(sessionId).isGreaterThan(0L);
 
-            try (BlobStoreManager.Session session = mBlobStoreManager.openSession(sessionId)) {
-                blobData.writeToSession(session);
+            commitBlob(blobData, session -> {
                 session.allowPackageAccess(HELPER_PKG2, HELPER_PKG2_CERT_SHA256);
                 session.allowPackageAccess(HELPER_PKG3, HELPER_PKG3_CERT_SHA256);
-
-                final CompletableFuture<Integer> callback = new CompletableFuture<>();
-                session.commit(mContext.getMainExecutor(), callback::complete);
-                assertThat(callback.get(TIMEOUT_COMMIT_CALLBACK_SEC, TimeUnit.SECONDS))
-                        .isEqualTo(0);
-            }
+                assertThat(session.isPackageAccessAllowed(HELPER_PKG2, HELPER_PKG2_CERT_SHA256))
+                        .isTrue();
+                assertThat(session.isPackageAccessAllowed(HELPER_PKG3, HELPER_PKG3_CERT_SHA256))
+                        .isTrue();
+            });
 
             assertPkgCannotAccess(blobData, HELPER_PKG);
             assertPkgCanAccess(blobData, HELPER_PKG2);
@@ -431,10 +402,10 @@
 
     @Test
     public void testAllowPackageAccess_abandonedSession() throws Exception {
-        final DummyBlobData blobData = new DummyBlobData(mContext);
+        final DummyBlobData blobData = new DummyBlobData.Builder(mContext).build();
         blobData.prepare();
         try {
-            final long sessionId = createSession(blobData.getBlobHandle());
+            final long sessionId = mBlobStoreManager.createSession(blobData.getBlobHandle());
             assertThat(sessionId).isGreaterThan(0L);
 
             try (BlobStoreManager.Session session = mBlobStoreManager.openSession(sessionId)) {
@@ -457,23 +428,16 @@
 
     @Test
     public void testPrivateAccess() throws Exception {
-        final DummyBlobData blobData = new DummyBlobData(mContext);
+        final DummyBlobData blobData = new DummyBlobData.Builder(mContext).build();
         blobData.prepare();
         final TestServiceConnection connection1 = bindToHelperService(HELPER_PKG);
         final TestServiceConnection connection2 = bindToHelperService(HELPER_PKG2);
         final TestServiceConnection connection3 = bindToHelperService(HELPER_PKG3);
         try {
-            final long sessionId = createSession(blobData.getBlobHandle());
+            final long sessionId = mBlobStoreManager.createSession(blobData.getBlobHandle());
             assertThat(sessionId).isGreaterThan(0L);
 
-            try (BlobStoreManager.Session session = mBlobStoreManager.openSession(sessionId)) {
-                blobData.writeToSession(session);
-
-                final CompletableFuture<Integer> callback = new CompletableFuture<>();
-                session.commit(mContext.getMainExecutor(), callback::complete);
-                assertThat(callback.get(TIMEOUT_COMMIT_CALLBACK_SEC, TimeUnit.SECONDS))
-                        .isEqualTo(0);
-            }
+            commitBlob(blobData);
 
             assertPkgCannotAccess(blobData, connection1);
             assertPkgCannotAccess(blobData, connection2);
@@ -498,28 +462,20 @@
 
     @Test
     public void testMixedAccessType() throws Exception {
-        final DummyBlobData blobData = new DummyBlobData(mContext);
+        final DummyBlobData blobData = new DummyBlobData.Builder(mContext).build();
         blobData.prepare();
         try {
-            final long sessionId = createSession(blobData.getBlobHandle());
+            final long sessionId = mBlobStoreManager.createSession(blobData.getBlobHandle());
             assertThat(sessionId).isGreaterThan(0L);
 
-            try (BlobStoreManager.Session session = mBlobStoreManager.openSession(sessionId)) {
-                blobData.writeToSession(session);
-
+            commitBlob(blobData, session -> {
                 session.allowSameSignatureAccess();
                 session.allowPackageAccess(HELPER_PKG3, HELPER_PKG3_CERT_SHA256);
-
                 assertThat(session.isSameSignatureAccessAllowed()).isTrue();
                 assertThat(session.isPackageAccessAllowed(HELPER_PKG3, HELPER_PKG3_CERT_SHA256))
                         .isTrue();
                 assertThat(session.isPublicAccessAllowed()).isFalse();
-
-                final CompletableFuture<Integer> callback = new CompletableFuture<>();
-                session.commit(mContext.getMainExecutor(), callback::complete);
-                assertThat(callback.get(TIMEOUT_COMMIT_CALLBACK_SEC, TimeUnit.SECONDS))
-                        .isEqualTo(0);
-            }
+            });
 
             assertPkgCanAccess(blobData, HELPER_PKG);
             assertPkgCannotAccess(blobData, HELPER_PKG2);
@@ -531,31 +487,23 @@
 
     @Test
     public void testMixedAccessType_fromMultiplePackages() throws Exception {
-        final DummyBlobData blobData = new DummyBlobData(mContext);
+        final DummyBlobData blobData = new DummyBlobData.Builder(mContext).build();
         blobData.prepare();
         final TestServiceConnection connection1 = bindToHelperService(HELPER_PKG);
         final TestServiceConnection connection2 = bindToHelperService(HELPER_PKG2);
         final TestServiceConnection connection3 = bindToHelperService(HELPER_PKG3);
         try {
-            final long sessionId = createSession(blobData.getBlobHandle());
+            final long sessionId = mBlobStoreManager.createSession(blobData.getBlobHandle());
             assertThat(sessionId).isGreaterThan(0L);
 
-            try (BlobStoreManager.Session session = mBlobStoreManager.openSession(sessionId)) {
-                blobData.writeToSession(session);
-
+            commitBlob(blobData, session -> {
                 session.allowSameSignatureAccess();
                 session.allowPackageAccess(HELPER_PKG2, HELPER_PKG2_CERT_SHA256);
-
                 assertThat(session.isSameSignatureAccessAllowed()).isTrue();
                 assertThat(session.isPackageAccessAllowed(HELPER_PKG2, HELPER_PKG2_CERT_SHA256))
                         .isTrue();
                 assertThat(session.isPublicAccessAllowed()).isFalse();
-
-                final CompletableFuture<Integer> callback = new CompletableFuture<>();
-                session.commit(mContext.getMainExecutor(), callback::complete);
-                assertThat(callback.get(TIMEOUT_COMMIT_CALLBACK_SEC, TimeUnit.SECONDS))
-                        .isEqualTo(0);
-            }
+            });
 
             assertPkgCanAccess(blobData, connection1);
             assertPkgCanAccess(blobData, connection2);
@@ -576,10 +524,10 @@
 
     @Test
     public void testSessionCommit() throws Exception {
-        final DummyBlobData blobData = new DummyBlobData(mContext);
+        final DummyBlobData blobData = new DummyBlobData.Builder(mContext).build();
         blobData.prepare();
         try {
-            final long sessionId = createSession(blobData.getBlobHandle());
+            final long sessionId = mBlobStoreManager.createSession(blobData.getBlobHandle());
             assertThat(sessionId).isGreaterThan(0L);
 
             try (BlobStoreManager.Session session = mBlobStoreManager.openSession(sessionId)) {
@@ -607,10 +555,10 @@
 
     @Test
     public void testOpenBlob() throws Exception {
-        final DummyBlobData blobData = new DummyBlobData(mContext);
+        final DummyBlobData blobData = new DummyBlobData.Builder(mContext).build();
         blobData.prepare();
         try {
-            final long sessionId = createSession(blobData.getBlobHandle());
+            final long sessionId = mBlobStoreManager.createSession(blobData.getBlobHandle());
             assertThat(sessionId).isGreaterThan(0L);
 
             try (BlobStoreManager.Session session = mBlobStoreManager.openSession(sessionId)) {
@@ -644,43 +592,75 @@
 
     @Test
     public void testAcquireReleaseLease() throws Exception {
-        final DummyBlobData blobData = new DummyBlobData(mContext);
+        final DummyBlobData blobData = new DummyBlobData.Builder(mContext).build();
         blobData.prepare();
         try {
-            final long sessionId = createSession(blobData.getBlobHandle());
+            final long sessionId = mBlobStoreManager.createSession(blobData.getBlobHandle());
             assertThat(sessionId).isGreaterThan(0L);
 
-            try (BlobStoreManager.Session session = mBlobStoreManager.openSession(sessionId)) {
-                blobData.writeToSession(session);
-
-                final CompletableFuture<Integer> callback = new CompletableFuture<>();
-                session.commit(mContext.getMainExecutor(), callback::complete);
-                assertThat(callback.get(TIMEOUT_COMMIT_CALLBACK_SEC, TimeUnit.SECONDS))
-                        .isEqualTo(0);
-            }
+            commitBlob(blobData);
 
             assertThrows(IllegalArgumentException.class, () ->
-                    mBlobStoreManager.acquireLease(blobData.getBlobHandle(),
+                    acquireLease(mContext, blobData.getBlobHandle(),
                             R.string.test_desc, blobData.getExpiryTimeMillis() + 1000));
+            assertNoLeasedBlobs(mBlobStoreManager);
 
-            mBlobStoreManager.acquireLease(blobData.getBlobHandle(), R.string.test_desc,
+            acquireLease(mContext, blobData.getBlobHandle(), R.string.test_desc,
                     blobData.getExpiryTimeMillis() - 1000);
-            mBlobStoreManager.acquireLease(blobData.getBlobHandle(), R.string.test_desc);
-            // TODO: verify acquiring lease took effect.
-            mBlobStoreManager.releaseLease(blobData.getBlobHandle());
+            assertLeasedBlobs(mBlobStoreManager, blobData.getBlobHandle());
+            acquireLease(mContext, blobData.getBlobHandle(), R.string.test_desc);
+            assertLeasedBlobs(mBlobStoreManager, blobData.getBlobHandle());
+            releaseLease(mContext, blobData.getBlobHandle());
+            assertNoLeasedBlobs(mBlobStoreManager);
 
-            mBlobStoreManager.acquireLease(blobData.getBlobHandle(), "Test description",
+            acquireLease(mContext, blobData.getBlobHandle(), "Test description",
                     blobData.getExpiryTimeMillis() - 20000);
-            mBlobStoreManager.acquireLease(blobData.getBlobHandle(), "Test description two");
-            mBlobStoreManager.releaseLease(blobData.getBlobHandle());
+            assertLeasedBlobs(mBlobStoreManager, blobData.getBlobHandle());
+            acquireLease(mContext, blobData.getBlobHandle(), "Test description two");
+            assertLeasedBlobs(mBlobStoreManager, blobData.getBlobHandle());
+            releaseLease(mContext, blobData.getBlobHandle());
+            assertNoLeasedBlobs(mBlobStoreManager);
         } finally {
             blobData.delete();
         }
     }
 
     @Test
+    public void testAcquireLease_multipleLeases() throws Exception {
+        final DummyBlobData blobData = new DummyBlobData.Builder(mContext).build();
+        final DummyBlobData blobData2 = new DummyBlobData.Builder(mContext)
+                .setRandomSeed(42)
+                .build();
+        blobData.prepare();
+        blobData2.prepare();
+        try {
+            commitBlob(blobData);
+
+            acquireLease(mContext, blobData.getBlobHandle(), R.string.test_desc,
+                    blobData.getExpiryTimeMillis() - 1000);
+            assertLeasedBlobs(mBlobStoreManager, blobData.getBlobHandle());
+
+            commitBlob(blobData2);
+
+            acquireLease(mContext, blobData2.getBlobHandle(), "Test desc2",
+                    blobData.getExpiryTimeMillis() - 2000);
+            assertLeasedBlobs(mBlobStoreManager, blobData.getBlobHandle(),
+                    blobData2.getBlobHandle());
+
+            releaseLease(mContext, blobData.getBlobHandle());
+            assertLeasedBlobs(mBlobStoreManager, blobData2.getBlobHandle());
+
+            releaseLease(mContext, blobData2.getBlobHandle());
+            assertNoLeasedBlobs(mBlobStoreManager);
+        } finally {
+            blobData.delete();
+            blobData2.delete();
+        }
+    }
+
+    @Test
     public void testAcquireReleaseLease_invalidArguments() throws Exception {
-        final DummyBlobData blobData = new DummyBlobData(mContext);
+        final DummyBlobData blobData = new DummyBlobData.Builder(mContext).build();
         blobData.prepare();
         try {
             assertThrows(NullPointerException.class, () -> mBlobStoreManager.acquireLease(
@@ -702,7 +682,7 @@
 
     @Test
     public void testStorageAttributedToSelf() throws Exception {
-        final DummyBlobData blobData = new DummyBlobData(mContext);
+        final DummyBlobData blobData = new DummyBlobData.Builder(mContext).build();
         blobData.prepare();
         final long partialFileSize = 3373L;
 
@@ -714,7 +694,7 @@
                 .queryStatsForUid(UUID_DEFAULT, Process.myUid());
 
         // Create a session and write some data.
-        final long sessionId = createSession(blobData.getBlobHandle());
+        final long sessionId = mBlobStoreManager.createSession(blobData.getBlobHandle());
         assertThat(sessionId).isGreaterThan(0L);
         try (BlobStoreManager.Session session = mBlobStoreManager.openSession(sessionId)) {
             blobData.writeToSession(session, 0, partialFileSize);
@@ -757,7 +737,8 @@
                     .isEqualTo(0);
         }
 
-        mBlobStoreManager.acquireLease(blobData.getBlobHandle(), R.string.test_desc);
+        acquireLease(mContext, blobData.getBlobHandle(), R.string.test_desc);
+        assertLeasedBlobs(mBlobStoreManager, blobData.getBlobHandle());
 
         afterStatsForPkg = storageStatsManager
                 .queryStatsForPackage(UUID_DEFAULT, mContext.getPackageName(), mContext.getUser());
@@ -771,7 +752,8 @@
         assertThat(afterStatsForUid.getDataBytes() - beforeStatsForUid.getDataBytes())
                 .isEqualTo(totalFileSize);
 
-        mBlobStoreManager.releaseLease(blobData.getBlobHandle());
+        releaseLease(mContext, blobData.getBlobHandle());
+        assertNoLeasedBlobs(mBlobStoreManager);
 
         afterStatsForPkg = storageStatsManager
                 .queryStatsForPackage(UUID_DEFAULT, mContext.getPackageName(), mContext.getUser());
@@ -787,7 +769,7 @@
 
     @Test
     public void testStorageAttribution_acquireLease() throws Exception {
-        final DummyBlobData blobData = new DummyBlobData(mContext);
+        final DummyBlobData blobData = new DummyBlobData.Builder(mContext).build();
         blobData.prepare();
 
         final StorageStatsManager storageStatsManager = mContext.getSystemService(
@@ -866,6 +848,31 @@
         }
     }
 
+    private void commitBlob(DummyBlobData blobData) throws Exception {
+        commitBlob(blobData, null);
+    }
+
+    private void commitBlob(DummyBlobData blobData,
+            AccessModifier accessModifier) throws Exception {
+        final long sessionId = mBlobStoreManager.createSession(blobData.getBlobHandle());
+        assertThat(sessionId).isGreaterThan(0L);
+        try (BlobStoreManager.Session session = mBlobStoreManager.openSession(sessionId)) {
+            blobData.writeToSession(session);
+
+            if (accessModifier != null) {
+                accessModifier.modify(session);
+            }
+            final CompletableFuture<Integer> callback = new CompletableFuture<>();
+            session.commit(mContext.getMainExecutor(), callback::complete);
+            assertThat(callback.get(TIMEOUT_COMMIT_CALLBACK_SEC, TimeUnit.SECONDS))
+                    .isEqualTo(0);
+        }
+    }
+
+    private interface AccessModifier {
+        void modify(BlobStoreManager.Session session) throws Exception;
+    }
+
     private void commitBlobFromPkg(DummyBlobData blobData, TestServiceConnection serviceConnection)
             throws Exception {
         commitBlobFromPkg(blobData, ICommandReceiver.FLAG_ACCESS_TYPE_PRIVATE, serviceConnection);
@@ -972,16 +979,4 @@
             mContext.unbindService(this);
         }
     }
-
-    private long createSession(BlobHandle blobHandle) throws Exception {
-        final long sessionId = mBlobStoreManager.createSession(blobHandle);
-        mCreatedSessionIds.add(sessionId);
-        return sessionId;
-    }
-
-    private String executeCmd(String cmd) {
-        final String result = runShellCommand(cmd).trim();
-        Log.d(TAG, "Output of <" + cmd + ">: <" + result + ">");
-        return result;
-    }
 }
diff --git a/tests/JobScheduler/src/android/jobscheduler/cts/ConnectivityConstraintTest.java b/tests/JobScheduler/src/android/jobscheduler/cts/ConnectivityConstraintTest.java
index db7192b..59018ea 100644
--- a/tests/JobScheduler/src/android/jobscheduler/cts/ConnectivityConstraintTest.java
+++ b/tests/JobScheduler/src/android/jobscheduler/cts/ConnectivityConstraintTest.java
@@ -30,6 +30,7 @@
 import android.os.Looper;
 import android.os.Message;
 import android.os.UserHandle;
+import android.platform.test.annotations.RequiresDevice;
 import android.util.Log;
 
 import com.android.compatibility.common.util.ShellIdentityUtils;
@@ -46,6 +47,7 @@
  * Similarly, requires that the phone be connected to a wifi hotspot, or else the test will fail.
  */
 @TargetApi(21)
+@RequiresDevice // Emulators don't always have access to wifi/network
 public class ConnectivityConstraintTest extends BaseJobSchedulerTest {
     private static final String TAG = "ConnectivityConstraintTest";
     private static final String RESTRICT_BACKGROUND_GET_CMD =
diff --git a/tests/JobScheduler/src/android/jobscheduler/cts/JobThrottlingTest.java b/tests/JobScheduler/src/android/jobscheduler/cts/JobThrottlingTest.java
index 0a34398..effabb7 100644
--- a/tests/JobScheduler/src/android/jobscheduler/cts/JobThrottlingTest.java
+++ b/tests/JobScheduler/src/android/jobscheduler/cts/JobThrottlingTest.java
@@ -39,6 +39,7 @@
 import android.os.SystemClock;
 import android.os.Temperature;
 import android.os.UserHandle;
+import android.platform.test.annotations.RequiresDevice;
 import android.provider.Settings;
 import android.support.test.uiautomator.UiDevice;
 import android.util.Log;
@@ -50,7 +51,6 @@
 import com.android.compatibility.common.util.AppOpsUtils;
 import com.android.compatibility.common.util.AppStandbyUtils;
 import com.android.compatibility.common.util.BatteryUtils;
-import com.android.compatibility.common.util.SystemUtil;
 import com.android.compatibility.common.util.ThermalUtils;
 
 import org.junit.After;
@@ -237,6 +237,7 @@
                 mTestAppInterface.awaitJobStart(DEFAULT_WAIT_TIMEOUT));
     }
 
+    @RequiresDevice // Emulators don't always have access to wifi/network
     @Test
     public void testBackgroundConnectivityJobsThrottled() throws Exception {
         if (!mHasWifi) {
@@ -315,6 +316,7 @@
                 mTestAppInterface.awaitJobStart(3_000));
     }
 
+    @RequiresDevice // Emulators don't always have access to wifi/network
     @Test
     public void testJobsInRestrictedBucket_WithRequiredNetwork() throws Exception {
         assumeTrue("app standby not enabled", mAppStandbyEnabled);
diff --git a/tests/accessibilityservice/src/android/accessibilityservice/cts/AccessibilityEmbeddedHierarchyTest.java b/tests/accessibilityservice/src/android/accessibilityservice/cts/AccessibilityEmbeddedHierarchyTest.java
index 8f79102..4d84a73 100644
--- a/tests/accessibilityservice/src/android/accessibilityservice/cts/AccessibilityEmbeddedHierarchyTest.java
+++ b/tests/accessibilityservice/src/android/accessibilityservice/cts/AccessibilityEmbeddedHierarchyTest.java
@@ -17,6 +17,7 @@
 package android.accessibilityservice.cts;
 
 import static android.accessibilityservice.cts.utils.ActivityLaunchUtils.launchActivityAndWaitForItToBeOnscreen;
+import static android.accessibilityservice.cts.utils.AsyncUtils.DEFAULT_TIMEOUT_MS;
 
 import static org.junit.Assert.assertFalse;
 import static org.junit.Assert.assertNotNull;
@@ -27,13 +28,18 @@
 import android.accessibilityservice.cts.activities.AccessibilityTestActivity;
 import android.app.Instrumentation;
 import android.app.UiAutomation;
+import android.graphics.Point;
 import android.graphics.Rect;
+import android.hardware.display.DisplayManager;
 import android.os.Bundle;
+import android.util.DisplayMetrics;
+import android.view.Display;
 import android.view.SurfaceControlViewHost;
 import android.view.SurfaceHolder;
 import android.view.SurfaceView;
 import android.view.View;
 import android.view.accessibility.AccessibilityNodeInfo;
+import android.view.accessibility.AccessibilityWindowInfo;
 
 import androidx.test.InstrumentationRegistry;
 import androidx.test.rule.ActivityTestRule;
@@ -49,6 +55,7 @@
 
 import java.util.concurrent.CountDownLatch;
 import java.util.concurrent.TimeUnit;
+import java.util.concurrent.TimeoutException;
 
 /**
  * Tests that AccessibilityNodeInfos from an embedded hierarchy that is present to another
@@ -131,7 +138,7 @@
     }
 
     @Test
-    public void testEmbeddedViewHasCorrectBoundAfterHostViewMove() {
+    public void testEmbeddedViewHasCorrectBoundAfterHostViewMove() throws TimeoutException {
         final AccessibilityNodeInfo target =
                 findEmbeddedAccessibilityNodeInfo(sUiAutomation.getRootInActiveWindow());
 
@@ -140,14 +147,13 @@
         final Rect oldEmbeddedViewBoundsInScreen = new Rect();
         target.getBoundsInScreen(oldEmbeddedViewBoundsInScreen);
 
-        // Move Host SurfaceView from (0, 0) to (100, 100).
-        mActivity.requestNewLayoutForTest();
+        // Move Host SurfaceView from (0, 0) to (50, 50).
+        mActivity.requestNewLayoutForTest(50, 50);
 
-        final AccessibilityNodeInfo newTarget =
-                findEmbeddedAccessibilityNodeInfo(sUiAutomation.getRootInActiveWindow());
-        final AccessibilityNodeInfo parent = newTarget.getParent();
+        target.refresh();
+        final AccessibilityNodeInfo parent = target.getParent();
 
-        newTarget.getBoundsInScreen(newEmbeddedViewBoundsInScreen);
+        target.getBoundsInScreen(newEmbeddedViewBoundsInScreen);
         parent.getBoundsInScreen(hostViewBoundsInScreen);
 
         assertTrue("hostViewBoundsInScreen" + hostViewBoundsInScreen.toShortString()
@@ -160,6 +166,22 @@
                 newEmbeddedViewBoundsInScreen.equals(oldEmbeddedViewBoundsInScreen));
     }
 
+    @Test
+    public void testEmbeddedViewIsInvisibleAfterMovingOutOfScreen() throws TimeoutException {
+        final AccessibilityNodeInfo target =
+                findEmbeddedAccessibilityNodeInfo(sUiAutomation.getRootInActiveWindow());
+        assertTrue("Embedded view should be visible at beginning.",
+                target.isVisibleToUser());
+
+        // Move Host SurfaceView out of screen
+        final Point screenSize = getScreenSize();
+        mActivity.requestNewLayoutForTest(screenSize.x, screenSize.y);
+
+        target.refresh();
+        assertFalse("Embedded view should be invisible after moving out of screen.",
+                target.isVisibleToUser());
+    }
+
     private AccessibilityNodeInfo findEmbeddedAccessibilityNodeInfo(AccessibilityNodeInfo root) {
         final int childCount = root.getChildCount();
         for (int i = 0; i < childCount; i++) {
@@ -177,6 +199,15 @@
         return null;
     }
 
+    private Point getScreenSize() {
+        final DisplayManager dm = sInstrumentation.getContext().getSystemService(
+                DisplayManager.class);
+        final Display display = dm.getDisplay(Display.DEFAULT_DISPLAY);
+        final DisplayMetrics metrics = new DisplayMetrics();
+        display.getRealMetrics(metrics);
+        return new Point(metrics.widthPixels, metrics.heightPixels);
+    }
+
     /**
      * This class is an dummy {@link android.app.Activity} used to perform embedded hierarchy
      * testing of the accessibility feature by interaction with the UI widgets.
@@ -188,9 +219,6 @@
         private static final int DEFAULT_WIDTH = 150;
         private static final int DEFAULT_HEIGHT = 150;
 
-        private static final int POSITION_X = 50;
-        private static final int POSITION_Y = 50;
-
         private SurfaceView mSurfaceView;
         private SurfaceControlViewHost mViewHost;
 
@@ -211,7 +239,7 @@
 
             View layout = getLayoutInflater().inflate(
                     R.layout.accessibility_embedded_hierarchy_test_embedded_side, null);
-            mViewHost.addView(layout, DEFAULT_WIDTH, DEFAULT_HEIGHT);
+            mViewHost.setView(layout, DEFAULT_WIDTH, DEFAULT_HEIGHT);
             mCountDownLatch.countDown();
         }
 
@@ -234,12 +262,20 @@
             }
         }
 
-        public void requestNewLayoutForTest() {
-            sInstrumentation.runOnMainSync(() -> {
-                mSurfaceView.setX(POSITION_X);
-                mSurfaceView.setY(POSITION_Y);
-                mSurfaceView.requestLayout();
-            });
+        public void requestNewLayoutForTest(int x, int y) throws TimeoutException {
+            sUiAutomation.executeAndWaitForEvent(
+                    () -> sInstrumentation.runOnMainSync(() -> {
+                        mSurfaceView.setX(x);
+                        mSurfaceView.setY(y);
+                        mSurfaceView.requestLayout();
+                    }),
+                    (event) -> {
+                        final Rect boundsInScreen = new Rect();
+                        final AccessibilityWindowInfo window =
+                                sUiAutomation.getRootInActiveWindow().getWindow();
+                        window.getBoundsInScreen(boundsInScreen);
+                        return !boundsInScreen.isEmpty();
+                    }, DEFAULT_TIMEOUT_MS);
         }
     }
 }
diff --git a/tests/accessibilityservice/src/android/accessibilityservice/cts/AccessibilityTakeScreenshotTest.java b/tests/accessibilityservice/src/android/accessibilityservice/cts/AccessibilityTakeScreenshotTest.java
index 93b8a06..0d264c3 100644
--- a/tests/accessibilityservice/src/android/accessibilityservice/cts/AccessibilityTakeScreenshotTest.java
+++ b/tests/accessibilityservice/src/android/accessibilityservice/cts/AccessibilityTakeScreenshotTest.java
@@ -105,6 +105,14 @@
                 callback));
     }
 
+    @Test(expected = IllegalArgumentException.class)
+    public void testTakeScreenshotWithNonDefaultDisplay_GetIllegalArgumentException() {
+        final Consumer callback = mock(Consumer.class);
+        // DisplayId isn't the default display, should throw illegalArgument exception.
+        mService.takeScreenshot(Display.DEFAULT_DISPLAY + 1,
+                mContext.getMainExecutor(), callback);
+    }
+
     private void verifyScreenshotResult(AccessibilityService.ScreenshotResult screenshot) {
         assertNotNull(screenshot);
         final HardwareBuffer hardwareBuffer = screenshot.getHardwareBuffer();
diff --git a/tests/accessibilityservice/src/android/accessibilityservice/cts/AccessibilityTextActionTest.java b/tests/accessibilityservice/src/android/accessibilityservice/cts/AccessibilityTextActionTest.java
index ca59377..b2fc2c5 100644
--- a/tests/accessibilityservice/src/android/accessibilityservice/cts/AccessibilityTextActionTest.java
+++ b/tests/accessibilityservice/src/android/accessibilityservice/cts/AccessibilityTextActionTest.java
@@ -495,9 +495,9 @@
                 EXTRA_DATA_RENDERING_INFO_KEY , arg));
         assertNotNull(info.getExtraRenderingInfo());
         extraRenderingInfo = info.getExtraRenderingInfo();
-        assertNotNull(extraRenderingInfo.getLayoutParams());
-        assertEquals(expectedWidthInPx, extraRenderingInfo.getLayoutParams().getWidth());
-        assertEquals(expectedHeightInPx, extraRenderingInfo.getLayoutParams().getHeight());
+        assertNotNull(extraRenderingInfo.getLayoutSize());
+        assertEquals(expectedWidthInPx, extraRenderingInfo.getLayoutSize().getWidth());
+        assertEquals(expectedHeightInPx, extraRenderingInfo.getLayoutSize().getHeight());
         assertEquals(expectedTextSize, extraRenderingInfo.getTextSizeInPx(), 0f);
         assertEquals(TypedValue.COMPLEX_UNIT_DIP, extraRenderingInfo.getTextSizeUnit());
 
@@ -523,8 +523,8 @@
         assertTrue("Refresh failed", info.refreshWithExtraData(
                 EXTRA_DATA_RENDERING_INFO_KEY, new Bundle()));
         assertNotNull(info.getExtraRenderingInfo());
-        assertNotNull(info.getExtraRenderingInfo().getLayoutParams());
-        final Size size = info.getExtraRenderingInfo().getLayoutParams();
+        assertNotNull(info.getExtraRenderingInfo().getLayoutSize());
+        final Size size = info.getExtraRenderingInfo().getLayoutSize();
         assertEquals(ViewGroup.LayoutParams.MATCH_PARENT, size.getWidth());
         assertEquals(ViewGroup.LayoutParams.WRAP_CONTENT, size.getHeight());
     }
diff --git a/tests/accessibilityservice/src/android/accessibilityservice/cts/AccessibilityWindowReportingTest.java b/tests/accessibilityservice/src/android/accessibilityservice/cts/AccessibilityWindowReportingTest.java
index eb5e2b4..3e253a7 100644
--- a/tests/accessibilityservice/src/android/accessibilityservice/cts/AccessibilityWindowReportingTest.java
+++ b/tests/accessibilityservice/src/android/accessibilityservice/cts/AccessibilityWindowReportingTest.java
@@ -261,22 +261,29 @@
             // Window manager changed the behavior of focused window at a virtual display. A window
             // at virtual display needs to be touched then it becomes to be focused one. Adding this
             // touch event on the activity window of the virtual display to pass this test case.
-            final DisplayMetrics displayMetrics = mActivity.getResources().getDisplayMetrics();
-            final int xOnScreen = displayMetrics.widthPixels / 2;
-            final int yOnScreen = displayMetrics.heightPixels / 2;
-            final long downEventTime = SystemClock.uptimeMillis();
-            final MotionEvent downEvent = MotionEvent.obtain(downEventTime, downEventTime,
-                    MotionEvent.ACTION_DOWN, xOnScreen, yOnScreen, 0);
-            downEvent.setSource(InputDevice.SOURCE_TOUCHSCREEN);
-            downEvent.setDisplayId(virtualDisplayId);
-            sUiAutomation.injectInputEvent(downEvent, true);
+            sUiAutomation.executeAndWaitForEvent(
+                    () -> {
+                        final DisplayMetrics displayMetrics =
+                                mActivity.getResources().getDisplayMetrics();
+                        final int xOnScreen = displayMetrics.widthPixels / 2;
+                        final int yOnScreen = displayMetrics.heightPixels / 2;
+                        final long downEventTime = SystemClock.uptimeMillis();
+                        final MotionEvent downEvent = MotionEvent.obtain(downEventTime,
+                                downEventTime, MotionEvent.ACTION_DOWN, xOnScreen, yOnScreen, 0);
+                        downEvent.setSource(InputDevice.SOURCE_TOUCHSCREEN);
+                        downEvent.setDisplayId(virtualDisplayId);
+                        sUiAutomation.injectInputEvent(downEvent, true);
 
-            final long upEventTime = downEventTime + 10;
-            final MotionEvent upEvent = MotionEvent.obtain(downEventTime, upEventTime,
-                    MotionEvent.ACTION_UP, xOnScreen, yOnScreen, 0);
-            upEvent.setSource(InputDevice.SOURCE_TOUCHSCREEN);
-            upEvent.setDisplayId(virtualDisplayId);
-            sUiAutomation.injectInputEvent(upEvent, true);
+                        final long upEventTime = downEventTime + 10;
+                        final MotionEvent upEvent = MotionEvent.obtain(downEventTime, upEventTime,
+                                MotionEvent.ACTION_UP, xOnScreen, yOnScreen, 0);
+                        upEvent.setSource(InputDevice.SOURCE_TOUCHSCREEN);
+                        upEvent.setDisplayId(virtualDisplayId);
+                        sUiAutomation.injectInputEvent(upEvent, true);
+                    },
+                    filterWindowsChangedWithChangeTypes(WINDOWS_CHANGE_FOCUSED |
+                            WINDOWS_CHANGE_ACTIVE),
+                    TIMEOUT_ASYNC_PROCESSING);
 
             final CharSequence activityTitle = getActivityTitle(sInstrumentation,
                     activityOnVirtualDisplay);
@@ -428,4 +435,4 @@
         });
         return params;
     }
-}
\ No newline at end of file
+}
diff --git a/tests/admin/src/android/admin/cts/DevicePolicyManagerTest.java b/tests/admin/src/android/admin/cts/DevicePolicyManagerTest.java
index c1a02ab..1c38b39 100644
--- a/tests/admin/src/android/admin/cts/DevicePolicyManagerTest.java
+++ b/tests/admin/src/android/admin/cts/DevicePolicyManagerTest.java
@@ -1114,29 +1114,29 @@
         }
     }
 
-    public void testSetProtectedPackages_failIfNotDeviceOwner() {
+    public void testSetUserControlDisabledPackages_failIfNotDeviceOwner() {
         if (!mDeviceAdmin) {
-            Log.w(TAG, "Skipping testSetProtectedPackages_failIfNotDeviceOwner()");
+            Log.w(TAG, "Skipping testSetUserControlDisabledPackages_failIfNotDeviceOwner()");
             return;
         }
         final String TEST_PACKAGE_NAME = "package1";
         List<String> packages = new ArrayList<>();
         packages.add(TEST_PACKAGE_NAME);
         try {
-            mDevicePolicyManager.setProtectedPackages(mComponent, packages);
-            fail("setProtectedPackages did not throw expected SecurityException");
+            mDevicePolicyManager.setUserControlDisabledPackages(mComponent, packages);
+            fail("setUserControlDisabledPackages did not throw expected SecurityException");
         } catch(SecurityException e) {
         }
     }
 
-    public void testGetProtectedPackages_failIfNotDeviceOwner() {
+    public void testGetUserControlDisabledPackages_failIfNotDeviceOwner() {
         if (!mDeviceAdmin) {
-            Log.w(TAG, "Skipping testGetProtectedPackages_failIfNotDeviceOwner()");
+            Log.w(TAG, "Skipping testGetUserControlDisabledPackages_failIfNotDeviceOwner()");
             return;
         }
         try {
-            mDevicePolicyManager.getProtectedPackages(mComponent);
-            fail("getProtectedPackages did not throw expected SecurityException");
+            mDevicePolicyManager.getUserControlDisabledPackages(mComponent);
+            fail("getUserControlDisabledPackages did not throw expected SecurityException");
         } catch(SecurityException e) {
         }
     }
diff --git a/tests/app/ActivityManagerApi29Test/AndroidManifest.xml b/tests/app/ActivityManagerApi29Test/AndroidManifest.xml
index 86f1cd2..0c75ff4 100644
--- a/tests/app/ActivityManagerApi29Test/AndroidManifest.xml
+++ b/tests/app/ActivityManagerApi29Test/AndroidManifest.xml
@@ -35,7 +35,7 @@
             </intent-filter>
         </activity>
         <service android:name="LocationForegroundService"
-            android:foregroundServiceType="location"
+            android:foregroundServiceType="location|camera|microphone"
             android:exported="true">
         </service>
     </application>
diff --git a/tests/app/ActivityManagerApi29Test/src/android/app/cts/LocationForegroundService.java b/tests/app/ActivityManagerApi29Test/src/android/app/cts/LocationForegroundService.java
index 86ea295..b9fa812 100644
--- a/tests/app/ActivityManagerApi29Test/src/android/app/cts/LocationForegroundService.java
+++ b/tests/app/ActivityManagerApi29Test/src/android/app/cts/LocationForegroundService.java
@@ -27,6 +27,9 @@
     private static final String NOTIFICATION_CHANNEL_ID =
             LocationForegroundService.class.getSimpleName();
 
+    public static String ACTION_SERVICE_START_RESULT =
+            "android.app.cts.activitymanager.api29.LocationForegroundService.RESULT";
+
     @Override
     public int onStartCommand(Intent intent, int flags, int startId) {
         getSystemService(NotificationManager.class).createNotificationChannel(
@@ -37,6 +40,8 @@
                 .setSmallIcon(R.drawable.black)
                 .build();
         startForeground(1, status);
+        sendBroadcast(
+                new Intent(ACTION_SERVICE_START_RESULT).setFlags(Intent.FLAG_RECEIVER_FOREGROUND));
         return START_STICKY;
     }
 
diff --git a/tests/app/ActivityManagerApi29Test/src/android/app/cts/SimpleActivity.java b/tests/app/ActivityManagerApi29Test/src/android/app/cts/SimpleActivity.java
index aa28b1f..6af83d0 100644
--- a/tests/app/ActivityManagerApi29Test/src/android/app/cts/SimpleActivity.java
+++ b/tests/app/ActivityManagerApi29Test/src/android/app/cts/SimpleActivity.java
@@ -24,6 +24,9 @@
  * A simple activity to install for various users to test LauncherApps.
  */
 public class SimpleActivity extends Activity {
+    public static String ACTION_SIMPLE_ACTIVITY_START_RESULT =
+            "android.app.cts.activitymanager.api29.SimpleActivity.RESULT";
+
     @Override
     public void onCreate(Bundle icicle) {
         super.onCreate(icicle);
@@ -35,6 +38,14 @@
     }
 
     @Override
+    public void onResume() {
+        super.onResume();
+        Intent reply = new Intent(ACTION_SIMPLE_ACTIVITY_START_RESULT);
+        reply.setFlags(Intent.FLAG_RECEIVER_FOREGROUND);
+        sendBroadcast(reply);
+    }
+
+    @Override
     protected void onNewIntent(Intent intent) {
         super.onNewIntent(intent);
         if (intent.getExtras().getBoolean("finish")) {
diff --git a/tests/app/AppExitTest/AndroidTest.xml b/tests/app/AppExitTest/AndroidTest.xml
index 2e2db13..0fdb0a7 100644
--- a/tests/app/AppExitTest/AndroidTest.xml
+++ b/tests/app/AppExitTest/AndroidTest.xml
@@ -29,7 +29,7 @@
     <test class="com.android.tradefed.testtype.AndroidJUnitTest" >
         <option name="runner" value="androidx.test.runner.AndroidJUnitRunner" />
         <option name="package" value="android.app.cts.appexit" />
-        <option name="runtime-hint" value="1m9s" />
+        <option name="runtime-hint" value="2m9s" />
         <option name="hidden-api-checks" value="false"/>
     </test>
 
diff --git a/tests/app/AppExitTest/src/android/app/cts/ActivityManagerAppExitInfoTest.java b/tests/app/AppExitTest/src/android/app/cts/ActivityManagerAppExitInfoTest.java
index 8586f2d..b815cc0 100644
--- a/tests/app/AppExitTest/src/android/app/cts/ActivityManagerAppExitInfoTest.java
+++ b/tests/app/AppExitTest/src/android/app/cts/ActivityManagerAppExitInfoTest.java
@@ -17,14 +17,15 @@
 package android.app.cts;
 
 import android.app.ActivityManager;
+import android.app.ActivityManager.RunningAppProcessInfo;
 import android.app.ApplicationExitInfo;
 import android.app.Instrumentation;
 import android.app.cts.android.app.cts.tools.WatchUidRunner;
 import android.content.ComponentName;
 import android.content.Context;
 import android.content.Intent;
+import android.content.pm.PackageManager;
 import android.os.Bundle;
-import android.os.Debug;
 import android.os.Handler;
 import android.os.HandlerThread;
 import android.os.Looper;
@@ -40,6 +41,7 @@
 import android.system.OsConstants;
 import android.test.InstrumentationTestCase;
 import android.text.TextUtils;
+import android.util.DebugUtils;
 import android.util.Log;
 
 import com.android.compatibility.common.util.ShellIdentityUtils;
@@ -86,6 +88,8 @@
     private static final int ACTION_ANR = 3;
     private static final int ACTION_NATIVE_CRASH = 4;
     private static final int ACTION_KILL = 5;
+    private static final int ACTION_ACQUIRE_STABLE_PROVIDER = 6;
+    private static final int ACTION_KILL_PROVIDER = 7;
     private static final int EXIT_CODE = 123;
     private static final int CRASH_SIGNAL = OsConstants.SIGSEGV;
 
@@ -266,6 +270,11 @@
     // Start the target package
     private void startService(int commandCode, String serviceName, boolean waitForGone,
             boolean other) {
+        startService(commandCode, serviceName, waitForGone, true, other);
+    }
+
+    private void startService(int commandCode, String serviceName, boolean waitForGone,
+            boolean waitForIdle, boolean other) {
         Intent intent = new Intent(EXIT_ACTION);
         intent.setClassName(STUB_PACKAGE_NAME, serviceName);
         intent.putExtra(EXTRA_ACTION, commandCode);
@@ -274,7 +283,9 @@
         UserHandle user = other ? mOtherUserHandle : mCurrentUserHandle;
         WatchUidRunner watcher = other ? mOtherUidWatcher : mWatcher;
         mContext.startServiceAsUser(intent, user);
-        watcher.waitFor(WatchUidRunner.CMD_IDLE, null);
+        if (waitForIdle) {
+            watcher.waitFor(WatchUidRunner.CMD_IDLE, null);
+        }
         if (waitForGone) {
             waitForGone(watcher);
         }
@@ -461,6 +472,9 @@
         // Start a process and block its main thread
         startService(ACTION_ANR, STUB_SERVICE_NAME, false, false);
 
+        // Sleep for a while to make sure it's already blocking its main thread.
+        sleep(WAITFOR_MSEC);
+
         Monitor monitor = new Monitor(mInstrumentation);
 
         Intent intent = new Intent();
@@ -493,21 +507,32 @@
         // Remove old records to avoid interference with the test.
         clearHistoricalExitInfo();
 
+        // Enable a compat feature
+        executeShellCmd("am compat enable " + PackageManager.FILTER_APPLICATION_QUERY
+                + " " + STUB_PACKAGE_NAME);
+        mInstrumentation.getUiAutomation().grantRuntimePermission(
+                STUB_PACKAGE_NAME, android.Manifest.permission.READ_CALENDAR);
         long now = System.currentTimeMillis();
 
         // Start a process and do nothing
         startService(ACTION_FINISH, STUB_SERVICE_NAME, false, false);
 
+        // Enable high frequency memory sampling
+        executeShellCmd("dumpsys procstats --start-testing");
+        // Sleep for a while to wait for the sampling of memory info
+        sleep(10000);
+        // Stop the high frequency memory sampling
+        executeShellCmd("dumpsys procstats --stop-testing");
         // Get the memory info from it.
-        Debug.MemoryInfo[] meminfo =
-                ShellIdentityUtils.invokeMethodWithShellPermissions(
-                        new int[] {mStubPackagePid},
-                        mActivityManager::getProcessMemoryInfo,
-                        android.Manifest.permission.REAL_GET_TASKS);
-        assertTrue(meminfo != null && meminfo.length == 1);
+        String dump = executeShellCmd("dumpsys activity processes " + STUB_PACKAGE_NAME);
+        assertNotNull(dump);
+        final String lastPss = extractMemString(dump, " lastPss=", ' ');
+        final String lastRss = extractMemString(dump, " lastRss=", '\n');
 
-        // kill background processes
-        executeShellCmd("am kill " + STUB_PACKAGE_NAME);
+        // Disable the compat feature
+        executeShellCmd("am compat disable " + PackageManager.FILTER_APPLICATION_QUERY
+                + " " + STUB_PACKAGE_NAME);
+
         waitForGone(mWatcher);
         long now2 = System.currentTimeMillis();
 
@@ -520,11 +545,52 @@
 
         ApplicationExitInfo info = list.get(0);
         verify(info, mStubPackagePid, mStubPackageUid, STUB_PACKAGE_NAME,
-                ApplicationExitInfo.REASON_OTHER, null, "kill background", now, now2);
+                ApplicationExitInfo.REASON_OTHER, null, "PlatformCompat overrides", now, now2);
 
         // Also verify that we get the expected meminfo
-        assertEquals(meminfo[0].getTotalPss(), info.getPss());
-        assertEquals(meminfo[0].getTotalRss(), info.getRss());
+        assertEquals(lastPss, DebugUtils.sizeValueToString(
+                info.getPss() * 1024, new StringBuilder()));
+        assertEquals(lastRss, DebugUtils.sizeValueToString(
+                info.getRss() * 1024, new StringBuilder()));
+    }
+
+    private String extractMemString(String dump, String prefix, char nextSep) {
+        int start = dump.indexOf(prefix);
+        assertTrue(start >= 0);
+        start += prefix.length();
+        int end = dump.indexOf(nextSep, start);
+        assertTrue(end > start);
+        return dump.substring(start, end);
+    }
+
+    public void testPermissionChange() throws Exception {
+        // Remove old records to avoid interference with the test.
+        clearHistoricalExitInfo();
+
+        // Grant the read calendar permission
+        mInstrumentation.getUiAutomation().grantRuntimePermission(
+                STUB_PACKAGE_NAME, android.Manifest.permission.READ_CALENDAR);
+        long now = System.currentTimeMillis();
+
+        // Start a process and do nothing
+        startService(ACTION_FINISH, STUB_SERVICE_NAME, false, false);
+
+        // Revoke the read calendar permission
+        mInstrumentation.getUiAutomation().revokeRuntimePermission(
+                STUB_PACKAGE_NAME, android.Manifest.permission.READ_CALENDAR);
+        waitForGone(mWatcher);
+        long now2 = System.currentTimeMillis();
+
+        List<ApplicationExitInfo> list = ShellIdentityUtils.invokeMethodWithShellPermissions(
+                STUB_PACKAGE_NAME, mStubPackagePid, 1,
+                mActivityManager::getHistoricalProcessExitReasons,
+                android.Manifest.permission.DUMP);
+
+        assertTrue(list != null && list.size() == 1);
+
+        ApplicationExitInfo info = list.get(0);
+        verify(info, mStubPackagePid, mStubPackageUid, STUB_PACKAGE_NAME,
+                ApplicationExitInfo.REASON_PERMISSION_CHANGE, null, null, now, now2);
     }
 
     public void testCrash() throws Exception {
@@ -571,6 +637,76 @@
                 ApplicationExitInfo.REASON_CRASH_NATIVE, null, null, now, now2);
     }
 
+    public void testUserRequested() throws Exception {
+        // Remove old records to avoid interference with the test.
+        clearHistoricalExitInfo();
+
+        long now = System.currentTimeMillis();
+
+        // Start a process and do nothing
+        startService(ACTION_NONE, STUB_SERVICE_NAME, false, false);
+
+        // Force stop the test package
+        executeShellCmd("am force-stop " + STUB_PACKAGE_NAME);
+
+        // Wait the process gone
+        waitForGone(mWatcher);
+
+        long now2 = System.currentTimeMillis();
+        List<ApplicationExitInfo> list = ShellIdentityUtils.invokeMethodWithShellPermissions(
+                STUB_PACKAGE_NAME, mStubPackagePid, 1,
+                mActivityManager::getHistoricalProcessExitReasons,
+                android.Manifest.permission.DUMP);
+
+        assertTrue(list != null && list.size() == 1);
+        verify(list.get(0), mStubPackagePid, mStubPackageUid, STUB_PACKAGE_NAME,
+                ApplicationExitInfo.REASON_USER_REQUESTED, null, null, now, now2);
+    }
+
+    public void testDependencyDied() throws Exception {
+        // Remove old records to avoid interference with the test.
+        clearHistoricalExitInfo();
+
+        // Start a process and acquire the provider
+        startService(ACTION_ACQUIRE_STABLE_PROVIDER, STUB_SERVICE_NAME, false, false);
+
+        final ActivityManager am = mContext.getSystemService(ActivityManager.class);
+        long now = System.currentTimeMillis();
+        final long timeout = now + WAITFOR_MSEC;
+        int providerPid = -1;
+        while (now < timeout && providerPid < 0) {
+            sleep(1000);
+            List<RunningAppProcessInfo> list = ShellIdentityUtils.invokeMethodWithShellPermissions(
+                    am, (m) -> m.getRunningAppProcesses(),
+                    android.Manifest.permission.REAL_GET_TASKS);
+            for (RunningAppProcessInfo info: list) {
+                if (info.processName.equals(STUB_REMOTE_ROCESS_NAME)) {
+                    providerPid = info.pid;
+                    break;
+                }
+            }
+            now = System.currentTimeMillis();
+        }
+        assertTrue(providerPid > 0);
+
+        now = System.currentTimeMillis();
+        // Now let the provider exit itself
+        startService(ACTION_KILL_PROVIDER, STUB_SERVICE_NAME, false, false, false);
+
+        // Wait for both of the processes gone
+        waitForGone(mWatcher);
+        final long now2 = System.currentTimeMillis();
+
+        List<ApplicationExitInfo> list = ShellIdentityUtils.invokeMethodWithShellPermissions(
+                STUB_PACKAGE_NAME, mStubPackagePid, 1,
+                mActivityManager::getHistoricalProcessExitReasons,
+                android.Manifest.permission.DUMP);
+
+        assertTrue(list != null && list.size() == 1);
+        verify(list.get(0), mStubPackagePid, mStubPackageUid, STUB_PACKAGE_NAME,
+                ApplicationExitInfo.REASON_DEPENDENCY_DIED, null, null, now, now2);
+    }
+
     public void testMultipleProcess() throws Exception {
         // Remove old records to avoid interference with the test.
         clearHistoricalExitInfo();
@@ -738,9 +874,31 @@
         verify(list.get(1), mStubPackageOtherUserPid, mStubPackageOtherUid, STUB_ROCESS_NAME,
                 ApplicationExitInfo.REASON_SIGNALED, OsConstants.SIGKILL, null, now2, now3);
 
-        int otherUserId = mOtherUserId;
+        // Get the full user permission in order to start service as other user
+        mInstrumentation.getUiAutomation().adoptShellPermissionIdentity(
+                android.Manifest.permission.INTERACT_ACROSS_USERS,
+                android.Manifest.permission.INTERACT_ACROSS_USERS_FULL);
+        // Start the process in a secondary user and do nothing
+        startService(ACTION_NONE, STUB_SERVICE_NAME, false, true);
+        // drop the permissions
+        mInstrumentation.getUiAutomation().dropShellPermissionIdentity();
+
+        long now6 = System.currentTimeMillis();
         // Stop the test user
         assertTrue(stopUser(mOtherUserId, true, true));
+        // Wait for being killed
+        waitForGone(mOtherUidWatcher);
+
+        long now7 = System.currentTimeMillis();
+        list = ShellIdentityUtils.invokeMethodWithShellPermissions(
+                STUB_PACKAGE_NAME, 0, 1, mOtherUserId,
+                this::getHistoricalProcessExitReasonsAsUser,
+                android.Manifest.permission.DUMP,
+                android.Manifest.permission.INTERACT_ACROSS_USERS);
+        verify(list.get(0), mStubPackageOtherUserPid, mStubPackageOtherUid, STUB_ROCESS_NAME,
+                ApplicationExitInfo.REASON_USER_STOPPED, null, null, now6, now7);
+
+        int otherUserId = mOtherUserId;
         // Now remove the other user
         removeUser(mOtherUserId);
         mOtherUidWatcher.finish();
diff --git a/tests/app/app/AndroidManifest.xml b/tests/app/app/AndroidManifest.xml
index 59368ad..c73b7d1 100644
--- a/tests/app/app/AndroidManifest.xml
+++ b/tests/app/app/AndroidManifest.xml
@@ -135,14 +135,15 @@
 
         <service android:name="android.app.stubs.LocalStoppedService" />
 
-        <service android:name="android.app.stubs.LocalForegroundService">
+        <service android:name="android.app.stubs.LocalForegroundService"
+                 android:foregroundServiceType="camera|microphone">
             <intent-filter>
                 <action android:name="android.app.stubs.FOREGROUND_SERVICE" />
             </intent-filter>
         </service>
 
         <service android:name="android.app.stubs.LocalForegroundServiceLocation"
-                android:foregroundServiceType="location">
+                android:foregroundServiceType="location|camera|microphone">
             <intent-filter>
                 <action android:name="android.app.stubs.FOREGROUND_SERVICE_LOCATION" />
             </intent-filter>
diff --git a/tests/app/app/src/android/app/stubs/LocalForegroundServiceLocation.java b/tests/app/app/src/android/app/stubs/LocalForegroundServiceLocation.java
index e013dc2..56346db 100644
--- a/tests/app/app/src/android/app/stubs/LocalForegroundServiceLocation.java
+++ b/tests/app/app/src/android/app/stubs/LocalForegroundServiceLocation.java
@@ -63,7 +63,7 @@
                         .setContentTitle(getNotificationTitle(mNotificationId))
                         .setSmallIcon(R.drawable.black)
                         .build();
-                startForeground(mNotificationId, notification, type);
+                startForeground(mNotificationId, notification);
                 //assertEquals(type, getForegroundServiceType());
                 break;
             default:
diff --git a/tests/app/app/src/android/app/stubs/SendBubbleActivity.java b/tests/app/app/src/android/app/stubs/SendBubbleActivity.java
index e2552bc..223f885 100644
--- a/tests/app/app/src/android/app/stubs/SendBubbleActivity.java
+++ b/tests/app/app/src/android/app/stubs/SendBubbleActivity.java
@@ -28,7 +28,6 @@
 import android.graphics.drawable.Icon;
 import android.os.Bundle;
 import android.os.SystemClock;
-import android.util.Log;
 
 /**
  * Used by NotificationManagerTest for testing policy around bubbles, this activity is able to
@@ -59,7 +58,7 @@
      * Sends a notification that has bubble metadata but the rest of the notification isn't
      * configured correctly so the system won't allow it to bubble.
      */
-    public void sendInvalidBubble(int i, boolean autoExpand) {
+    public void sendInvalidBubble(boolean autoExpand) {
         Context context = getApplicationContext();
 
         PendingIntent pendingIntent = PendingIntent.getActivity(context, 0, new Intent(), 0);
@@ -75,7 +74,6 @@
         NotificationManager noMan = (NotificationManager) context.getSystemService(
                 Context.NOTIFICATION_SERVICE);
         noMan.notify(BUBBLE_NOTIF_ID, n);
-        Log.d(TAG, "posting bubble: " + n + ", " + i);
     }
 
     /** Sends a notification that is properly configured to bubble. */
diff --git a/tests/app/src/android/app/cts/ActivityManagerApi29Test.java b/tests/app/src/android/app/cts/ActivityManagerApi29Test.java
index a1fad70..26b44f1 100644
--- a/tests/app/src/android/app/cts/ActivityManagerApi29Test.java
+++ b/tests/app/src/android/app/cts/ActivityManagerApi29Test.java
@@ -17,6 +17,7 @@
 
 import static android.Manifest.permission.ACCESS_COARSE_LOCATION;
 import static android.app.ActivityManager.PROCESS_CAPABILITY_ALL;
+import static android.app.ActivityManager.PROCESS_CAPABILITY_FOREGROUND_LOCATION;
 import static android.app.ActivityManager.PROCESS_CAPABILITY_NONE;
 import static android.app.AppOpsManager.MODE_ALLOWED;
 import static android.app.AppOpsManager.MODE_FOREGROUND;
@@ -38,6 +39,7 @@
 import android.app.AppOpsManager.HistoricalOps;
 import android.app.AppOpsManager.HistoricalOpsRequest;
 import android.app.Instrumentation;
+import android.app.cts.android.app.cts.tools.WaitForBroadcast;
 import android.app.cts.android.app.cts.tools.WatchUidRunner;
 import android.content.Context;
 import android.content.Intent;
@@ -46,7 +48,6 @@
 import android.provider.DeviceConfig;
 import android.provider.Settings;
 
-import androidx.test.filters.Suppress;
 import androidx.test.InstrumentationRegistry;
 import androidx.test.runner.AndroidJUnit4;
 
@@ -69,17 +70,27 @@
  * when the process is in background state.
  */
 @RunWith(AndroidJUnit4.class)
-@Suppress
+//@Suppress
 public class ActivityManagerApi29Test {
     private static final String PACKAGE_NAME = "android.app.cts.activitymanager.api29";
     private static final String SIMPLE_ACTIVITY = ".SimpleActivity";
+    private static final String ACTION_SIMPLE_ACTIVITY_START_RESULT =
+            "android.app.cts.activitymanager.api29.SimpleActivity.RESULT";
+    private static final String ACTION_SERVICE_START_RESULT =
+            "android.app.cts.activitymanager.api29.LocationForegroundService.RESULT";
     private static final String SERVICE_NAME = ".LocationForegroundService";
     private static final String PROPERTY_PERMISSIONS_HUB_ENABLED = "permissions_hub_enabled";
     private static final int WAITFOR_MSEC = 10000;
     private static final int NOTEOP_COUNT = 5;
-    private static Instrumentation sInstrumentation = InstrumentationRegistry.getInstrumentation();
-    private static Context sContext = sInstrumentation.getContext();
-    private static AppOpsManager sAppOps =
+
+    //TODO: remove this when development is done.
+    private static final int TEMP_PROCESS_CAPABILITY_FOREGROUND_LOCATION = 1 << 31;
+
+    private static final Instrumentation sInstrumentation =
+            InstrumentationRegistry.getInstrumentation();
+    private static final Context sContext = sInstrumentation.getContext();
+    private static final Context sTargetContext = sInstrumentation.getTargetContext();
+    private static final AppOpsManager sAppOps =
             (AppOpsManager) sContext.getSystemService(AppOpsManager.class);
     private static Intent sActivityIntent;
     private static Intent sServiceIntent = new Intent().setClassName(
@@ -142,21 +153,21 @@
         sActivityIntent = new Intent(Intent.ACTION_MAIN)
                 .setClassName(PACKAGE_NAME, PACKAGE_NAME + SIMPLE_ACTIVITY)
                 .addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
-        sContext.startActivity(sActivityIntent);
+        sTargetContext.startActivity(sActivityIntent);
     }
 
     private void stopSimpleActivity() {
         sActivityIntent.addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP)
                 .putExtra("finish", true);
-        sContext.startActivity(sActivityIntent);
+        sTargetContext.startActivity(sActivityIntent);
     }
 
     private void startSimpleService() {
-        sContext.startForegroundService(sServiceIntent);
+        sTargetContext.startForegroundService(sServiceIntent);
     }
 
     private void stopSimpleService() {
-        sContext.stopService(sServiceIntent);
+        sTargetContext.stopService(sServiceIntent);
     }
 
     /**
@@ -198,7 +209,7 @@
         // Wait for state and capability change.
         // BG started FGS does not have location capability.
         mUidWatcher.waitFor(WatchUidRunner.CMD_PROCSTATE, WatchUidRunner.STATE_FG_SERVICE,
-                new Integer(PROCESS_CAPABILITY_NONE));
+                new Integer(TEMP_PROCESS_CAPABILITY_FOREGROUND_LOCATION));
 
         startSimpleActivity();
         mUidWatcher.waitFor(WatchUidRunner.CMD_PROCSTATE, WatchUidRunner.STATE_TOP,
@@ -209,7 +220,7 @@
 
         stopSimpleActivity();
         mUidWatcher.waitFor(WatchUidRunner.CMD_PROCSTATE, WatchUidRunner.STATE_FG_SERVICE,
-                new Integer(PROCESS_CAPABILITY_NONE));
+                new Integer(TEMP_PROCESS_CAPABILITY_FOREGROUND_LOCATION));
 
         // AppOps location access should be denied.
         assertEquals(MODE_IGNORED, noteOp(OPSTR_COARSE_LOCATION));
@@ -231,23 +242,33 @@
      */
     @Test
     public void testAppOpsHistoricalOps() throws Exception {
-        startSimpleActivity();
-        startSimpleService();
-        // Wait for state and capability change.
-        mUidWatcher.waitFor(WatchUidRunner.CMD_PROCSTATE, WatchUidRunner.STATE_TOP,
-                new Integer(PROCESS_CAPABILITY_ALL));
-
         runWithShellPermissionIdentity(
                 () ->  sAppOps.setHistoryParameters(AppOpsManager.HISTORICAL_MODE_ENABLED_ACTIVE,
                         1000, 10)
         );
+        WaitForBroadcast waiter = new WaitForBroadcast(sInstrumentation.getTargetContext());
+        waiter.prepare(ACTION_SIMPLE_ACTIVITY_START_RESULT);
+        startSimpleActivity();
+        mUidWatcher.waitFor(WatchUidRunner.CMD_PROCSTATE, WatchUidRunner.STATE_TOP,
+                new Integer(PROCESS_CAPABILITY_ALL));
+        waiter.doWait(WAITFOR_MSEC);
+
+        waiter = new WaitForBroadcast(sInstrumentation.getTargetContext());
+        waiter.prepare(ACTION_SERVICE_START_RESULT);
+        startSimpleService();
+        waiter.doWait(WAITFOR_MSEC);
+
         for (int i = 0; i < NOTEOP_COUNT; i++) {
             noteOp(OPSTR_COARSE_LOCATION);
         }
 
         stopSimpleActivity();
+        // The callingPackage to start FGS is in background.
         mUidWatcher.waitFor(WatchUidRunner.CMD_PROCSTATE, WatchUidRunner.STATE_FG_SERVICE,
-                new Integer(PROCESS_CAPABILITY_NONE));
+                new Integer(TEMP_PROCESS_CAPABILITY_FOREGROUND_LOCATION));
+        for (int i = 0; i < NOTEOP_COUNT; i++) {
+            noteOp(OPSTR_COARSE_LOCATION);
+        }
         stopSimpleService();
         mUidWatcher.waitFor(WatchUidRunner.CMD_PROCSTATE, WatchUidRunner.STATE_CACHED_EMPTY,
                 new Integer(PROCESS_CAPABILITY_NONE));
@@ -272,7 +293,7 @@
             assertEquals(NOTEOP_COUNT, hOp.getAccessCount(UID_STATE_TOP,
                     UID_STATE_FOREGROUND_SERVICE, AppOpsManager.OP_FLAGS_ALL));
             assertEquals(NOTEOP_COUNT, hOp.getForegroundAccessCount(OP_FLAGS_ALL));
-            assertEquals(0, hOp.getForegroundRejectCount(OP_FLAGS_ALL));
+            assertEquals(NOTEOP_COUNT, hOp.getForegroundRejectCount(OP_FLAGS_ALL));
             assertEquals(0, hOp.getBackgroundAccessCount(OP_FLAGS_ALL));
             // denied access one time in background.
             assertEquals(NOTEOP_COUNT, hOp.getBackgroundRejectCount(OP_FLAGS_ALL)); }
@@ -288,7 +309,7 @@
         startSimpleService();
         // Wait for state and capability change.
         mUidWatcher.waitFor(WatchUidRunner.CMD_PROCSTATE, WatchUidRunner.STATE_FG_SERVICE,
-                new Integer(PROCESS_CAPABILITY_NONE));
+                new Integer(TEMP_PROCESS_CAPABILITY_FOREGROUND_LOCATION));
 
         // Non-Top started FGS do not have while-in-use permission, camera/microphone access is
         // denied.
@@ -308,7 +329,7 @@
         // Tell the activity to finalize.
         stopSimpleActivity();
         mUidWatcher.waitFor(WatchUidRunner.CMD_PROCSTATE, WatchUidRunner.STATE_FG_SERVICE,
-                new Integer(PROCESS_CAPABILITY_NONE));
+                new Integer(TEMP_PROCESS_CAPABILITY_FOREGROUND_LOCATION));
 
         // App not in Top, camera/microphone access should be denied.
         assertEquals(MODE_IGNORED, noteOp(OPSTR_CAMERA));
diff --git a/tests/app/src/android/app/cts/ActivityManagerFgsBgStartTest.java b/tests/app/src/android/app/cts/ActivityManagerFgsBgStartTest.java
index 4961bff7..70dd07a 100644
--- a/tests/app/src/android/app/cts/ActivityManagerFgsBgStartTest.java
+++ b/tests/app/src/android/app/cts/ActivityManagerFgsBgStartTest.java
@@ -38,9 +38,12 @@
     private static final String PACKAGE_NAME_APP2 = "com.android.app2";
     private static final String PACKAGE_NAME_APP3 = "com.android.app3";
 
-    public static String ACTION_START_FGS_RESULT =
+    //TODO: remove this when development is done.
+    private static final int TEMP_PROCESS_CAPABILITY_FOREGROUND_LOCATION = 1 << 31;
+
+    private static final String ACTION_START_FGS_RESULT =
             "android.app.stubs.LocalForegroundService.RESULT";
-    public static String ACTION_START_FGSL_RESULT =
+    private static final String ACTION_START_FGSL_RESULT =
             "android.app.stubs.LocalForegroundServiceLocation.RESULT";
 
     private static final int WAITFOR_MSEC = 10000;
@@ -88,7 +91,7 @@
             // Package1 is in FGS state, but won't get location capability.
             uid1Watcher.waitFor(WatchUidRunner.CMD_PROCSTATE,
                     WatchUidRunner.STATE_FG_SERVICE,
-                    new Integer(PROCESS_CAPABILITY_NONE));
+                    new Integer(TEMP_PROCESS_CAPABILITY_FOREGROUND_LOCATION));
             // stop FGSL
             CommandReceiver.sendCommand(mContext,
                     CommandReceiver.COMMAND_STOP_FOREGROUND_SERVICE_LOCATION,
@@ -108,7 +111,7 @@
             // Package1 is in STATE_FG_SERVICE, but won't get location capability.
             uid1Watcher.waitFor(WatchUidRunner.CMD_PROCSTATE,
                     WatchUidRunner.STATE_FG_SERVICE,
-                    new Integer(PROCESS_CAPABILITY_NONE));
+                    new Integer(TEMP_PROCESS_CAPABILITY_FOREGROUND_LOCATION));
             // stop FGSL.
             CommandReceiver.sendCommand(mContext,
                     CommandReceiver.COMMAND_STOP_FOREGROUND_SERVICE_LOCATION,
@@ -167,7 +170,7 @@
             // Package2 won't have location capability because package1 is not in TOP state.
             uid2Watcher.waitFor(WatchUidRunner.CMD_PROCSTATE,
                     WatchUidRunner.STATE_FG_SERVICE,
-                    new Integer(PROCESS_CAPABILITY_NONE));
+                    new Integer(TEMP_PROCESS_CAPABILITY_FOREGROUND_LOCATION));
             waiter.doWait(WAITFOR_MSEC);
 
             CommandReceiver.sendCommand(mContext,
@@ -243,7 +246,7 @@
             // Package2 won't have location capability.
             uid2Watcher.waitFor(WatchUidRunner.CMD_PROCSTATE,
                     WatchUidRunner.STATE_FG_SERVICE,
-                    new Integer(PROCESS_CAPABILITY_NONE));
+                    new Integer(TEMP_PROCESS_CAPABILITY_FOREGROUND_LOCATION));
             // Stop FGSL in package2.
             CommandReceiver.sendCommand(mContext,
                     CommandReceiver.COMMAND_STOP_FOREGROUND_SERVICE_LOCATION,
@@ -271,7 +274,7 @@
             // Package2 won't have location capability.
             uid2Watcher.waitFor(WatchUidRunner.CMD_PROCSTATE,
                     WatchUidRunner.STATE_FG_SERVICE,
-                    new Integer(PROCESS_CAPABILITY_NONE));
+                    new Integer(TEMP_PROCESS_CAPABILITY_FOREGROUND_LOCATION));
             waiter.doWait(WAITFOR_MSEC);
             // stop FGSL in package2.
             CommandReceiver.sendCommand(mContext,
diff --git a/tests/app/src/android/app/cts/ActivityManagerProcessStateTest.java b/tests/app/src/android/app/cts/ActivityManagerProcessStateTest.java
index 79c1778..b105b92 100644
--- a/tests/app/src/android/app/cts/ActivityManagerProcessStateTest.java
+++ b/tests/app/src/android/app/cts/ActivityManagerProcessStateTest.java
@@ -1774,7 +1774,7 @@
             mWatchers[0].waitFor(WatchUidRunner.CMD_PROCSTATE,
                     WatchUidRunner.STATE_TOP,
                     new Integer(PROCESS_CAPABILITY_FOREGROUND_LOCATION
-                            | PROCESS_CAPABILITY_ALL_IMPLICIT));
+                            | PROCESS_CAPABILITY_ALL));
 
             // Start a FGS
             CommandReceiver.sendCommand(mContext,
@@ -1805,7 +1805,7 @@
             // Verify app1 does NOT have capability.
             mWatchers[1].waitFor(WatchUidRunner.CMD_PROCSTATE,
                     WatchUidRunner.STATE_FG_SERVICE,
-                    new Integer(PROCESS_CAPABILITY_NONE));
+                    new Integer(PROCESS_CAPABILITY_ALL_IMPLICIT));
 
             // Bind App 0 -> App 2, include capability.
             bundle = new Bundle();
@@ -1863,7 +1863,7 @@
             CommandReceiver.sendCommand(mContext, CommandReceiver.COMMAND_BIND_SERVICE,
                     STUB_PACKAGE_NAME, mAppInfo[0].packageName, 0, null);
             mWatchers[0].waitFor(WatchUidRunner.CMD_PROCSTATE, WatchUidRunner.STATE_BOUND_TOP,
-                    new Integer(PROCESS_CAPABILITY_ALL_IMPLICIT));
+                    new Integer(PROCESS_CAPABILITY_NONE));
 
             // Bind Stub -> App 1, include capability (TOP)
             Bundle bundle = new Bundle();
diff --git a/tests/app/src/android/app/cts/ActivityManagerTest.java b/tests/app/src/android/app/cts/ActivityManagerTest.java
index 277ec3a..61b5cbc 100644
--- a/tests/app/src/android/app/cts/ActivityManagerTest.java
+++ b/tests/app/src/android/app/cts/ActivityManagerTest.java
@@ -80,6 +80,12 @@
 
     private static final String PACKAGE_NAME_APP1 = "com.android.app1";
 
+    private static final String MCC_TO_UPDATE = "987";
+    private static final String MNC_TO_UPDATE = "654";
+    private static final String SHELL_COMMAND_GET_CONFIG = "am get-config";
+    private static final String SHELL_COMMAND_RESULT_CONFIG_NAME_MCC = "mcc";
+    private static final String SHELL_COMMAND_RESULT_CONFIG_NAME_MNC = "mnc";
+
     // Return states of the ActivityReceiverFilter.
     public static final int RESULT_PASS = 1;
     public static final int RESULT_FAIL = 2;
@@ -333,6 +339,11 @@
         Log.d(TAG, "executed[" + cmd + "]; output[" + output.trim() + "]");
     }
 
+    private String executeShellCommand(String cmd) throws IOException {
+        final UiDevice uiDevice = UiDevice.getInstance(mInstrumentation);
+        return uiDevice.executeShellCommand(cmd).trim();
+    }
+
     private void setForcedAppStandby(String packageName, boolean enabled) throws IOException {
         final StringBuilder cmdBuilder = new StringBuilder("appops set ")
                 .append(packageName)
@@ -426,6 +437,62 @@
     }
 
     /**
+     * Due to the corresponding API is hidden in R and will be public in S, this test
+     * is commented and will be un-commented in Android S.
+     *
+    public void testUpdateMccMncConfiguration() throws Exception {
+        // Store the original mcc mnc to set back
+        String[] mccMncConfigOriginal = new String[2];
+        // Store other configs to check they won't be affected
+        Set<String> otherConfigsOriginal = new HashSet<String>();
+        getMccMncConfigsAndOthers(mccMncConfigOriginal, otherConfigsOriginal);
+
+        String[] mccMncConfigToUpdate = new String[] {MCC_TO_UPDATE, MNC_TO_UPDATE};
+        boolean success = ShellIdentityUtils.invokeMethodWithShellPermissions(mActivityManager,
+                (am) -> am.updateMccMncConfiguration(mccMncConfigToUpdate[0],
+                        mccMncConfigToUpdate[1]));
+
+        if (success) {
+            String[] mccMncConfigUpdated = new String[2];
+            Set<String> otherConfigsUpdated = new HashSet<String>();
+            getMccMncConfigsAndOthers(mccMncConfigUpdated, otherConfigsUpdated);
+            // Check the mcc mnc are updated as expected
+            assertTrue(Arrays.equals(mccMncConfigToUpdate, mccMncConfigUpdated));
+            // Check other configs are not changed
+            assertTrue(otherConfigsOriginal.equals(otherConfigsUpdated));
+        }
+
+        // Set mcc mnc configs back in the end of the test
+        ShellIdentityUtils.invokeMethodWithShellPermissions(mActivityManager,
+                (am) -> am.updateMccMncConfiguration(mccMncConfigOriginal[0],
+                        mccMncConfigOriginal[1]));
+    }
+     */
+
+    /**
+     * Due to the corresponding API is hidden in R and will be public in S, this method
+     * for test "testUpdateMccMncConfiguration" is commented and will be un-commented in
+     * Android S.
+     *
+    private void getMccMncConfigsAndOthers(String[] mccMncConfigs, Set<String> otherConfigs)
+            throws Exception {
+        String[] configs = SystemUtil.runShellCommand(
+                mInstrumentation, SHELL_COMMAND_GET_CONFIG).split(" |\\-");
+        for (String config : configs) {
+            if (config.startsWith(SHELL_COMMAND_RESULT_CONFIG_NAME_MCC)) {
+                mccMncConfigs[0] = config.substring(
+                        SHELL_COMMAND_RESULT_CONFIG_NAME_MCC.length());
+            } else if (config.startsWith(SHELL_COMMAND_RESULT_CONFIG_NAME_MNC)) {
+                mccMncConfigs[1] = config.substring(
+                        SHELL_COMMAND_RESULT_CONFIG_NAME_MNC.length());
+            } else {
+                otherConfigs.add(config);
+            }
+        }
+    }
+    */
+
+    /**
      * Simple test for {@link ActivityManager#isUserAMonkey()} - verifies its false.
      *
      * TODO: test positive case
@@ -737,7 +804,11 @@
 
         ActivityReceiverFilter appStartedReceiver = new ActivityReceiverFilter(
                 ACTIVITY_LAUNCHED_ACTION);
+        boolean disabled = "0".equals(executeShellCommand("cmd deviceidle enabled light"));
         try {
+            if (disabled) {
+                executeAndLogShellCommand("cmd deviceidle enable light");
+            }
             intent = new Intent(Intent.ACTION_MAIN);
             intent.setClassName(SIMPLE_PACKAGE_NAME, SIMPLE_PACKAGE_NAME + SIMPLE_ACTIVITY);
             intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
@@ -810,6 +881,9 @@
             toggleScreenOn(true);
             appStartedReceiver.close();
 
+            if (disabled) {
+                executeAndLogShellCommand("cmd deviceidle disable light");
+            }
             SystemUtil.runWithShellPermissionIdentity(() -> {
                 mActivityManager.forceStopPackage(SIMPLE_PACKAGE_NAME);
             });
diff --git a/tests/app/src/android/app/cts/NotificationChannelTest.java b/tests/app/src/android/app/cts/NotificationChannelTest.java
index 184f678..2cc965f 100644
--- a/tests/app/src/android/app/cts/NotificationChannelTest.java
+++ b/tests/app/src/android/app/cts/NotificationChannelTest.java
@@ -225,4 +225,11 @@
         channel.setImportantConversation(true);
         assertTrue(channel.isImportantConversation());
     }
+
+    public void testHasUserSetSound() {
+        NotificationChannel channel = new NotificationChannel("a", "a", IMPORTANCE_DEFAULT);
+        channel.lockFields(NotificationChannel.USER_LOCKED_SOUND);
+
+        assertTrue(channel.hasUserSetSound());
+    }
 }
diff --git a/tests/app/src/android/app/cts/NotificationManagerTest.java b/tests/app/src/android/app/cts/NotificationManagerTest.java
index 0c4d6fe..476b79f 100644
--- a/tests/app/src/android/app/cts/NotificationManagerTest.java
+++ b/tests/app/src/android/app/cts/NotificationManagerTest.java
@@ -450,8 +450,21 @@
         }
     }
 
+    private void setUpNotifListener() {
+        try {
+            toggleListenerAccess(TestNotificationListener.getId(),
+                    InstrumentationRegistry.getInstrumentation(), true);
+            mListener = TestNotificationListener.getInstance();
+            mListener.resetData();
+            assertNotNull(mListener);
+        } catch (IOException e) {
+        }
+    }
+
     private void sendAndVerifyBubble(final int id, Notification.Builder builder,
             Notification.BubbleMetadata data, boolean shouldBeBubble) {
+        setUpNotifListener();
+
         final Intent intent = new Intent(mContext, BubbledActivity.class);
 
         intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_SINGLE_TOP
@@ -478,50 +491,48 @@
         Notification notif = builder.build();
         mNotificationManager.notify(id, notif);
 
-        if (!checkNotificationExistence(id, /*shouldExist=*/ true, shouldBeBubble)) {
-            fail("couldn't find posted notification bubble with id=" + id);
-        }
+        verifyNotificationBubbleState(id, shouldBeBubble);
     }
 
-    private StatusBarNotification getNotification(int id) {
-        // notification is a bit asynchronous so it may take a few ms to appear in
-        // getActiveNotifications()
-        // we will check for it for up to 300ms before giving up
-        for (int tries = 3; tries-- > 0;) {
-            // Need reset flag.
-            final StatusBarNotification[] sbns = mNotificationManager.getActiveNotifications();
-            for (StatusBarNotification sbn : sbns) {
-                if (sbn.getId() == id) {
-                    return sbn;
+    /**
+     * Make sure {@link #setUpNotifListener()} is called prior to sending the notif and verifying
+     * in this method.
+     */
+    private void verifyNotificationBubbleState(int id, boolean shouldBeBubble) {
+        try {
+            // FLAG_BUBBLE relies on notification being posted, wait for notification listener
+            Thread.sleep(500);
+        } catch (InterruptedException ex) {
+        }
+
+        for (StatusBarNotification sbn : mListener.mPosted) {
+            if (sbn.getId() == id) {
+                boolean isBubble = (sbn.getNotification().flags & FLAG_BUBBLE) != 0;
+                if (isBubble != shouldBeBubble) {
+                    final String failure = shouldBeBubble
+                            ? "Notification with id= " + id + " wasn't a bubble"
+                            : "Notification with id= " + id + " was a bubble and shouldn't be";
+                    fail(failure);
+                } else {
+                    // pass
+                    return;
                 }
             }
-            try {
-                Thread.sleep(100);
-            } catch (InterruptedException ex) {
-                // pass
-            }
         }
-        return null;
+        fail("Couldn't find posted notification with id= " + id);
     }
 
     private boolean checkNotificationExistence(int id, boolean shouldExist) {
-        return checkNotificationExistence(id, shouldExist, false /* shouldBeBubble */);
-    }
-
-    private boolean checkNotificationExistence(int id, boolean shouldExist,
-            boolean shouldBeBubble) {
         // notification is a bit asynchronous so it may take a few ms to appear in
         // getActiveNotifications()
         // we will check for it for up to 300ms before giving up
         boolean found = false;
-        boolean isBubble = false;
         for (int tries = 3; tries--> 0;) {
             // Need reset flag.
             found = false;
             final StatusBarNotification[] sbns = mNotificationManager.getActiveNotifications();
             for (StatusBarNotification sbn : sbns) {
-                isBubble = (sbn.getNotification().flags & FLAG_BUBBLE) != 0;
-                Log.d(TAG, "Found " + sbn.getKey() + " Bubble? " + isBubble);
+                Log.d(TAG, "Found " + sbn.getKey());
                 if (sbn.getId() == id) {
                     found = true;
                     break;
@@ -534,7 +545,7 @@
                 // pass
             }
         }
-        return (found == shouldExist) && (isBubble == shouldBeBubble);
+        return found == shouldExist;
     }
 
     private void assertNotificationCount(int expectedCount) {
@@ -825,6 +836,8 @@
             mNotificationManager.setAutomaticZenRuleState(id1, onCondition1);
             mNotificationManager.setAutomaticZenRuleState(id2, onCondition2);
 
+            Thread.sleep(300); // wait for rules to be applied - it's done asynchronously
+
             mRuleIds.add(id1);
             mRuleIds.add(id2);
             assertExpectedDndState(INTERRUPTION_FILTER_PRIORITY);
@@ -2767,7 +2780,7 @@
                 badNumberString);
     }
 
-    public void testNotificationManagerBubblePolicy_flagForMessage_failsNoRemoteInput()
+    public void testNotificationManagerBubblePolicy_flagForMessage_passesNoRemoteInput()
             throws InterruptedException {
         // turn on bubbles globally
         toggleBubbleSetting(true);
@@ -2785,7 +2798,8 @@
                                 SystemClock.currentThreadTimeMillis(), person)
                 )
                 .setSmallIcon(android.R.drawable.sym_def_app_icon);
-        sendAndVerifyBubble(1, nb, null /* use default metadata */, false);
+        boolean shouldBeBubble = !mActivityManager.isLowRamDevice();
+        sendAndVerifyBubble(1, nb, null /* use default metadata */, shouldBeBubble);
     }
 
     public void testNotificationManagerBubblePolicy_flagForMessage_succeeds()
@@ -2829,13 +2843,12 @@
         try {
             // turn on bubbles globally
             toggleBubbleSetting(true);
+
+            setUpNotifListener();
+
             mContext.startService(serviceIntent);
 
-            if (!checkNotificationExistence(BUBBLE_NOTIF_ID,
-                    true /* shouldExist */, false /* shouldBeBubble */)) {
-                fail("found bubble notification id=" + BUBBLE_NOTIF_ID
-                        + " when it should just be a notification");
-            }
+            verifyNotificationBubbleState(BUBBLE_NOTIF_ID, false /* shouldBeBubble */);
         } finally {
             mContext.stopService(serviceIntent);
         }
@@ -2848,14 +2861,13 @@
         try {
             // turn on bubbles globally
             toggleBubbleSetting(true);
+
+            setUpNotifListener();
+
             mContext.startService(serviceIntent);
 
             boolean shouldBeBubble = !mActivityManager.isLowRamDevice();
-            if (!checkNotificationExistence(BUBBLE_NOTIF_ID,
-                    true /* shouldExist */, shouldBeBubble)) {
-                fail("couldn't find posted notification bubble with id=" + BUBBLE_NOTIF_ID);
-            }
-
+            verifyNotificationBubbleState(BUBBLE_NOTIF_ID, shouldBeBubble);
         } finally {
             mContext.stopService(serviceIntent);
         }
@@ -2869,13 +2881,12 @@
         try {
             // turn on bubbles globally
             toggleBubbleSetting(true);
+
+            setUpNotifListener();
+
             mContext.startService(serviceIntent);
 
-            if (!checkNotificationExistence(BUBBLE_NOTIF_ID,
-                    true /* shouldExist */, false /* shouldBeBubble */)) {
-                fail("couldn't find posted notification with id=" + BUBBLE_NOTIF_ID
-                        + " or it was a bubble when it shouldn't be");
-            }
+            verifyNotificationBubbleState(BUBBLE_NOTIF_ID, false /* shouldBeBubble */);
         } finally {
             mContext.stopService(serviceIntent);
         }
@@ -2905,13 +2916,12 @@
         try {
             // turn on bubbles globally
             toggleBubbleSetting(true);
+
+            setUpNotifListener();
+
             mContext.startService(serviceIntent);
 
-            if (!checkNotificationExistence(BUBBLE_NOTIF_ID,
-                    true /* shouldExist */, false /* shouldBeBubble */)) {
-                fail("couldn't find posted notification with id=" + BUBBLE_NOTIF_ID
-                        + " or it was a bubble when it shouldn't be");
-            }
+            verifyNotificationBubbleState(BUBBLE_NOTIF_ID, false /* shouldBeBubble */);
         } finally {
             mContext.stopService(serviceIntent);
         }
@@ -2925,13 +2935,12 @@
         try {
             // turn on bubbles globally
             toggleBubbleSetting(true);
+
+            setUpNotifListener();
+
             mContext.startService(serviceIntent);
 
-            if (!checkNotificationExistence(BUBBLE_NOTIF_ID,
-                    true /* shouldExist */, false /* shouldBeBubble */)) {
-                fail("couldn't find posted notification with id=" + BUBBLE_NOTIF_ID
-                        + " or it was a bubble when it shouldn't be");
-            }
+            verifyNotificationBubbleState(BUBBLE_NOTIF_ID, false /* shouldBeBubble */);
         } finally {
             mContext.stopService(serviceIntent);
         }
@@ -2942,17 +2951,16 @@
             // turn on bubbles globally
             toggleBubbleSetting(true);
 
+            setUpNotifListener();
+
             // Start & get the activity
             SendBubbleActivity a = startSendBubbleActivity();
 
             // Send a bubble that doesn't fulfill policy from foreground
-            a.sendInvalidBubble(4000, false /* autoExpand */);
+            a.sendInvalidBubble(false /* autoExpand */);
 
             // Just because app is foreground, doesn't mean they get to bubble
-            if (!checkNotificationExistence(BUBBLE_NOTIF_ID,
-                    true /* shouldExist */, false /* shouldBeBubble */)) {
-                fail("couldn't find posted notification bubble with id=" + BUBBLE_NOTIF_ID);
-            }
+            verifyNotificationBubbleState(BUBBLE_NOTIF_ID, false /* shouldBeBubble */);
         } finally {
             cleanupSendBubbleActivity();
         }
@@ -2963,6 +2971,8 @@
             // turn on bubbles globally
             toggleBubbleSetting(true);
 
+            setUpNotifListener();
+
             // make ourselves foreground so we can auto-expand the bubble & check the intent flags
             SendBubbleActivity a = startSendBubbleActivity();
 
@@ -2977,10 +2987,7 @@
             a.sendBubble(true /* autoExpand */, false /* suppressNotif */);
 
             boolean shouldBeBubble = !mActivityManager.isLowRamDevice();
-            if (!checkNotificationExistence(BUBBLE_NOTIF_ID,
-                    true /* shouldExist */, shouldBeBubble)) {
-                fail("couldn't find posted notification bubble with id=" + BUBBLE_NOTIF_ID);
-            }
+            verifyNotificationBubbleState(BUBBLE_NOTIF_ID, shouldBeBubble);
 
             InstrumentationRegistry.getInstrumentation().waitForIdleSync();
 
@@ -3046,6 +3053,7 @@
                     .setShortLabel(BUBBLE_SHORTCUT_ID_DYNAMIC)
                     .setIcon(Icon.createWithResource(mContext, R.drawable.icon_black))
                     .setIntent(shortcutIntent)
+                    .setLongLived(true)
                     .build();
             scmanager.addDynamicShortcuts(Arrays.asList(shortcut));
 
@@ -3081,7 +3089,6 @@
 
             boolean shouldBeBubble = !mActivityManager.isLowRamDevice();
             sendAndVerifyBubble(1, nb, data, shouldBeBubble);
-
         } finally {
             // remove the shortcut
             scmanager.removeAllDynamicShortcuts();
@@ -3149,6 +3156,8 @@
             // turn on bubbles globally
             toggleBubbleSetting(true);
 
+            setUpNotifListener();
+
             // Make dynamic shortcut
             Intent shortcutIntent = new Intent(mContext, SendBubbleActivity.class);
             shortcutIntent.setAction(Intent.ACTION_VIEW);
@@ -3156,6 +3165,7 @@
                     .setShortLabel(BUBBLE_SHORTCUT_ID_DYNAMIC)
                     .setIcon(Icon.createWithResource(mContext, R.drawable.icon_black))
                     .setIntent(shortcutIntent)
+                    .setLongLived(true)
                     .build();
             scmanager.addDynamicShortcuts(Arrays.asList(shortcut));
 
@@ -3192,12 +3202,13 @@
             boolean shouldBeBubble = !mActivityManager.isLowRamDevice();
             sendAndVerifyBubble(1, nb, data, shouldBeBubble);
 
+            mListener.resetData();
+
             // Now lets delete the shortcut and make sure the notif has been updated to not
             // be a bubble.
             scmanager.removeAllDynamicShortcuts();
 
-            checkNotificationExistence(1, true /* should exist */, false /* should be bubble */);
-
+            verifyNotificationBubbleState(1, false /* should be bubble */);
         } finally {
             // remove the shortcut
             scmanager.removeAllDynamicShortcuts();
@@ -3209,14 +3220,18 @@
             // turn on bubbles globally
             toggleBubbleSetting(true);
 
+            setUpNotifListener();
+
             // make ourselves foreground so we can specify suppress notification flag
             SendBubbleActivity a = startSendBubbleActivity();
 
             // send the bubble with notification suppressed
             a.sendBubble(false /* autoExpand */, true /* suppressNotif */);
+            boolean shouldBeBubble = !mActivityManager.isLowRamDevice();
+            verifyNotificationBubbleState(BUBBLE_NOTIF_ID, shouldBeBubble);
 
             // check for the notification
-            StatusBarNotification sbnSuppressed = getNotification(BUBBLE_NOTIF_ID);
+            StatusBarNotification sbnSuppressed = mListener.mPosted.get(0);
             assertNotNull(sbnSuppressed);
             // check for suppression state
             Notification.BubbleMetadata metadata =
@@ -3224,11 +3239,14 @@
             assertNotNull(metadata);
             assertTrue(metadata.isNotificationSuppressed());
 
+            mListener.resetData();
+
             // send the bubble with notification NOT suppressed
             a.sendBubble(false /* autoExpand */, false /* suppressNotif */);
+            verifyNotificationBubbleState(BUBBLE_NOTIF_ID, shouldBeBubble);
 
             // check for the notification
-            StatusBarNotification sbnNotSuppressed = getNotification(BUBBLE_NOTIF_ID);
+            StatusBarNotification sbnNotSuppressed = mListener.mPosted.get(0);
             assertNotNull(sbnNotSuppressed);
             // check for suppression state
             metadata = sbnNotSuppressed.getNotification().getBubbleMetadata();
@@ -3239,6 +3257,8 @@
 
             // turn off bubbles globally
             toggleBubbleSetting(false);
+
+            mListener.resetData();
         }
     }
 
diff --git a/tests/appsearch/AndroidManifest.xml b/tests/appsearch/AndroidManifest.xml
deleted file mode 100644
index 7eac46b..0000000
--- a/tests/appsearch/AndroidManifest.xml
+++ /dev/null
@@ -1,26 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-  ~ Copyright (C) 2019 The Android Open Source Project
-  ~
-  ~ Licensed under the Apache License, Version 2.0 (the "License");
-  ~ you may not use this file except in compliance with the License.
-  ~ You may obtain a copy of the License at
-  ~
-  ~      http://www.apache.org/licenses/LICENSE-2.0
-  ~
-  ~ Unless required by applicable law or agreed to in writing, software
-  ~ distributed under the License is distributed on an "AS IS" BASIS,
-  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-  ~ See the License for the specific language governing permissions and
-  ~ limitations under the License.
-  -->
-
-<manifest xmlns:android="http://schemas.android.com/apk/res/android"
-          package="com.android.cts.appsearch" >
-    <application android:label="CtsAppSearchTestCases">
-        <uses-library android:name="android.test.runner"/>
-    </application>
-    <instrumentation android:name="androidx.test.runner.AndroidJUnitRunner"
-                     android:targetPackage="com.android.cts.appsearch"
-                     android:label="CtsAppSearchTestCases"/>
-</manifest>
diff --git a/tests/appsearch/AndroidTest.xml b/tests/appsearch/AndroidTest.xml
deleted file mode 100644
index a86e339..0000000
--- a/tests/appsearch/AndroidTest.xml
+++ /dev/null
@@ -1,32 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-  ~ Copyright (C) 2019 The Android Open Source Project
-  ~
-  ~ Licensed under the Apache License, Version 2.0 (the "License");
-  ~ you may not use this file except in compliance with the License.
-  ~ You may obtain a copy of the License at
-  ~
-  ~      http://www.apache.org/licenses/LICENSE-2.0
-  ~
-  ~ Unless required by applicable law or agreed to in writing, software
-  ~ distributed under the License is distributed on an "AS IS" BASIS,
-  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-  ~ See the License for the specific language governing permissions and
-  ~ limitations under the License.
-  -->
-<configuration description="Config for CTS AppSearch test cases">
-    <option name="test-suite-tag" value="cts" />
-    <option name="config-descriptor:metadata" key="component" value="framework" />
-    <option name="config-descriptor:metadata" key="parameter" value="instant_app" />
-    <option name="config-descriptor:metadata" key="parameter" value="not_multi_abi" />
-    <option name="config-descriptor:metadata" key="parameter" value="secondary_user" />
-
-    <target_preparer class="com.android.tradefed.targetprep.suite.SuiteApkInstaller">
-        <option name="cleanup-apks" value="true" />
-        <option name="test-file-name" value="CtsAppSearchTestCases.apk" />
-    </target_preparer>
-
-    <test class="com.android.tradefed.testtype.AndroidJUnitTest" >
-        <option name="package" value="com.android.cts.appsearch" />
-    </test>
-</configuration>
diff --git a/tests/appsearch/OWNERS b/tests/appsearch/OWNERS
deleted file mode 100644
index cf3ad8a..0000000
--- a/tests/appsearch/OWNERS
+++ /dev/null
@@ -1,2 +0,0 @@
-# Bug component: 755061
-adorokhine@google.com
diff --git a/tests/appsearch/src/com/android/cts/appsearch/AppSearchManagerTest.java b/tests/appsearch/src/com/android/cts/appsearch/AppSearchManagerTest.java
deleted file mode 100644
index 25ee503..0000000
--- a/tests/appsearch/src/com/android/cts/appsearch/AppSearchManagerTest.java
+++ /dev/null
@@ -1,84 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.android.cts.appsearch;
-
-import static com.google.common.truth.Truth.assertThat;
-
-import android.app.appsearch.AppSearchBatchResult;
-import android.app.appsearch.AppSearchEmail;
-import android.app.appsearch.AppSearchManager;
-import android.app.appsearch.AppSearchSchema;
-import android.app.appsearch.AppSearchSchema.PropertyConfig;
-import android.content.Context;
-
-import androidx.test.ext.junit.runners.AndroidJUnit4;
-import androidx.test.platform.app.InstrumentationRegistry;
-
-import com.google.common.collect.ImmutableList;
-
-import org.junit.Test;
-import org.junit.runner.RunWith;
-
-@RunWith(AndroidJUnit4.class)
-public class AppSearchManagerTest {
-    private final Context mContext = InstrumentationRegistry.getInstrumentation().getContext();
-    private final AppSearchManager mAppSearch = mContext.getSystemService(AppSearchManager.class);
-
-    @Test
-    public void testGetService() {
-        assertThat(mContext.getSystemService(Context.APP_SEARCH_SERVICE)).isNotNull();
-        assertThat(mContext.getSystemService(AppSearchManager.class)).isNotNull();
-        assertThat(mAppSearch).isNotNull();
-    }
-
-    @Test
-    public void testSetSchema() {
-        AppSearchSchema emailSchema = AppSearchSchema.newBuilder("Email")
-                .addProperty(AppSearchSchema.newPropertyBuilder("subject")
-                        .setDataType(PropertyConfig.DATA_TYPE_STRING)
-                        .setCardinality(PropertyConfig.CARDINALITY_OPTIONAL)
-                        .setIndexingType(PropertyConfig.INDEXING_TYPE_PREFIXES)
-                        .setTokenizerType(PropertyConfig.TOKENIZER_TYPE_PLAIN)
-                        .build()
-                ).addProperty(AppSearchSchema.newPropertyBuilder("body")
-                        .setDataType(PropertyConfig.DATA_TYPE_STRING)
-                        .setCardinality(PropertyConfig.CARDINALITY_OPTIONAL)
-                        .setIndexingType(PropertyConfig.INDEXING_TYPE_PREFIXES)
-                        .setTokenizerType(PropertyConfig.TOKENIZER_TYPE_PLAIN)
-                        .build()
-                ).build();
-        mAppSearch.setSchema(emailSchema);
-    }
-
-    @Test
-    public void testPutDocuments() throws Exception {
-        // Schema registration
-        mAppSearch.setSchema(AppSearchEmail.SCHEMA);
-
-        // Index a document
-        AppSearchEmail email = new AppSearchEmail.Builder("uri1")
-                .setFrom("from@example.com")
-                .setTo("to1@example.com", "to2@example.com")
-                .setSubject("testPut example")
-                .setBody("This is the body of the testPut email")
-                .build();
-
-        AppSearchBatchResult result = mAppSearch.putDocuments(ImmutableList.of(email));
-        assertThat(result.isSuccess()).isTrue();
-        assertThat(result.getResults()).containsExactly("uri1", null);
-        assertThat(result.getFailures()).isEmpty();
-    }
-}
diff --git a/tests/autofillservice/src/android/autofillservice/cts/CannedFillResponse.java b/tests/autofillservice/src/android/autofillservice/cts/CannedFillResponse.java
index cd099d7..aa751a2 100644
--- a/tests/autofillservice/src/android/autofillservice/cts/CannedFillResponse.java
+++ b/tests/autofillservice/src/android/autofillservice/cts/CannedFillResponse.java
@@ -596,7 +596,7 @@
             final Dataset.Builder builder = mPresentation != null
                     ? mInlinePresentation == null
                     ? new Dataset.Builder(mPresentation)
-                    : new Dataset.Builder(mPresentation, mInlinePresentation)
+                    : new Dataset.Builder(mPresentation).setInlinePresentation(mInlinePresentation)
                     : mInlinePresentation == null
                             ? new Dataset.Builder()
                             : new Dataset.Builder(mInlinePresentation);
@@ -631,7 +631,7 @@
                         }
                     } else {
                         if (inlinePresentation != null) {
-                            builder.setInlinePresentation(autofillId, value,
+                            builder.setFieldInlinePresentation(autofillId, value,
                                     filter != null ? filter.second : null, inlinePresentation);
                         } else {
                             if (filter == null) {
diff --git a/tests/autofillservice/src/android/autofillservice/cts/CustomDescriptionWithLinkTestCase.java b/tests/autofillservice/src/android/autofillservice/cts/CustomDescriptionWithLinkTestCase.java
index de7a266..5806234 100644
--- a/tests/autofillservice/src/android/autofillservice/cts/CustomDescriptionWithLinkTestCase.java
+++ b/tests/autofillservice/src/android/autofillservice/cts/CustomDescriptionWithLinkTestCase.java
@@ -89,6 +89,7 @@
     public final void testTapLink_changeOrientationThenTapBack() throws Exception {
         assumeTrue("Rotation is supported", Helper.isRotationSupported(mContext));
 
+        mUiBot.assumeMinimumResolution(500);
         mUiBot.setScreenOrientation(UiBot.PORTRAIT);
         try {
             saveUiRestoredAfterTappingLinkTest(
diff --git a/tests/autofillservice/src/android/autofillservice/cts/DatasetTest.java b/tests/autofillservice/src/android/autofillservice/cts/DatasetTest.java
index c9434cb..43c8e06 100644
--- a/tests/autofillservice/src/android/autofillservice/cts/DatasetTest.java
+++ b/tests/autofillservice/src/android/autofillservice/cts/DatasetTest.java
@@ -58,22 +58,29 @@
     @Test
     public void testBuilder_nullPresentation() {
         assertThrows(NullPointerException.class, () -> new Dataset.Builder((RemoteViews) null));
-        assertThrows(NullPointerException.class, () -> new Dataset.Builder(null,
-                mInlinePresentation));
     }
 
     @Test
     public void testBuilder_nullInlinePresentation() {
         assertThrows(NullPointerException.class,
                 () -> new Dataset.Builder((InlinePresentation) null));
-        assertThrows(NullPointerException.class, () -> new Dataset.Builder(mPresentation, null));
     }
 
     @Test
     public void testBuilder_validPresentations() {
         assertThat(new Dataset.Builder(mPresentation)).isNotNull();
         assertThat(new Dataset.Builder(mInlinePresentation)).isNotNull();
-        assertThat(new Dataset.Builder(mPresentation, mInlinePresentation)).isNotNull();
+    }
+
+    @Test
+    public void testBuilder_setNullInlinePresentation() {
+        final Dataset.Builder builder = new Dataset.Builder(mPresentation);
+        assertThrows(NullPointerException.class, () -> builder.setInlinePresentation(null));
+    }
+
+    @Test
+    public void testBuilder_setInlinePresentation() {
+        assertThat(new Dataset.Builder().setInlinePresentation(mInlinePresentation)).isNotNull();
     }
 
     @Test
@@ -163,8 +170,8 @@
     }
 
     @Test
-    public void testBuilder_setInlinePresentations() {
-        assertThat(new Dataset.Builder().setInlinePresentation(mId, mValue, mFilter,
+    public void testBuilder_setFieldInlinePresentations() {
+        assertThat(new Dataset.Builder().setFieldInlinePresentation(mId, mValue, mFilter,
                 mInlinePresentation)).isNotNull();
     }
 
@@ -180,6 +187,8 @@
         builder.setValue(mId, mValue, mPresentation);
         assertThat(builder.build()).isNotNull();
         assertThrows(IllegalStateException.class, () -> builder.build());
+        assertThrows(IllegalStateException.class,
+                () -> builder.setInlinePresentation(mInlinePresentation));
         assertThrows(IllegalStateException.class, () -> builder.setValue(mId, mValue));
         assertThrows(IllegalStateException.class,
                 () -> builder.setValue(mId, mValue, mPresentation));
@@ -192,6 +201,7 @@
         assertThrows(IllegalStateException.class,
                 () -> builder.setValue(mId, mValue, mFilter, mPresentation, mInlinePresentation));
         assertThrows(IllegalStateException.class,
-                () -> builder.setInlinePresentation(mId, mValue, mFilter, mInlinePresentation));
+                () -> builder.setFieldInlinePresentation(mId, mValue, mFilter,
+                        mInlinePresentation));
     }
 }
diff --git a/tests/autofillservice/src/android/autofillservice/cts/augmented/AugmentedLoginActivityTest.java b/tests/autofillservice/src/android/autofillservice/cts/augmented/AugmentedLoginActivityTest.java
index 70a4818..99cfcf7 100644
--- a/tests/autofillservice/src/android/autofillservice/cts/augmented/AugmentedLoginActivityTest.java
+++ b/tests/autofillservice/src/android/autofillservice/cts/augmented/AugmentedLoginActivityTest.java
@@ -527,10 +527,10 @@
                 .build());
         mActivity.onPassword(View::requestFocus);
         mUiBot.assertNoDatasetsEver();
-        final AugmentedFillRequest request2 = sAugmentedReplier.getNextFillRequest();
-        assertBasicRequestInfo(request2, mActivity, passwordId, passwordValue);
 
-        mAugmentedUiBot.assertUiShown(passwordId, "req2");
+        // (TODO: b/141703197) password request temp disabled.
+        mAugmentedUiBot.assertUiGone();
+        sAugmentedReplier.reset();
 
         // Tap on username again...
         sAugmentedReplier.addResponse(new CannedAugmentedFillResponse.Builder()
@@ -643,11 +643,11 @@
                 .build());
         mActivity.onPassword(View::requestFocus);
         mUiBot.assertNoDatasetsEver();
-        final AugmentedFillRequest request2 = sAugmentedReplier.getNextFillRequest();
-        assertBasicRequestInfo(request2, mActivity, passwordId, passwordValue);
 
-        callback.assertUiShownEvent(password);
-        mAugmentedUiBot.assertUiShown(passwordId, "req2");
+        // (TODO: b/141703197) password request temp disabled.
+        callback.assertNotCalled();
+        mAugmentedUiBot.assertUiGone();
+        sAugmentedReplier.reset();
 
         // Tap on username again...
         sAugmentedReplier.addResponse(new CannedAugmentedFillResponse.Builder()
@@ -661,13 +661,14 @@
         final AugmentedFillRequest request3 = sAugmentedReplier.getNextFillRequest();
         assertBasicRequestInfo(request3, mActivity, usernameId, usernameValue);
         final UiObject2 ui = mAugmentedUiBot.assertUiShown(usernameId, "Augment Me");
+        callback.assertUiShownEvent(username);
 
         // ...and autofill this time
         mActivity.expectAutoFill("dude", "sweet");
         ui.click();
         mActivity.assertAutoFilled();
         mAugmentedUiBot.assertUiGone();
-        callback.assertUiHiddenEvent(password);
+        callback.assertUiHiddenEvent(username);
     }
 
     @Test
diff --git a/tests/autofillservice/src/android/autofillservice/cts/augmented/CannedAugmentedFillResponse.java b/tests/autofillservice/src/android/autofillservice/cts/augmented/CannedAugmentedFillResponse.java
index 580816d..5a312ef 100644
--- a/tests/autofillservice/src/android/autofillservice/cts/augmented/CannedAugmentedFillResponse.java
+++ b/tests/autofillservice/src/android/autofillservice/cts/augmented/CannedAugmentedFillResponse.java
@@ -177,7 +177,7 @@
                         new android.service.autofill.Dataset.Builder();
                 for (Pair<AutofillId, AutofillValue> pair : dataset.getValues()) {
                     final AutofillId id = pair.first;
-                    datasetBuilder.setInlinePresentation(id, pair.second, null,
+                    datasetBuilder.setFieldInlinePresentation(id, pair.second, null,
                             dataset.mFieldPresentationById.get(id));
                 }
                 list.add(datasetBuilder.build());
diff --git a/tests/autofillservice/src/android/autofillservice/cts/inline/InlineFilteringTest.java b/tests/autofillservice/src/android/autofillservice/cts/inline/InlineFilteringTest.java
index 1e47dd0..67d7a35 100644
--- a/tests/autofillservice/src/android/autofillservice/cts/inline/InlineFilteringTest.java
+++ b/tests/autofillservice/src/android/autofillservice/cts/inline/InlineFilteringTest.java
@@ -99,6 +99,9 @@
         mUiBot.assertSuggestionStrip(1);
 
         mUiBot.selectSuggestion(0);
+        // TODO(b/151702075): Find a better way to wait for the views to update.
+        Thread.sleep(/* millis= */ 1000);
+        mUiBot.waitForIdle();
         mActivity.assertAutoFilled();
     }
 }
diff --git a/tests/camera/src/android/hardware/camera2/cts/ConcurrentCameraTest.java b/tests/camera/src/android/hardware/camera2/cts/ConcurrentCameraTest.java
index 05118b1..ebff2dd 100644
--- a/tests/camera/src/android/hardware/camera2/cts/ConcurrentCameraTest.java
+++ b/tests/camera/src/android/hardware/camera2/cts/ConcurrentCameraTest.java
@@ -186,7 +186,7 @@
     /**
      * Generates a list of combinations used for mandatory stream combination testing.
      * Each combination(GeneratedEntry) corresponds to a camera id advertised by
-     * getConcurrentStreamingCameraIds().
+     * getConcurrentCameraIds().
      */
     private List<HashMap<String, GeneratedEntry>> generateStreamSelections(
             Set<String> cameraIdCombination) {
diff --git a/tests/camera/src/android/hardware/camera2/cts/testcases/Camera2ConcurrentAndroidTestCase.java b/tests/camera/src/android/hardware/camera2/cts/testcases/Camera2ConcurrentAndroidTestCase.java
index 8877343..c35e8d5 100644
--- a/tests/camera/src/android/hardware/camera2/cts/testcases/Camera2ConcurrentAndroidTestCase.java
+++ b/tests/camera/src/android/hardware/camera2/cts/testcases/Camera2ConcurrentAndroidTestCase.java
@@ -124,7 +124,7 @@
             }
         }
         mConcurrentCameraIdCombinations =
-                CameraTestUtils.getConcurrentStreamingCameraIds(mCameraManager, mAdoptShellPerm);
+                CameraTestUtils.getConcurrentCameraIds(mCameraManager, mAdoptShellPerm);
         assertNotNull("Unable to get concurrent camera combinations",
                 mConcurrentCameraIdCombinations);
         mCameraTestInfos = new HashMap<String, CameraTestInfo>();
diff --git a/tests/camera/utils/src/android/hardware/camera2/cts/CameraTestUtils.java b/tests/camera/utils/src/android/hardware/camera2/cts/CameraTestUtils.java
index 4edd936..f64ff08 100644
--- a/tests/camera/utils/src/android/hardware/camera2/cts/CameraTestUtils.java
+++ b/tests/camera/utils/src/android/hardware/camera2/cts/CameraTestUtils.java
@@ -849,11 +849,11 @@
         return idsForTesting.toArray(new String[idsForTesting.size()]);
     }
 
-    public static Set<Set<String>> getConcurrentStreamingCameraIds(CameraManager manager,
+    public static Set<Set<String>> getConcurrentCameraIds(CameraManager manager,
             boolean getSystemCameras)
             throws CameraAccessException {
         Set<String> cameraIds = new HashSet<String>(Arrays.asList(getCameraIdListForTesting(manager, getSystemCameras)));
-        Set<Set<String>> combinations =  manager.getConcurrentStreamingCameraIds();
+        Set<Set<String>> combinations =  manager.getConcurrentCameraIds();
         Set<Set<String>> correctComb = new HashSet<Set<String>>();
         for (Set<String> comb : combinations) {
             Set<String> filteredIds = new HashSet<String>();
diff --git a/tests/framework/base/windowmanager/AndroidManifest.xml b/tests/framework/base/windowmanager/AndroidManifest.xml
index bf7b209..c3d5bce 100644
--- a/tests/framework/base/windowmanager/AndroidManifest.xml
+++ b/tests/framework/base/windowmanager/AndroidManifest.xml
@@ -165,8 +165,6 @@
         <activity android:name="android.server.wm.lifecycle.ActivityLifecycleClientTestBase$TransitionDestinationActivity"
                   android:theme="@style/window_activity_transitions" />
 
-        <activity android:name="android.server.wm.StartActivityTests$TestActivity2" />
-
         <activity android:name="android.server.wm.MultiDisplaySystemDecorationTests$ImeTestActivity"
                   android:resizeableActivity="true"
                   android:configChanges="orientation|screenSize|smallestScreenSize|screenLayout|colorMode|density|touchscreen" />
diff --git a/tests/framework/base/windowmanager/app/AndroidManifest.xml b/tests/framework/base/windowmanager/app/AndroidManifest.xml
index 507859b..67cae55 100755
--- a/tests/framework/base/windowmanager/app/AndroidManifest.xml
+++ b/tests/framework/base/windowmanager/app/AndroidManifest.xml
@@ -162,6 +162,16 @@
                   android:configChanges="orientation|screenSize|smallestScreenSize|screenLayout"
                   android:exported="true"
         />
+        <activity android:name=".PipActivityWithMinimalSize"
+                  android:resizeableActivity="false"
+                  android:supportsPictureInPicture="true"
+                  android:configChanges="orientation|screenSize|smallestScreenSize|screenLayout"
+                  android:exported="true"
+                  android:taskAffinity="nobody.but.PipActivity">
+                  <layout android:minWidth="100dp"
+                          android:minHeight="80dp"
+                  />
+        </activity>
         <activity android:name=".FreeformActivity"
                   android:resizeableActivity="true"
                   android:taskAffinity="nobody.but.FreeformActivity"
@@ -544,6 +554,14 @@
            </intent-filter>
         </service>
 
+        <activity android:name=".HostActivity"
+                  android:exported="true">
+            <intent-filter>
+                <action android:name="android.server.wm.app.HostActivity"></action>
+            </intent-filter>
+        </activity>
+        <service android:name=".RenderService"
+                 android:process=".render_process" />
         <activity
             android:name=".ClickableToastActivity"
             android:exported="true" />
diff --git a/tests/framework/base/windowmanager/app/src/android/server/wm/app/Components.java b/tests/framework/base/windowmanager/app/src/android/server/wm/app/Components.java
index 8a06a46..b5e8de2 100644
--- a/tests/framework/base/windowmanager/app/src/android/server/wm/app/Components.java
+++ b/tests/framework/base/windowmanager/app/src/android/server/wm/app/Components.java
@@ -50,6 +50,7 @@
     public static final ComponentName FONT_SCALE_NO_RELAUNCH_ACTIVITY =
             component("FontScaleNoRelaunchActivity");
     public static final ComponentName FREEFORM_ACTIVITY = component("FreeformActivity");
+    public static final ComponentName HOST_ACTIVITY = component("HostActivity");
     public static final ComponentName KEYGUARD_LOCK_ACTIVITY = component("KeyguardLockActivity");
     public static final ComponentName LANDSCAPE_ORIENTATION_ACTIVITY =
             component("LandscapeOrientationActivity");
@@ -76,6 +77,8 @@
     public static final ComponentName PRESENTATION_ACTIVITY = component("PresentationActivity");
     public static final ComponentName PIP_ACTIVITY = component("PipActivity");
     public static final ComponentName PIP_ACTIVITY2 = component("PipActivity2");
+    public static final ComponentName PIP_ACTIVITY_WITH_MINIMAL_SIZE = component(
+            "PipActivityWithMinimalSize");
     public static final ComponentName PIP_ACTIVITY_WITH_SAME_AFFINITY =
             component("PipActivityWithSameAffinity");
     public static final ComponentName PIP_ON_STOP_ACTIVITY = component("PipOnStopActivity");
@@ -445,6 +448,10 @@
         public static final String PROCESS_NAME = ".unresponsive_activity_process";
     }
 
+    public static class RenderService {
+        public static final String PROCESS_NAME = ".render_process";
+    }
+
     /**
      * Extra key constants for {@link android.server.wm.app.VirtualDisplayActivity}.
      *
diff --git a/tests/framework/base/windowmanager/app/src/android/server/wm/app/HostActivity.java b/tests/framework/base/windowmanager/app/src/android/server/wm/app/HostActivity.java
new file mode 100644
index 0000000..11354fb
--- /dev/null
+++ b/tests/framework/base/windowmanager/app/src/android/server/wm/app/HostActivity.java
@@ -0,0 +1,105 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.server.wm.app;
+
+import static android.server.wm.app.Components.UnresponsiveActivity.EXTRA_ON_MOTIONEVENT_DELAY_MS;
+import static android.server.wm.app.RenderService.BROADCAST_EMBED_CONTENT;
+import static android.server.wm.app.RenderService.EXTRAS_BUNDLE;
+import static android.server.wm.app.RenderService.EXTRAS_DISPLAY_ID;
+import static android.server.wm.app.RenderService.EXTRAS_HOST_TOKEN;
+import static android.server.wm.app.RenderService.EXTRAS_SURFACE_PACKAGE;
+
+import android.app.Activity;
+import android.content.BroadcastReceiver;
+import android.content.ComponentName;
+import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.content.ServiceConnection;
+import android.os.Bundle;
+import android.os.IBinder;
+import android.view.SurfaceControlViewHost.SurfacePackage;
+import android.view.SurfaceHolder;
+import android.view.SurfaceView;
+import android.view.ViewGroup;
+import android.widget.RelativeLayout;
+
+public class HostActivity extends Activity implements SurfaceHolder.Callback{
+    private SurfaceView mSurfaceView;
+
+    private ServiceConnection mConnection = new ServiceConnection() {
+        @Override
+        public void onServiceConnected(ComponentName name, IBinder service) {}
+
+        @Override
+        public void onServiceDisconnected(ComponentName className) {}
+    };
+
+    private BroadcastReceiver receiver = new BroadcastReceiver() {
+        @Override
+        public void onReceive(Context context, Intent intent) {
+            SurfacePackage surfacePackage =
+                    intent.getParcelableExtra(EXTRAS_SURFACE_PACKAGE);
+            if (surfacePackage != null) {
+                mSurfaceView.setChildSurfacePackage(surfacePackage);
+            }
+        }
+    };
+
+    @Override
+    public void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+
+        IntentFilter filter = new IntentFilter();
+        filter.addAction(BROADCAST_EMBED_CONTENT);
+        registerReceiver(receiver, filter);
+
+        final RelativeLayout content = new RelativeLayout(this);
+        mSurfaceView = new SurfaceView(this);
+        mSurfaceView.setZOrderOnTop(true);
+        content.addView(mSurfaceView,
+                new RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.MATCH_PARENT,
+                        RelativeLayout.LayoutParams.MATCH_PARENT));
+        setContentView(content, new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT,
+                ViewGroup.LayoutParams.MATCH_PARENT));
+        mSurfaceView.getHolder().addCallback(this);
+    }
+
+    @Override
+    protected void onPause() {
+        unregisterReceiver(receiver);
+        super.onPause();
+    }
+
+    @Override
+    public void surfaceCreated(SurfaceHolder holder) {
+        Intent mIntent =  new Intent(this, RenderService.class);
+        Bundle b = new Bundle();
+        b.putBinder(EXTRAS_HOST_TOKEN, mSurfaceView.getHostToken());
+        b.putInt(EXTRAS_DISPLAY_ID, getDisplayId());
+        b.putInt(EXTRA_ON_MOTIONEVENT_DELAY_MS,
+                getIntent().getIntExtra(EXTRA_ON_MOTIONEVENT_DELAY_MS, 2000));
+        mIntent.putExtra(EXTRAS_BUNDLE, b);
+        bindService(mIntent, mConnection, Context.BIND_AUTO_CREATE|Context.BIND_IMPORTANT);
+    }
+
+    @Override
+    public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {}
+
+    @Override
+    public void surfaceDestroyed(SurfaceHolder holder) {}
+}
diff --git a/apps/CtsVerifier/jni/audio_loopback/audio_utils/roundup.h b/tests/framework/base/windowmanager/app/src/android/server/wm/app/PipActivityWithMinimalSize.java
similarity index 61%
rename from apps/CtsVerifier/jni/audio_loopback/audio_utils/roundup.h
rename to tests/framework/base/windowmanager/app/src/android/server/wm/app/PipActivityWithMinimalSize.java
index ad34289..8c573c0 100644
--- a/apps/CtsVerifier/jni/audio_loopback/audio_utils/roundup.h
+++ b/tests/framework/base/windowmanager/app/src/android/server/wm/app/PipActivityWithMinimalSize.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2012 The Android Open Source Project
+ * Copyright (C) 2020 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -11,21 +11,14 @@
  * 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.
+ * limitations under the License
  */
 
-#ifndef ANDROID_AUDIO_ROUNDUP_H
-#define ANDROID_AUDIO_ROUNDUP_H
+package android.server.wm.app;
 
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-// Round up to the next highest power of 2
-unsigned roundup(unsigned v);
-
-#ifdef __cplusplus
+/**
+ * An activity that has the same behavior as {@link PipActivity} and specifies
+ * minimal dimension in its manifest.
+ */
+public class PipActivityWithMinimalSize extends PipActivity {
 }
-#endif
-
-#endif  // ANDROID_AUDIO_ROUNDUP_H
diff --git a/tests/framework/base/windowmanager/app/src/android/server/wm/app/RenderService.java b/tests/framework/base/windowmanager/app/src/android/server/wm/app/RenderService.java
new file mode 100644
index 0000000..58da2d4
--- /dev/null
+++ b/tests/framework/base/windowmanager/app/src/android/server/wm/app/RenderService.java
@@ -0,0 +1,95 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.server.wm.app;
+
+import static android.server.wm.app.Components.UnresponsiveActivity.EXTRA_ON_MOTIONEVENT_DELAY_MS;
+import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION;
+
+import android.app.Service;
+import android.content.Context;
+import android.content.Intent;
+import android.graphics.PixelFormat;
+import android.hardware.display.DisplayManager;
+import android.os.Bundle;
+import android.os.IBinder;
+import android.os.SystemClock;
+import android.util.DisplayMetrics;
+import android.view.Display;
+import android.view.MotionEvent;
+import android.view.SurfaceControlViewHost;
+import android.view.View;
+import android.view.WindowManager;
+import android.widget.Button;
+
+public class RenderService extends Service {
+    static final String EXTRAS_BUNDLE = "INTENT_BUNDLE";
+    static final String EXTRAS_DISPLAY_ID = "hostDisplayId";
+    static final String EXTRAS_HOST_TOKEN = "hostInputToken";
+    static final String BROADCAST_EMBED_CONTENT
+            = "android.server.wm.app.RenderService.EMBED_CONTENT";
+    static final String EXTRAS_SURFACE_PACKAGE = "surfacePackage";
+
+    private int mOnMotionEventDelayMs;
+
+    private boolean onTouch(View v, MotionEvent event) {
+        SystemClock.sleep(mOnMotionEventDelayMs);
+        // Don't consume the event.
+        return false;
+    }
+
+    @Override
+    public IBinder onBind(Intent intent) {
+        Bundle b = intent.getBundleExtra(EXTRAS_BUNDLE);
+        IBinder hostToken = b.getBinder(EXTRAS_HOST_TOKEN);
+        int hostDisplayId = b.getInt(EXTRAS_DISPLAY_ID);
+        mOnMotionEventDelayMs = b.getInt(EXTRA_ON_MOTIONEVENT_DELAY_MS);
+
+        SurfaceControlViewHost surfaceControlViewHost = getSurfaceControlViewHost(hostToken,
+                hostDisplayId);
+        sendSurfacePackage(surfaceControlViewHost.getSurfacePackage());
+        return null;
+    }
+
+    private SurfaceControlViewHost getSurfaceControlViewHost(IBinder hostToken, int hostDisplayId) {
+        final Context displayContext = getDisplayContext(hostDisplayId);
+        SurfaceControlViewHost surfaceControlViewHost =
+                new SurfaceControlViewHost(displayContext, displayContext.getDisplay(), hostToken);
+
+        View embeddedView = new Button(this);
+        embeddedView.setOnTouchListener(this::onTouch);
+        DisplayMetrics metrics = new DisplayMetrics();
+        displayContext.getDisplay().getMetrics(metrics);
+        WindowManager.LayoutParams lp = new WindowManager.LayoutParams(metrics.widthPixels,
+                metrics.heightPixels, TYPE_APPLICATION, 0,
+                PixelFormat.OPAQUE);
+        surfaceControlViewHost.setView(embeddedView, lp);
+        return surfaceControlViewHost;
+    }
+
+    private Context getDisplayContext(int hostDisplayId) {
+        final DisplayManager displayManager = getSystemService(DisplayManager.class);
+        final Display targetDisplay = displayManager.getDisplay(hostDisplayId);
+        return createDisplayContext(targetDisplay);
+    }
+
+    private void sendSurfacePackage(SurfaceControlViewHost.SurfacePackage surfacePackage) {
+        Intent broadcast = new Intent();
+        broadcast.setAction(BROADCAST_EMBED_CONTENT);
+        broadcast.putExtra(EXTRAS_SURFACE_PACKAGE, surfacePackage);
+        sendBroadcast(broadcast);
+    }
+}
diff --git a/tests/framework/base/windowmanager/intent_tests/clearCases/clear-task_with_new-task.json b/tests/framework/base/windowmanager/intent_tests/clearCases/clear-task_with_new-task.json
index 09753b8..9fd5204 100644
--- a/tests/framework/base/windowmanager/intent_tests/clearCases/clear-task_with_new-task.json
+++ b/tests/framework/base/windowmanager/intent_tests/clearCases/clear-task_with_new-task.json
@@ -18,37 +18,29 @@
         ]
     },
     "initialState": {
-        "stacks": [
+        "tasks": [
             {
-                "tasks": [
+                "activities": [
                     {
-                        "activities": [
-                            {
-                                "name": "android.server.wm.cts\/android.server.wm.intent.Activities$RegularActivity",
-                                "state": "RESUMED"
-                            }
-                        ]
+                        "name": "android.server.wm.cts/android.server.wm.intent.Activities$RegularActivity",
+                        "state": "RESUMED"
                     }
-                ],
-                "resumedActivity": "android.server.wm.cts\/android.server.wm.intent.Activities$RegularActivity"
+                ]
             }
-        ]
+        ],
+        "resumedActivity": "android.server.wm.cts/android.server.wm.intent.Activities$RegularActivity"
     },
     "endState": {
-        "stacks": [
+        "tasks": [
             {
-                "tasks": [
+                "activities": [
                     {
-                        "activities": [
-                            {
-                                "name": "android.server.wm.cts\/android.server.wm.intent.Activities$RegularActivity",
-                                "state": "RESUMED"
-                            }
-                        ]
+                        "name": "android.server.wm.cts/android.server.wm.intent.Activities$RegularActivity",
+                        "state": "RESUMED"
                     }
-                ],
-                "resumedActivity": "android.server.wm.cts\/android.server.wm.intent.Activities$RegularActivity"
+                ]
             }
-        ]
+        ],
+        "resumedActivity": "android.server.wm.cts/android.server.wm.intent.Activities$RegularActivity"
     }
-}
+}
\ No newline at end of file
diff --git a/tests/framework/base/windowmanager/intent_tests/clearCases/clear-task_without_new-task.json b/tests/framework/base/windowmanager/intent_tests/clearCases/clear-task_without_new-task.json
index da82d52..58c719f 100644
--- a/tests/framework/base/windowmanager/intent_tests/clearCases/clear-task_without_new-task.json
+++ b/tests/framework/base/windowmanager/intent_tests/clearCases/clear-task_without_new-task.json
@@ -18,41 +18,33 @@
         ]
     },
     "initialState": {
-        "stacks": [
+        "tasks": [
             {
-                "tasks": [
+                "activities": [
                     {
-                        "activities": [
-                            {
-                                "name": "android.server.wm.cts\/android.server.wm.intent.Activities$RegularActivity",
-                                "state": "RESUMED"
-                            }
-                        ]
+                        "name": "android.server.wm.cts/android.server.wm.intent.Activities$RegularActivity",
+                        "state": "RESUMED"
                     }
-                ],
-                "resumedActivity": "android.server.wm.cts\/android.server.wm.intent.Activities$RegularActivity"
+                ]
             }
-        ]
+        ],
+        "resumedActivity": "android.server.wm.cts/android.server.wm.intent.Activities$RegularActivity"
     },
     "endState": {
-        "stacks": [
+        "tasks": [
             {
-                "tasks": [
+                "activities": [
                     {
-                        "activities": [
-                            {
-                                "name": "android.server.wm.cts\/android.server.wm.intent.Activities$RegularActivity",
-                                "state": "RESUMED"
-                            },
-                            {
-                                "name": "android.server.wm.cts\/android.server.wm.intent.Activities$RegularActivity",
-                                "state": "STOPPED"
-                            }
-                        ]
+                        "name": "android.server.wm.cts/android.server.wm.intent.Activities$RegularActivity",
+                        "state": "RESUMED"
+                    },
+                    {
+                        "name": "android.server.wm.cts/android.server.wm.intent.Activities$RegularActivity",
+                        "state": "STOPPED"
                     }
-                ],
-                "resumedActivity": "android.server.wm.cts\/android.server.wm.intent.Activities$RegularActivity"
+                ]
             }
-        ]
+        ],
+        "resumedActivity": "android.server.wm.cts/android.server.wm.intent.Activities$RegularActivity"
     }
-}
+}
\ No newline at end of file
diff --git a/tests/framework/base/windowmanager/intent_tests/clearCases/test-1.json b/tests/framework/base/windowmanager/intent_tests/clearCases/test-1.json
index 0ee6cc8..10d9a4a 100644
--- a/tests/framework/base/windowmanager/intent_tests/clearCases/test-1.json
+++ b/tests/framework/base/windowmanager/intent_tests/clearCases/test-1.json
@@ -18,37 +18,29 @@
         ]
     },
     "initialState": {
-        "stacks": [
+        "tasks": [
             {
-                "tasks": [
+                "activities": [
                     {
-                        "activities": [
-                            {
-                                "name": "android.server.wm.cts\/android.server.wm.intent.Activities$RegularActivity",
-                                "state": "RESUMED"
-                            }
-                        ]
+                        "name": "android.server.wm.cts/android.server.wm.intent.Activities$RegularActivity",
+                        "state": "RESUMED"
                     }
-                ],
-                "resumedActivity": "android.server.wm.cts\/android.server.wm.intent.Activities$RegularActivity"
+                ]
             }
-        ]
+        ],
+        "resumedActivity": "android.server.wm.cts/android.server.wm.intent.Activities$RegularActivity"
     },
     "endState": {
-        "stacks": [
+        "tasks": [
             {
-                "tasks": [
+                "activities": [
                     {
-                        "activities": [
-                            {
-                                "name": "android.server.wm.cts\/android.server.wm.intent.Activities$RegularActivity",
-                                "state": "RESUMED"
-                            }
-                        ]
+                        "name": "android.server.wm.cts/android.server.wm.intent.Activities$RegularActivity",
+                        "state": "RESUMED"
                     }
-                ],
-                "resumedActivity": "android.server.wm.cts\/android.server.wm.intent.Activities$RegularActivity"
+                ]
             }
-        ]
+        ],
+        "resumedActivity": "android.server.wm.cts/android.server.wm.intent.Activities$RegularActivity"
     }
-}
+}
\ No newline at end of file
diff --git a/tests/framework/base/windowmanager/intent_tests/clearCases/test-2.json b/tests/framework/base/windowmanager/intent_tests/clearCases/test-2.json
index 35fadcc..901e618 100644
--- a/tests/framework/base/windowmanager/intent_tests/clearCases/test-2.json
+++ b/tests/framework/base/windowmanager/intent_tests/clearCases/test-2.json
@@ -24,45 +24,37 @@
         ]
     },
     "initialState": {
-        "stacks": [
+        "tasks": [
             {
-                "tasks": [
+                "activities": [
                     {
-                        "activities": [
-                            {
-                                "name": "android.server.wm.cts\/android.server.wm.intent.Activities$RegularActivity",
-                                "state": "RESUMED"
-                            },
-                            {
-                                "name": "android.server.wm.cts\/android.server.wm.intent.Activities$RegularActivity",
-                                "state": "STOPPED"
-                            }
-                        ]
+                        "name": "android.server.wm.cts/android.server.wm.intent.Activities$RegularActivity",
+                        "state": "RESUMED"
+                    },
+                    {
+                        "name": "android.server.wm.cts/android.server.wm.intent.Activities$RegularActivity",
+                        "state": "STOPPED"
                     }
-                ],
-                "resumedActivity": "android.server.wm.cts\/android.server.wm.intent.Activities$RegularActivity"
+                ]
             }
-        ]
+        ],
+        "resumedActivity": "android.server.wm.cts/android.server.wm.intent.Activities$RegularActivity"
     },
     "endState": {
-        "stacks": [
+        "tasks": [
             {
-                "tasks": [
+                "activities": [
                     {
-                        "activities": [
-                            {
-                                "name": "android.server.wm.cts\/android.server.wm.intent.Activities$RegularActivity",
-                                "state": "RESUMED"
-                            },
-                            {
-                                "name": "android.server.wm.cts\/android.server.wm.intent.Activities$RegularActivity",
-                                "state": "STOPPED"
-                            }
-                        ]
+                        "name": "android.server.wm.cts/android.server.wm.intent.Activities$RegularActivity",
+                        "state": "RESUMED"
+                    },
+                    {
+                        "name": "android.server.wm.cts/android.server.wm.intent.Activities$RegularActivity",
+                        "state": "STOPPED"
                     }
-                ],
-                "resumedActivity": "android.server.wm.cts\/android.server.wm.intent.Activities$RegularActivity"
+                ]
             }
-        ]
+        ],
+        "resumedActivity": "android.server.wm.cts/android.server.wm.intent.Activities$RegularActivity"
     }
-}
+}
\ No newline at end of file
diff --git a/tests/framework/base/windowmanager/intent_tests/clearCases/test-3.json b/tests/framework/base/windowmanager/intent_tests/clearCases/test-3.json
index 42f1ffa..636eee3 100644
--- a/tests/framework/base/windowmanager/intent_tests/clearCases/test-3.json
+++ b/tests/framework/base/windowmanager/intent_tests/clearCases/test-3.json
@@ -24,45 +24,37 @@
         ]
     },
     "initialState": {
-        "stacks": [
+        "tasks": [
             {
-                "tasks": [
+                "activities": [
                     {
-                        "activities": [
-                            {
-                                "name": "android.server.wm.cts\/android.server.wm.intent.Activities$RegularActivity",
-                                "state": "RESUMED"
-                            },
-                            {
-                                "name": "android.server.wm.cts\/android.server.wm.intent.Activities$RegularActivity",
-                                "state": "STOPPED"
-                            }
-                        ]
+                        "name": "android.server.wm.cts/android.server.wm.intent.Activities$RegularActivity",
+                        "state": "RESUMED"
+                    },
+                    {
+                        "name": "android.server.wm.cts/android.server.wm.intent.Activities$RegularActivity",
+                        "state": "STOPPED"
                     }
-                ],
-                "resumedActivity": "android.server.wm.cts\/android.server.wm.intent.Activities$RegularActivity"
+                ]
             }
-        ]
+        ],
+        "resumedActivity": "android.server.wm.cts/android.server.wm.intent.Activities$RegularActivity"
     },
     "endState": {
-        "stacks": [
+        "tasks": [
             {
-                "tasks": [
+                "activities": [
                     {
-                        "activities": [
-                            {
-                                "name": "android.server.wm.cts\/android.server.wm.intent.Activities$RegularActivity",
-                                "state": "RESUMED"
-                            },
-                            {
-                                "name": "android.server.wm.cts\/android.server.wm.intent.Activities$RegularActivity",
-                                "state": "STOPPED"
-                            }
-                        ]
+                        "name": "android.server.wm.cts/android.server.wm.intent.Activities$RegularActivity",
+                        "state": "RESUMED"
+                    },
+                    {
+                        "name": "android.server.wm.cts/android.server.wm.intent.Activities$RegularActivity",
+                        "state": "STOPPED"
                     }
-                ],
-                "resumedActivity": "android.server.wm.cts\/android.server.wm.intent.Activities$RegularActivity"
+                ]
             }
-        ]
+        ],
+        "resumedActivity": "android.server.wm.cts/android.server.wm.intent.Activities$RegularActivity"
     }
-}
+}
\ No newline at end of file
diff --git a/tests/framework/base/windowmanager/intent_tests/clearCases/test-4.json b/tests/framework/base/windowmanager/intent_tests/clearCases/test-4.json
index 5b52541..ad7184b 100644
--- a/tests/framework/base/windowmanager/intent_tests/clearCases/test-4.json
+++ b/tests/framework/base/windowmanager/intent_tests/clearCases/test-4.json
@@ -24,45 +24,37 @@
         ]
     },
     "initialState": {
-        "stacks": [
+        "tasks": [
             {
-                "tasks": [
+                "activities": [
                     {
-                        "activities": [
-                            {
-                                "name": "android.server.wm.cts\/android.server.wm.intent.Activities$RegularActivity",
-                                "state": "RESUMED"
-                            },
-                            {
-                                "name": "android.server.wm.cts\/android.server.wm.intent.Activities$RegularActivity",
-                                "state": "STOPPED"
-                            }
-                        ]
+                        "name": "android.server.wm.cts/android.server.wm.intent.Activities$RegularActivity",
+                        "state": "RESUMED"
+                    },
+                    {
+                        "name": "android.server.wm.cts/android.server.wm.intent.Activities$RegularActivity",
+                        "state": "STOPPED"
                     }
-                ],
-                "resumedActivity": "android.server.wm.cts\/android.server.wm.intent.Activities$RegularActivity"
+                ]
             }
-        ]
+        ],
+        "resumedActivity": "android.server.wm.cts/android.server.wm.intent.Activities$RegularActivity"
     },
     "endState": {
-        "stacks": [
+        "tasks": [
             {
-                "tasks": [
+                "activities": [
                     {
-                        "activities": [
-                            {
-                                "name": "android.server.wm.cts\/android.server.wm.intent.Activities$RegularActivity",
-                                "state": "RESUMED"
-                            },
-                            {
-                                "name": "android.server.wm.cts\/android.server.wm.intent.Activities$RegularActivity",
-                                "state": "STOPPED"
-                            }
-                        ]
+                        "name": "android.server.wm.cts/android.server.wm.intent.Activities$RegularActivity",
+                        "state": "RESUMED"
+                    },
+                    {
+                        "name": "android.server.wm.cts/android.server.wm.intent.Activities$RegularActivity",
+                        "state": "STOPPED"
                     }
-                ],
-                "resumedActivity": "android.server.wm.cts\/android.server.wm.intent.Activities$RegularActivity"
+                ]
             }
-        ]
+        ],
+        "resumedActivity": "android.server.wm.cts/android.server.wm.intent.Activities$RegularActivity"
     }
-}
+}
\ No newline at end of file
diff --git a/tests/framework/base/windowmanager/intent_tests/clearCases/test-5.json b/tests/framework/base/windowmanager/intent_tests/clearCases/test-5.json
index 2f1def6..1873b76 100644
--- a/tests/framework/base/windowmanager/intent_tests/clearCases/test-5.json
+++ b/tests/framework/base/windowmanager/intent_tests/clearCases/test-5.json
@@ -24,45 +24,37 @@
         ]
     },
     "initialState": {
-        "stacks": [
+        "tasks": [
             {
-                "tasks": [
+                "activities": [
                     {
-                        "activities": [
-                            {
-                                "name": "android.server.wm.cts\/android.server.wm.intent.Activities$RegularActivity",
-                                "state": "RESUMED"
-                            },
-                            {
-                                "name": "android.server.wm.cts\/android.server.wm.intent.Activities$RegularActivity",
-                                "state": "STOPPED"
-                            }
-                        ]
+                        "name": "android.server.wm.cts/android.server.wm.intent.Activities$RegularActivity",
+                        "state": "RESUMED"
+                    },
+                    {
+                        "name": "android.server.wm.cts/android.server.wm.intent.Activities$RegularActivity",
+                        "state": "STOPPED"
                     }
-                ],
-                "resumedActivity": "android.server.wm.cts\/android.server.wm.intent.Activities$RegularActivity"
+                ]
             }
-        ]
+        ],
+        "resumedActivity": "android.server.wm.cts/android.server.wm.intent.Activities$RegularActivity"
     },
     "endState": {
-        "stacks": [
+        "tasks": [
             {
-                "tasks": [
+                "activities": [
                     {
-                        "activities": [
-                            {
-                                "name": "android.server.wm.cts\/android.server.wm.intent.Activities$RegularActivity",
-                                "state": "RESUMED"
-                            },
-                            {
-                                "name": "android.server.wm.cts\/android.server.wm.intent.Activities$RegularActivity",
-                                "state": "STOPPED"
-                            }
-                        ]
+                        "name": "android.server.wm.cts/android.server.wm.intent.Activities$RegularActivity",
+                        "state": "RESUMED"
+                    },
+                    {
+                        "name": "android.server.wm.cts/android.server.wm.intent.Activities$RegularActivity",
+                        "state": "STOPPED"
                     }
-                ],
-                "resumedActivity": "android.server.wm.cts\/android.server.wm.intent.Activities$RegularActivity"
+                ]
             }
-        ]
+        ],
+        "resumedActivity": "android.server.wm.cts/android.server.wm.intent.Activities$RegularActivity"
     }
-}
+}
\ No newline at end of file
diff --git a/tests/framework/base/windowmanager/intent_tests/clearCases/test-6.json b/tests/framework/base/windowmanager/intent_tests/clearCases/test-6.json
index dce5119..a56da5e 100644
--- a/tests/framework/base/windowmanager/intent_tests/clearCases/test-6.json
+++ b/tests/framework/base/windowmanager/intent_tests/clearCases/test-6.json
@@ -30,49 +30,41 @@
         ]
     },
     "initialState": {
-        "stacks": [
+        "tasks": [
             {
-                "tasks": [
+                "activities": [
                     {
-                        "activities": [
-                            {
-                                "name": "android.server.wm.cts\/android.server.wm.intent.Activities$RegularActivity",
-                                "state": "RESUMED"
-                            },
-                            {
-                                "name": "android.server.wm.cts\/android.server.wm.intent.Activities$TaskAffinity1Activity",
-                                "state": "STOPPED"
-                            },
-                            {
-                                "name": "android.server.wm.cts\/android.server.wm.intent.Activities$RegularActivity",
-                                "state": "STOPPED"
-                            }
-                        ]
+                        "name": "android.server.wm.cts/android.server.wm.intent.Activities$RegularActivity",
+                        "state": "RESUMED"
+                    },
+                    {
+                        "name": "android.server.wm.cts/android.server.wm.intent.Activities$TaskAffinity1Activity",
+                        "state": "STOPPED"
+                    },
+                    {
+                        "name": "android.server.wm.cts/android.server.wm.intent.Activities$RegularActivity",
+                        "state": "STOPPED"
                     }
-                ],
-                "resumedActivity": "android.server.wm.cts\/android.server.wm.intent.Activities$RegularActivity"
+                ]
             }
-        ]
+        ],
+        "resumedActivity": "android.server.wm.cts/android.server.wm.intent.Activities$RegularActivity"
     },
     "endState": {
-        "stacks": [
+        "tasks": [
             {
-                "tasks": [
+                "activities": [
                     {
-                        "activities": [
-                            {
-                                "name": "android.server.wm.cts\/android.server.wm.intent.Activities$TaskAffinity1Activity",
-                                "state": "RESUMED"
-                            },
-                            {
-                                "name": "android.server.wm.cts\/android.server.wm.intent.Activities$RegularActivity",
-                                "state": "STOPPED"
-                            }
-                        ]
+                        "name": "android.server.wm.cts/android.server.wm.intent.Activities$TaskAffinity1Activity",
+                        "state": "RESUMED"
+                    },
+                    {
+                        "name": "android.server.wm.cts/android.server.wm.intent.Activities$RegularActivity",
+                        "state": "STOPPED"
                     }
-                ],
-                "resumedActivity": "android.server.wm.cts\/android.server.wm.intent.Activities$TaskAffinity1Activity"
+                ]
             }
-        ]
+        ],
+        "resumedActivity": "android.server.wm.cts/android.server.wm.intent.Activities$TaskAffinity1Activity"
     }
-}
+}
\ No newline at end of file
diff --git a/tests/framework/base/windowmanager/intent_tests/forResult/test-1.json b/tests/framework/base/windowmanager/intent_tests/forResult/test-1.json
index f901ad1..578a4b4 100644
--- a/tests/framework/base/windowmanager/intent_tests/forResult/test-1.json
+++ b/tests/framework/base/windowmanager/intent_tests/forResult/test-1.json
@@ -18,37 +18,29 @@
         ]
     },
     "initialState": {
-        "stacks": [
+        "tasks": [
             {
-                "tasks": [
+                "activities": [
                     {
-                        "activities": [
-                            {
-                                "name": "android.server.wm.cts\/android.server.wm.intent.Activities$RegularActivity",
-                                "state": "RESUMED"
-                            }
-                        ]
+                        "name": "android.server.wm.cts/android.server.wm.intent.Activities$RegularActivity",
+                        "state": "RESUMED"
                     }
-                ],
-                "resumedActivity": "android.server.wm.cts\/android.server.wm.intent.Activities$RegularActivity"
+                ]
             }
-        ]
+        ],
+        "resumedActivity": "android.server.wm.cts/android.server.wm.intent.Activities$RegularActivity"
     },
     "endState": {
-        "stacks": [
+        "tasks": [
             {
-                "tasks": [
+                "activities": [
                     {
-                        "activities": [
-                            {
-                                "name": "android.server.wm.cts\/android.server.wm.intent.Activities$RegularActivity",
-                                "state": "RESUMED"
-                            }
-                        ]
+                        "name": "android.server.wm.cts/android.server.wm.intent.Activities$RegularActivity",
+                        "state": "RESUMED"
                     }
-                ],
-                "resumedActivity": "android.server.wm.cts\/android.server.wm.intent.Activities$RegularActivity"
+                ]
             }
-        ]
+        ],
+        "resumedActivity": "android.server.wm.cts/android.server.wm.intent.Activities$RegularActivity"
     }
-}
+}
\ No newline at end of file
diff --git a/tests/framework/base/windowmanager/intent_tests/forResult/test-2.json b/tests/framework/base/windowmanager/intent_tests/forResult/test-2.json
index 6e97377..2e283da 100644
--- a/tests/framework/base/windowmanager/intent_tests/forResult/test-2.json
+++ b/tests/framework/base/windowmanager/intent_tests/forResult/test-2.json
@@ -18,41 +18,33 @@
         ]
     },
     "initialState": {
-        "stacks": [
+        "tasks": [
             {
-                "tasks": [
+                "activities": [
                     {
-                        "activities": [
-                            {
-                                "name": "android.server.wm.cts\/android.server.wm.intent.Activities$RegularActivity",
-                                "state": "RESUMED"
-                            }
-                        ]
+                        "name": "android.server.wm.cts/android.server.wm.intent.Activities$RegularActivity",
+                        "state": "RESUMED"
                     }
-                ],
-                "resumedActivity": "android.server.wm.cts\/android.server.wm.intent.Activities$RegularActivity"
+                ]
             }
-        ]
+        ],
+        "resumedActivity": "android.server.wm.cts/android.server.wm.intent.Activities$RegularActivity"
     },
     "endState": {
-        "stacks": [
+        "tasks": [
             {
-                "tasks": [
+                "activities": [
                     {
-                        "activities": [
-                            {
-                                "name": "android.server.wm.cts\/android.server.wm.intent.Activities$RegularActivity",
-                                "state": "RESUMED"
-                            },
-                            {
-                                "name": "android.server.wm.cts\/android.server.wm.intent.Activities$RegularActivity",
-                                "state": "STOPPED"
-                            }
-                        ]
+                        "name": "android.server.wm.cts/android.server.wm.intent.Activities$RegularActivity",
+                        "state": "RESUMED"
+                    },
+                    {
+                        "name": "android.server.wm.cts/android.server.wm.intent.Activities$RegularActivity",
+                        "state": "STOPPED"
                     }
-                ],
-                "resumedActivity": "android.server.wm.cts\/android.server.wm.intent.Activities$RegularActivity"
+                ]
             }
-        ]
+        ],
+        "resumedActivity": "android.server.wm.cts/android.server.wm.intent.Activities$RegularActivity"
     }
-}
+}
\ No newline at end of file
diff --git a/tests/framework/base/windowmanager/intent_tests/forResult/test-3.json b/tests/framework/base/windowmanager/intent_tests/forResult/test-3.json
index da3478d..53f40de 100644
--- a/tests/framework/base/windowmanager/intent_tests/forResult/test-3.json
+++ b/tests/framework/base/windowmanager/intent_tests/forResult/test-3.json
@@ -18,37 +18,29 @@
         ]
     },
     "initialState": {
-        "stacks": [
+        "tasks": [
             {
-                "tasks": [
+                "activities": [
                     {
-                        "activities": [
-                            {
-                                "name": "android.server.wm.cts\/android.server.wm.intent.Activities$SingleTopActivity",
-                                "state": "RESUMED"
-                            }
-                        ]
+                        "name": "android.server.wm.cts/android.server.wm.intent.Activities$SingleTopActivity",
+                        "state": "RESUMED"
                     }
-                ],
-                "resumedActivity": "android.server.wm.cts\/android.server.wm.intent.Activities$SingleTopActivity"
+                ]
             }
-        ]
+        ],
+        "resumedActivity": "android.server.wm.cts/android.server.wm.intent.Activities$SingleTopActivity"
     },
     "endState": {
-        "stacks": [
+        "tasks": [
             {
-                "tasks": [
+                "activities": [
                     {
-                        "activities": [
-                            {
-                                "name": "android.server.wm.cts\/android.server.wm.intent.Activities$SingleTopActivity",
-                                "state": "RESUMED"
-                            }
-                        ]
+                        "name": "android.server.wm.cts/android.server.wm.intent.Activities$SingleTopActivity",
+                        "state": "RESUMED"
                     }
-                ],
-                "resumedActivity": "android.server.wm.cts\/android.server.wm.intent.Activities$SingleTopActivity"
+                ]
             }
-        ]
+        ],
+        "resumedActivity": "android.server.wm.cts/android.server.wm.intent.Activities$SingleTopActivity"
     }
-}
+}
\ No newline at end of file
diff --git a/tests/framework/base/windowmanager/intent_tests/forResult/test-4.json b/tests/framework/base/windowmanager/intent_tests/forResult/test-4.json
index 2ed6023..7a75e94 100644
--- a/tests/framework/base/windowmanager/intent_tests/forResult/test-4.json
+++ b/tests/framework/base/windowmanager/intent_tests/forResult/test-4.json
@@ -18,41 +18,33 @@
         ]
     },
     "initialState": {
-        "stacks": [
+        "tasks": [
             {
-                "tasks": [
+                "activities": [
                     {
-                        "activities": [
-                            {
-                                "name": "android.server.wm.cts\/android.server.wm.intent.Activities$SingleTopActivity",
-                                "state": "RESUMED"
-                            }
-                        ]
+                        "name": "android.server.wm.cts/android.server.wm.intent.Activities$SingleTopActivity",
+                        "state": "RESUMED"
                     }
-                ],
-                "resumedActivity": "android.server.wm.cts\/android.server.wm.intent.Activities$SingleTopActivity"
+                ]
             }
-        ]
+        ],
+        "resumedActivity": "android.server.wm.cts/android.server.wm.intent.Activities$SingleTopActivity"
     },
     "endState": {
-        "stacks": [
+        "tasks": [
             {
-                "tasks": [
+                "activities": [
                     {
-                        "activities": [
-                            {
-                                "name": "android.server.wm.cts\/android.server.wm.intent.Activities$SingleTopActivity",
-                                "state": "RESUMED"
-                            },
-                            {
-                                "name": "android.server.wm.cts\/android.server.wm.intent.Activities$SingleTopActivity",
-                                "state": "STOPPED"
-                            }
-                        ]
+                        "name": "android.server.wm.cts/android.server.wm.intent.Activities$SingleTopActivity",
+                        "state": "RESUMED"
+                    },
+                    {
+                        "name": "android.server.wm.cts/android.server.wm.intent.Activities$SingleTopActivity",
+                        "state": "STOPPED"
                     }
-                ],
-                "resumedActivity": "android.server.wm.cts\/android.server.wm.intent.Activities$SingleTopActivity"
+                ]
             }
-        ]
+        ],
+        "resumedActivity": "android.server.wm.cts/android.server.wm.intent.Activities$SingleTopActivity"
     }
-}
+}
\ No newline at end of file
diff --git a/tests/framework/base/windowmanager/intent_tests/forResult/test-5.json b/tests/framework/base/windowmanager/intent_tests/forResult/test-5.json
index 0ee6cc8..10d9a4a 100644
--- a/tests/framework/base/windowmanager/intent_tests/forResult/test-5.json
+++ b/tests/framework/base/windowmanager/intent_tests/forResult/test-5.json
@@ -18,37 +18,29 @@
         ]
     },
     "initialState": {
-        "stacks": [
+        "tasks": [
             {
-                "tasks": [
+                "activities": [
                     {
-                        "activities": [
-                            {
-                                "name": "android.server.wm.cts\/android.server.wm.intent.Activities$RegularActivity",
-                                "state": "RESUMED"
-                            }
-                        ]
+                        "name": "android.server.wm.cts/android.server.wm.intent.Activities$RegularActivity",
+                        "state": "RESUMED"
                     }
-                ],
-                "resumedActivity": "android.server.wm.cts\/android.server.wm.intent.Activities$RegularActivity"
+                ]
             }
-        ]
+        ],
+        "resumedActivity": "android.server.wm.cts/android.server.wm.intent.Activities$RegularActivity"
     },
     "endState": {
-        "stacks": [
+        "tasks": [
             {
-                "tasks": [
+                "activities": [
                     {
-                        "activities": [
-                            {
-                                "name": "android.server.wm.cts\/android.server.wm.intent.Activities$RegularActivity",
-                                "state": "RESUMED"
-                            }
-                        ]
+                        "name": "android.server.wm.cts/android.server.wm.intent.Activities$RegularActivity",
+                        "state": "RESUMED"
                     }
-                ],
-                "resumedActivity": "android.server.wm.cts\/android.server.wm.intent.Activities$RegularActivity"
+                ]
             }
-        ]
+        ],
+        "resumedActivity": "android.server.wm.cts/android.server.wm.intent.Activities$RegularActivity"
     }
-}
+}
\ No newline at end of file
diff --git a/tests/framework/base/windowmanager/intent_tests/forResult/test-6.json b/tests/framework/base/windowmanager/intent_tests/forResult/test-6.json
index dca9dd2..2179acd 100644
--- a/tests/framework/base/windowmanager/intent_tests/forResult/test-6.json
+++ b/tests/framework/base/windowmanager/intent_tests/forResult/test-6.json
@@ -18,37 +18,29 @@
         ]
     },
     "initialState": {
-        "stacks": [
+        "tasks": [
             {
-                "tasks": [
+                "activities": [
                     {
-                        "activities": [
-                            {
-                                "name": "android.server.wm.cts\/android.server.wm.intent.Activities$RegularActivity",
-                                "state": "RESUMED"
-                            }
-                        ]
+                        "name": "android.server.wm.cts/android.server.wm.intent.Activities$RegularActivity",
+                        "state": "RESUMED"
                     }
-                ],
-                "resumedActivity": "android.server.wm.cts\/android.server.wm.intent.Activities$RegularActivity"
+                ]
             }
-        ]
+        ],
+        "resumedActivity": "android.server.wm.cts/android.server.wm.intent.Activities$RegularActivity"
     },
     "endState": {
-        "stacks": [
+        "tasks": [
             {
-                "tasks": [
+                "activities": [
                     {
-                        "activities": [
-                            {
-                                "name": "android.server.wm.cts\/android.server.wm.intent.Activities$RegularActivity",
-                                "state": "RESUMED"
-                            }
-                        ]
+                        "name": "android.server.wm.cts/android.server.wm.intent.Activities$RegularActivity",
+                        "state": "RESUMED"
                     }
-                ],
-                "resumedActivity": "android.server.wm.cts\/android.server.wm.intent.Activities$RegularActivity"
+                ]
             }
-        ]
+        ],
+        "resumedActivity": "android.server.wm.cts/android.server.wm.intent.Activities$RegularActivity"
     }
-}
+}
\ No newline at end of file
diff --git a/tests/framework/base/windowmanager/intent_tests/forResult/test-7.json b/tests/framework/base/windowmanager/intent_tests/forResult/test-7.json
index 4599e0f..6c4adea 100644
--- a/tests/framework/base/windowmanager/intent_tests/forResult/test-7.json
+++ b/tests/framework/base/windowmanager/intent_tests/forResult/test-7.json
@@ -18,49 +18,37 @@
         ]
     },
     "initialState": {
-        "stacks": [
+        "tasks": [
             {
-                "tasks": [
+                "activities": [
                     {
-                        "activities": [
-                            {
-                                "name": "android.server.wm.cts\/android.server.wm.intent.Activities$RegularActivity",
-                                "state": "RESUMED"
-                            }
-                        ]
-                    }
-                ],
-                "resumedActivity": "android.server.wm.cts\/android.server.wm.intent.Activities$RegularActivity"
-            }
-        ]
-    },
-    "endState": {
-        "stacks": [
-            {
-                "tasks": [
-                    {
-                        "activities": [
-                            {
-                                "name": "android.server.wm.cts\/android.server.wm.intent.Activities$RegularActivity",
-                                "state": "RESUMED"
-                            }
-                        ]
-                    }
-                ],
-                "resumedActivity": "android.server.wm.cts\/android.server.wm.intent.Activities$RegularActivity"
-            },
-            {
-                "tasks": [
-                    {
-                        "activities": [
-                            {
-                                "name": "android.server.wm.cts\/android.server.wm.intent.Activities$RegularActivity",
-                                "state": "STOPPED"
-                            }
-                        ]
+                        "name": "android.server.wm.cts/android.server.wm.intent.Activities$RegularActivity",
+                        "state": "RESUMED"
                     }
                 ]
             }
-        ]
+        ],
+        "resumedActivity": "android.server.wm.cts/android.server.wm.intent.Activities$RegularActivity"
+    },
+    "endState": {
+        "tasks": [
+            {
+                "activities": [
+                    {
+                        "name": "android.server.wm.cts/android.server.wm.intent.Activities$RegularActivity",
+                        "state": "RESUMED"
+                    }
+                ]
+            },
+            {
+                "activities": [
+                    {
+                        "name": "android.server.wm.cts/android.server.wm.intent.Activities$RegularActivity",
+                        "state": "STOPPED"
+                    }
+                ]
+            }
+        ],
+        "resumedActivity": "android.server.wm.cts/android.server.wm.intent.Activities$RegularActivity"
     }
-}
+}
\ No newline at end of file
diff --git a/tests/framework/base/windowmanager/intent_tests/forResult/test-8.json b/tests/framework/base/windowmanager/intent_tests/forResult/test-8.json
index 22608c7..dba3df2 100644
--- a/tests/framework/base/windowmanager/intent_tests/forResult/test-8.json
+++ b/tests/framework/base/windowmanager/intent_tests/forResult/test-8.json
@@ -24,45 +24,37 @@
         ]
     },
     "initialState": {
-        "stacks": [
+        "tasks": [
             {
-                "tasks": [
+                "activities": [
                     {
-                        "activities": [
-                            {
-                                "name": "android.server.wm.cts\/android.server.wm.intent.Activities$TaskAffinity1Activity",
-                                "state": "RESUMED"
-                            },
-                            {
-                                "name": "android.server.wm.cts\/android.server.wm.intent.Activities$RegularActivity",
-                                "state": "STOPPED"
-                            }
-                        ]
+                        "name": "android.server.wm.cts/android.server.wm.intent.Activities$TaskAffinity1Activity",
+                        "state": "RESUMED"
+                    },
+                    {
+                        "name": "android.server.wm.cts/android.server.wm.intent.Activities$RegularActivity",
+                        "state": "STOPPED"
                     }
-                ],
-                "resumedActivity": "android.server.wm.cts\/android.server.wm.intent.Activities$TaskAffinity1Activity"
+                ]
             }
-        ]
+        ],
+        "resumedActivity": "android.server.wm.cts/android.server.wm.intent.Activities$TaskAffinity1Activity"
     },
     "endState": {
-        "stacks": [
+        "tasks": [
             {
-                "tasks": [
+                "activities": [
                     {
-                        "activities": [
-                            {
-                                "name": "android.server.wm.cts\/android.server.wm.intent.Activities$RegularActivity",
-                                "state": "RESUMED"
-                            },
-                            {
-                                "name": "android.server.wm.cts\/android.server.wm.intent.Activities$TaskAffinity1Activity",
-                                "state": "STOPPED"
-                            }
-                        ]
+                        "name": "android.server.wm.cts/android.server.wm.intent.Activities$RegularActivity",
+                        "state": "RESUMED"
+                    },
+                    {
+                        "name": "android.server.wm.cts/android.server.wm.intent.Activities$TaskAffinity1Activity",
+                        "state": "STOPPED"
                     }
-                ],
-                "resumedActivity": "android.server.wm.cts\/android.server.wm.intent.Activities$RegularActivity"
+                ]
             }
-        ]
+        ],
+        "resumedActivity": "android.server.wm.cts/android.server.wm.intent.Activities$RegularActivity"
     }
-}
+}
\ No newline at end of file
diff --git a/tests/framework/base/windowmanager/intent_tests/forResult/test-9.json b/tests/framework/base/windowmanager/intent_tests/forResult/test-9.json
index 3f2a71a..5d2173e 100644
--- a/tests/framework/base/windowmanager/intent_tests/forResult/test-9.json
+++ b/tests/framework/base/windowmanager/intent_tests/forResult/test-9.json
@@ -24,45 +24,37 @@
         ]
     },
     "initialState": {
-        "stacks": [
+        "tasks": [
             {
-                "tasks": [
+                "activities": [
                     {
-                        "activities": [
-                            {
-                                "name": "android.server.wm.cts\/android.server.wm.intent.Activities$TaskAffinity1Activity",
-                                "state": "RESUMED"
-                            },
-                            {
-                                "name": "android.server.wm.cts\/android.server.wm.intent.Activities$RegularActivity",
-                                "state": "STOPPED"
-                            }
-                        ]
+                        "name": "android.server.wm.cts/android.server.wm.intent.Activities$TaskAffinity1Activity",
+                        "state": "RESUMED"
+                    },
+                    {
+                        "name": "android.server.wm.cts/android.server.wm.intent.Activities$RegularActivity",
+                        "state": "STOPPED"
                     }
-                ],
-                "resumedActivity": "android.server.wm.cts\/android.server.wm.intent.Activities$TaskAffinity1Activity"
+                ]
             }
-        ]
+        ],
+        "resumedActivity": "android.server.wm.cts/android.server.wm.intent.Activities$TaskAffinity1Activity"
     },
     "endState": {
-        "stacks": [
+        "tasks": [
             {
-                "tasks": [
+                "activities": [
                     {
-                        "activities": [
-                            {
-                                "name": "android.server.wm.cts\/android.server.wm.intent.Activities$RegularActivity",
-                                "state": "RESUMED"
-                            },
-                            {
-                                "name": "android.server.wm.cts\/android.server.wm.intent.Activities$TaskAffinity1Activity",
-                                "state": "STOPPED"
-                            }
-                        ]
+                        "name": "android.server.wm.cts/android.server.wm.intent.Activities$RegularActivity",
+                        "state": "RESUMED"
+                    },
+                    {
+                        "name": "android.server.wm.cts/android.server.wm.intent.Activities$TaskAffinity1Activity",
+                        "state": "STOPPED"
                     }
-                ],
-                "resumedActivity": "android.server.wm.cts\/android.server.wm.intent.Activities$RegularActivity"
+                ]
             }
-        ]
+        ],
+        "resumedActivity": "android.server.wm.cts/android.server.wm.intent.Activities$RegularActivity"
     }
-}
+}
\ No newline at end of file
diff --git a/tests/framework/base/windowmanager/intent_tests/newDocumentCases/test-1.json b/tests/framework/base/windowmanager/intent_tests/newDocumentCases/test-1.json
index e4accd3..e50cd7e 100644
--- a/tests/framework/base/windowmanager/intent_tests/newDocumentCases/test-1.json
+++ b/tests/framework/base/windowmanager/intent_tests/newDocumentCases/test-1.json
@@ -18,49 +18,37 @@
         ]
     },
     "initialState": {
-        "stacks": [
+        "tasks": [
             {
-                "tasks": [
+                "activities": [
                     {
-                        "activities": [
-                            {
-                                "name": "android.server.wm.cts\/android.server.wm.intent.Activities$RegularActivity",
-                                "state": "RESUMED"
-                            }
-                        ]
-                    }
-                ],
-                "resumedActivity": "android.server.wm.cts\/android.server.wm.intent.Activities$RegularActivity"
-            }
-        ]
-    },
-    "endState": {
-        "stacks": [
-            {
-                "tasks": [
-                    {
-                        "activities": [
-                            {
-                                "name": "android.server.wm.cts\/android.server.wm.intent.Activities$SingleInstanceActivity",
-                                "state": "RESUMED"
-                            }
-                        ]
-                    }
-                ],
-                "resumedActivity": "android.server.wm.cts\/android.server.wm.intent.Activities$SingleInstanceActivity"
-            },
-            {
-                "tasks": [
-                    {
-                        "activities": [
-                            {
-                                "name": "android.server.wm.cts\/android.server.wm.intent.Activities$RegularActivity",
-                                "state": "STOPPED"
-                            }
-                        ]
+                        "name": "android.server.wm.cts/android.server.wm.intent.Activities$RegularActivity",
+                        "state": "RESUMED"
                     }
                 ]
             }
-        ]
+        ],
+        "resumedActivity": "android.server.wm.cts/android.server.wm.intent.Activities$RegularActivity"
+    },
+    "endState": {
+        "tasks": [
+            {
+                "activities": [
+                    {
+                        "name": "android.server.wm.cts/android.server.wm.intent.Activities$SingleInstanceActivity",
+                        "state": "RESUMED"
+                    }
+                ]
+            },
+            {
+                "activities": [
+                    {
+                        "name": "android.server.wm.cts/android.server.wm.intent.Activities$RegularActivity",
+                        "state": "STOPPED"
+                    }
+                ]
+            }
+        ],
+        "resumedActivity": "android.server.wm.cts/android.server.wm.intent.Activities$SingleInstanceActivity"
     }
-}
+}
\ No newline at end of file
diff --git a/tests/framework/base/windowmanager/intent_tests/newDocumentCases/test-10.json b/tests/framework/base/windowmanager/intent_tests/newDocumentCases/test-10.json
index 0b5a0f5..60d541b 100644
--- a/tests/framework/base/windowmanager/intent_tests/newDocumentCases/test-10.json
+++ b/tests/framework/base/windowmanager/intent_tests/newDocumentCases/test-10.json
@@ -18,49 +18,37 @@
         ]
     },
     "initialState": {
-        "stacks": [
+        "tasks": [
             {
-                "tasks": [
+                "activities": [
                     {
-                        "activities": [
-                            {
-                                "name": "android.server.wm.cts\/android.server.wm.intent.Activities$RegularActivity",
-                                "state": "RESUMED"
-                            }
-                        ]
-                    }
-                ],
-                "resumedActivity": "android.server.wm.cts\/android.server.wm.intent.Activities$RegularActivity"
-            }
-        ]
-    },
-    "endState": {
-        "stacks": [
-            {
-                "tasks": [
-                    {
-                        "activities": [
-                            {
-                                "name": "android.server.wm.cts\/android.server.wm.intent.Activities$RegularActivity",
-                                "state": "RESUMED"
-                            }
-                        ]
-                    }
-                ],
-                "resumedActivity": "android.server.wm.cts\/android.server.wm.intent.Activities$RegularActivity"
-            },
-            {
-                "tasks": [
-                    {
-                        "activities": [
-                            {
-                                "name": "android.server.wm.cts\/android.server.wm.intent.Activities$RegularActivity",
-                                "state": "STOPPED"
-                            }
-                        ]
+                        "name": "android.server.wm.cts/android.server.wm.intent.Activities$RegularActivity",
+                        "state": "RESUMED"
                     }
                 ]
             }
-        ]
+        ],
+        "resumedActivity": "android.server.wm.cts/android.server.wm.intent.Activities$RegularActivity"
+    },
+    "endState": {
+        "tasks": [
+            {
+                "activities": [
+                    {
+                        "name": "android.server.wm.cts/android.server.wm.intent.Activities$RegularActivity",
+                        "state": "RESUMED"
+                    }
+                ]
+            },
+            {
+                "activities": [
+                    {
+                        "name": "android.server.wm.cts/android.server.wm.intent.Activities$RegularActivity",
+                        "state": "STOPPED"
+                    }
+                ]
+            }
+        ],
+        "resumedActivity": "android.server.wm.cts/android.server.wm.intent.Activities$RegularActivity"
     }
-}
+}
\ No newline at end of file
diff --git a/tests/framework/base/windowmanager/intent_tests/newDocumentCases/test-11.json b/tests/framework/base/windowmanager/intent_tests/newDocumentCases/test-11.json
index 3b782b0..c457193 100644
--- a/tests/framework/base/windowmanager/intent_tests/newDocumentCases/test-11.json
+++ b/tests/framework/base/windowmanager/intent_tests/newDocumentCases/test-11.json
@@ -18,37 +18,29 @@
         ]
     },
     "initialState": {
-        "stacks": [
+        "tasks": [
             {
-                "tasks": [
+                "activities": [
                     {
-                        "activities": [
-                            {
-                                "name": "android.server.wm.cts\/android.server.wm.intent.Activities$SingleInstanceActivity",
-                                "state": "RESUMED"
-                            }
-                        ]
+                        "name": "android.server.wm.cts/android.server.wm.intent.Activities$SingleInstanceActivity",
+                        "state": "RESUMED"
                     }
-                ],
-                "resumedActivity": "android.server.wm.cts\/android.server.wm.intent.Activities$SingleInstanceActivity"
+                ]
             }
-        ]
+        ],
+        "resumedActivity": "android.server.wm.cts/android.server.wm.intent.Activities$SingleInstanceActivity"
     },
     "endState": {
-        "stacks": [
+        "tasks": [
             {
-                "tasks": [
+                "activities": [
                     {
-                        "activities": [
-                            {
-                                "name": "android.server.wm.cts\/android.server.wm.intent.Activities$SingleInstanceActivity",
-                                "state": "RESUMED"
-                            }
-                        ]
+                        "name": "android.server.wm.cts/android.server.wm.intent.Activities$SingleInstanceActivity",
+                        "state": "RESUMED"
                     }
-                ],
-                "resumedActivity": "android.server.wm.cts\/android.server.wm.intent.Activities$SingleInstanceActivity"
+                ]
             }
-        ]
+        ],
+        "resumedActivity": "android.server.wm.cts/android.server.wm.intent.Activities$SingleInstanceActivity"
     }
-}
+}
\ No newline at end of file
diff --git a/tests/framework/base/windowmanager/intent_tests/newDocumentCases/test-12.json b/tests/framework/base/windowmanager/intent_tests/newDocumentCases/test-12.json
index 63f9948..35a63cb 100644
--- a/tests/framework/base/windowmanager/intent_tests/newDocumentCases/test-12.json
+++ b/tests/framework/base/windowmanager/intent_tests/newDocumentCases/test-12.json
@@ -18,37 +18,29 @@
         ]
     },
     "initialState": {
-        "stacks": [
+        "tasks": [
             {
-                "tasks": [
+                "activities": [
                     {
-                        "activities": [
-                            {
-                                "name": "android.server.wm.cts\/android.server.wm.intent.Activities$SingleTaskActivity",
-                                "state": "RESUMED"
-                            }
-                        ]
+                        "name": "android.server.wm.cts/android.server.wm.intent.Activities$SingleTaskActivity",
+                        "state": "RESUMED"
                     }
-                ],
-                "resumedActivity": "android.server.wm.cts\/android.server.wm.intent.Activities$SingleTaskActivity"
+                ]
             }
-        ]
+        ],
+        "resumedActivity": "android.server.wm.cts/android.server.wm.intent.Activities$SingleTaskActivity"
     },
     "endState": {
-        "stacks": [
+        "tasks": [
             {
-                "tasks": [
+                "activities": [
                     {
-                        "activities": [
-                            {
-                                "name": "android.server.wm.cts\/android.server.wm.intent.Activities$SingleTaskActivity",
-                                "state": "RESUMED"
-                            }
-                        ]
+                        "name": "android.server.wm.cts/android.server.wm.intent.Activities$SingleTaskActivity",
+                        "state": "RESUMED"
                     }
-                ],
-                "resumedActivity": "android.server.wm.cts\/android.server.wm.intent.Activities$SingleTaskActivity"
+                ]
             }
-        ]
+        ],
+        "resumedActivity": "android.server.wm.cts/android.server.wm.intent.Activities$SingleTaskActivity"
     }
-}
+}
\ No newline at end of file
diff --git a/tests/framework/base/windowmanager/intent_tests/newDocumentCases/test-2.json b/tests/framework/base/windowmanager/intent_tests/newDocumentCases/test-2.json
index baa3996d..a53f7b8 100644
--- a/tests/framework/base/windowmanager/intent_tests/newDocumentCases/test-2.json
+++ b/tests/framework/base/windowmanager/intent_tests/newDocumentCases/test-2.json
@@ -18,49 +18,37 @@
         ]
     },
     "initialState": {
-        "stacks": [
+        "tasks": [
             {
-                "tasks": [
+                "activities": [
                     {
-                        "activities": [
-                            {
-                                "name": "android.server.wm.cts\/android.server.wm.intent.Activities$RegularActivity",
-                                "state": "RESUMED"
-                            }
-                        ]
-                    }
-                ],
-                "resumedActivity": "android.server.wm.cts\/android.server.wm.intent.Activities$RegularActivity"
-            }
-        ]
-    },
-    "endState": {
-        "stacks": [
-            {
-                "tasks": [
-                    {
-                        "activities": [
-                            {
-                                "name": "android.server.wm.cts\/android.server.wm.intent.Activities$SingleInstanceActivity",
-                                "state": "RESUMED"
-                            }
-                        ]
-                    }
-                ],
-                "resumedActivity": "android.server.wm.cts\/android.server.wm.intent.Activities$SingleInstanceActivity"
-            },
-            {
-                "tasks": [
-                    {
-                        "activities": [
-                            {
-                                "name": "android.server.wm.cts\/android.server.wm.intent.Activities$RegularActivity",
-                                "state": "STOPPED"
-                            }
-                        ]
+                        "name": "android.server.wm.cts/android.server.wm.intent.Activities$RegularActivity",
+                        "state": "RESUMED"
                     }
                 ]
             }
-        ]
+        ],
+        "resumedActivity": "android.server.wm.cts/android.server.wm.intent.Activities$RegularActivity"
+    },
+    "endState": {
+        "tasks": [
+            {
+                "activities": [
+                    {
+                        "name": "android.server.wm.cts/android.server.wm.intent.Activities$SingleInstanceActivity",
+                        "state": "RESUMED"
+                    }
+                ]
+            },
+            {
+                "activities": [
+                    {
+                        "name": "android.server.wm.cts/android.server.wm.intent.Activities$RegularActivity",
+                        "state": "STOPPED"
+                    }
+                ]
+            }
+        ],
+        "resumedActivity": "android.server.wm.cts/android.server.wm.intent.Activities$SingleInstanceActivity"
     }
-}
+}
\ No newline at end of file
diff --git a/tests/framework/base/windowmanager/intent_tests/newDocumentCases/test-3.json b/tests/framework/base/windowmanager/intent_tests/newDocumentCases/test-3.json
index 53d01b1..c31e9a7 100644
--- a/tests/framework/base/windowmanager/intent_tests/newDocumentCases/test-3.json
+++ b/tests/framework/base/windowmanager/intent_tests/newDocumentCases/test-3.json
@@ -18,41 +18,33 @@
         ]
     },
     "initialState": {
-        "stacks": [
+        "tasks": [
             {
-                "tasks": [
+                "activities": [
                     {
-                        "activities": [
-                            {
-                                "name": "android.server.wm.cts\/android.server.wm.intent.Activities$RegularActivity",
-                                "state": "RESUMED"
-                            }
-                        ]
+                        "name": "android.server.wm.cts/android.server.wm.intent.Activities$RegularActivity",
+                        "state": "RESUMED"
                     }
-                ],
-                "resumedActivity": "android.server.wm.cts\/android.server.wm.intent.Activities$RegularActivity"
+                ]
             }
-        ]
+        ],
+        "resumedActivity": "android.server.wm.cts/android.server.wm.intent.Activities$RegularActivity"
     },
     "endState": {
-        "stacks": [
+        "tasks": [
             {
-                "tasks": [
+                "activities": [
                     {
-                        "activities": [
-                            {
-                                "name": "android.server.wm.cts\/android.server.wm.intent.Activities$TaskAffinity1Activity",
-                                "state": "RESUMED"
-                            },
-                            {
-                                "name": "android.server.wm.cts\/android.server.wm.intent.Activities$RegularActivity",
-                                "state": "STOPPED"
-                            }
-                        ]
+                        "name": "android.server.wm.cts/android.server.wm.intent.Activities$TaskAffinity1Activity",
+                        "state": "RESUMED"
+                    },
+                    {
+                        "name": "android.server.wm.cts/android.server.wm.intent.Activities$RegularActivity",
+                        "state": "STOPPED"
                     }
-                ],
-                "resumedActivity": "android.server.wm.cts\/android.server.wm.intent.Activities$TaskAffinity1Activity"
+                ]
             }
-        ]
+        ],
+        "resumedActivity": "android.server.wm.cts/android.server.wm.intent.Activities$TaskAffinity1Activity"
     }
-}
+}
\ No newline at end of file
diff --git a/tests/framework/base/windowmanager/intent_tests/newDocumentCases/test-4.json b/tests/framework/base/windowmanager/intent_tests/newDocumentCases/test-4.json
index 697703b..b285901 100644
--- a/tests/framework/base/windowmanager/intent_tests/newDocumentCases/test-4.json
+++ b/tests/framework/base/windowmanager/intent_tests/newDocumentCases/test-4.json
@@ -18,49 +18,37 @@
         ]
     },
     "initialState": {
-        "stacks": [
+        "tasks": [
             {
-                "tasks": [
+                "activities": [
                     {
-                        "activities": [
-                            {
-                                "name": "android.server.wm.cts\/android.server.wm.intent.Activities$RegularActivity",
-                                "state": "RESUMED"
-                            }
-                        ]
-                    }
-                ],
-                "resumedActivity": "android.server.wm.cts\/android.server.wm.intent.Activities$RegularActivity"
-            }
-        ]
-    },
-    "endState": {
-        "stacks": [
-            {
-                "tasks": [
-                    {
-                        "activities": [
-                            {
-                                "name": "android.server.wm.cts\/android.server.wm.intent.Activities$TaskAffinity1Activity",
-                                "state": "RESUMED"
-                            }
-                        ]
-                    }
-                ],
-                "resumedActivity": "android.server.wm.cts\/android.server.wm.intent.Activities$TaskAffinity1Activity"
-            },
-            {
-                "tasks": [
-                    {
-                        "activities": [
-                            {
-                                "name": "android.server.wm.cts\/android.server.wm.intent.Activities$RegularActivity",
-                                "state": "STOPPED"
-                            }
-                        ]
+                        "name": "android.server.wm.cts/android.server.wm.intent.Activities$RegularActivity",
+                        "state": "RESUMED"
                     }
                 ]
             }
-        ]
+        ],
+        "resumedActivity": "android.server.wm.cts/android.server.wm.intent.Activities$RegularActivity"
+    },
+    "endState": {
+        "tasks": [
+            {
+                "activities": [
+                    {
+                        "name": "android.server.wm.cts/android.server.wm.intent.Activities$TaskAffinity1Activity",
+                        "state": "RESUMED"
+                    }
+                ]
+            },
+            {
+                "activities": [
+                    {
+                        "name": "android.server.wm.cts/android.server.wm.intent.Activities$RegularActivity",
+                        "state": "STOPPED"
+                    }
+                ]
+            }
+        ],
+        "resumedActivity": "android.server.wm.cts/android.server.wm.intent.Activities$TaskAffinity1Activity"
     }
-}
+}
\ No newline at end of file
diff --git a/tests/framework/base/windowmanager/intent_tests/newDocumentCases/test-5.json b/tests/framework/base/windowmanager/intent_tests/newDocumentCases/test-5.json
index 2050021..f6158b1 100644
--- a/tests/framework/base/windowmanager/intent_tests/newDocumentCases/test-5.json
+++ b/tests/framework/base/windowmanager/intent_tests/newDocumentCases/test-5.json
@@ -18,37 +18,29 @@
         ]
     },
     "initialState": {
-        "stacks": [
+        "tasks": [
             {
-                "tasks": [
+                "activities": [
                     {
-                        "activities": [
-                            {
-                                "name": "android.server.wm.cts\/android.server.wm.intent.Activities$RegularActivity",
-                                "state": "RESUMED"
-                            }
-                        ]
+                        "name": "android.server.wm.cts/android.server.wm.intent.Activities$RegularActivity",
+                        "state": "RESUMED"
                     }
-                ],
-                "resumedActivity": "android.server.wm.cts\/android.server.wm.intent.Activities$RegularActivity"
+                ]
             }
-        ]
+        ],
+        "resumedActivity": "android.server.wm.cts/android.server.wm.intent.Activities$RegularActivity"
     },
     "endState": {
-        "stacks": [
+        "tasks": [
             {
-                "tasks": [
+                "activities": [
                     {
-                        "activities": [
-                            {
-                                "name": "android.server.wm.cts\/android.server.wm.intent.Activities$RegularActivity",
-                                "state": "RESUMED"
-                            }
-                        ]
+                        "name": "android.server.wm.cts/android.server.wm.intent.Activities$RegularActivity",
+                        "state": "RESUMED"
                     }
-                ],
-                "resumedActivity": "android.server.wm.cts\/android.server.wm.intent.Activities$RegularActivity"
+                ]
             }
-        ]
+        ],
+        "resumedActivity": "android.server.wm.cts/android.server.wm.intent.Activities$RegularActivity"
     }
-}
+}
\ No newline at end of file
diff --git a/tests/framework/base/windowmanager/intent_tests/newDocumentCases/test-6.json b/tests/framework/base/windowmanager/intent_tests/newDocumentCases/test-6.json
index 07e05bc..3c9fde6 100644
--- a/tests/framework/base/windowmanager/intent_tests/newDocumentCases/test-6.json
+++ b/tests/framework/base/windowmanager/intent_tests/newDocumentCases/test-6.json
@@ -18,49 +18,37 @@
         ]
     },
     "initialState": {
-        "stacks": [
+        "tasks": [
             {
-                "tasks": [
+                "activities": [
                     {
-                        "activities": [
-                            {
-                                "name": "android.server.wm.cts\/android.server.wm.intent.Activities$RegularActivity",
-                                "state": "RESUMED"
-                            }
-                        ]
-                    }
-                ],
-                "resumedActivity": "android.server.wm.cts\/android.server.wm.intent.Activities$RegularActivity"
-            }
-        ]
-    },
-    "endState": {
-        "stacks": [
-            {
-                "tasks": [
-                    {
-                        "activities": [
-                            {
-                                "name": "android.server.wm.cts\/android.server.wm.intent.Activities$SingleTopActivity",
-                                "state": "RESUMED"
-                            }
-                        ]
-                    }
-                ],
-                "resumedActivity": "android.server.wm.cts\/android.server.wm.intent.Activities$SingleTopActivity"
-            },
-            {
-                "tasks": [
-                    {
-                        "activities": [
-                            {
-                                "name": "android.server.wm.cts\/android.server.wm.intent.Activities$RegularActivity",
-                                "state": "STOPPED"
-                            }
-                        ]
+                        "name": "android.server.wm.cts/android.server.wm.intent.Activities$RegularActivity",
+                        "state": "RESUMED"
                     }
                 ]
             }
-        ]
+        ],
+        "resumedActivity": "android.server.wm.cts/android.server.wm.intent.Activities$RegularActivity"
+    },
+    "endState": {
+        "tasks": [
+            {
+                "activities": [
+                    {
+                        "name": "android.server.wm.cts/android.server.wm.intent.Activities$SingleTopActivity",
+                        "state": "RESUMED"
+                    }
+                ]
+            },
+            {
+                "activities": [
+                    {
+                        "name": "android.server.wm.cts/android.server.wm.intent.Activities$RegularActivity",
+                        "state": "STOPPED"
+                    }
+                ]
+            }
+        ],
+        "resumedActivity": "android.server.wm.cts/android.server.wm.intent.Activities$SingleTopActivity"
     }
-}
+}
\ No newline at end of file
diff --git a/tests/framework/base/windowmanager/intent_tests/newDocumentCases/test-7.json b/tests/framework/base/windowmanager/intent_tests/newDocumentCases/test-7.json
index b6354b5..fb6f1ad 100644
--- a/tests/framework/base/windowmanager/intent_tests/newDocumentCases/test-7.json
+++ b/tests/framework/base/windowmanager/intent_tests/newDocumentCases/test-7.json
@@ -30,69 +30,53 @@
         ]
     },
     "initialState": {
-        "stacks": [
+        "tasks": [
             {
-                "tasks": [
+                "activities": [
                     {
-                        "activities": [
-                            {
-                                "name": "android.server.wm.cts\/android.server.wm.intent.Activities$TaskAffinity1Activity",
-                                "state": "RESUMED"
-                            }
-                        ]
+                        "name": "android.server.wm.cts/android.server.wm.intent.Activities$TaskAffinity1Activity",
+                        "state": "RESUMED"
                     }
-                ],
-                "resumedActivity": "android.server.wm.cts\/android.server.wm.intent.Activities$TaskAffinity1Activity"
+                ]
             },
             {
-                "tasks": [
+                "activities": [
                     {
-                        "activities": [
-                            {
-                                "name": "android.server.wm.cts\/android.server.wm.intent.Activities$RegularActivity",
-                                "state": "STOPPED"
-                            },
-                            {
-                                "name": "android.server.wm.cts\/android.server.wm.intent.Activities$TaskAffinity1Activity",
-                                "state": "STOPPED"
-                            }
-                        ]
+                        "name": "android.server.wm.cts/android.server.wm.intent.Activities$RegularActivity",
+                        "state": "STOPPED"
+                    },
+                    {
+                        "name": "android.server.wm.cts/android.server.wm.intent.Activities$TaskAffinity1Activity",
+                        "state": "STOPPED"
                     }
                 ]
             }
-        ]
+        ],
+        "resumedActivity": "android.server.wm.cts/android.server.wm.intent.Activities$TaskAffinity1Activity"
     },
     "endState": {
-        "stacks": [
+        "tasks": [
             {
-                "tasks": [
+                "activities": [
                     {
-                        "activities": [
-                            {
-                                "name": "android.server.wm.cts\/android.server.wm.intent.Activities$TaskAffinity1Activity",
-                                "state": "RESUMED"
-                            }
-                        ]
+                        "name": "android.server.wm.cts/android.server.wm.intent.Activities$TaskAffinity1Activity",
+                        "state": "RESUMED"
                     }
-                ],
-                "resumedActivity": "android.server.wm.cts\/android.server.wm.intent.Activities$TaskAffinity1Activity"
+                ]
             },
             {
-                "tasks": [
+                "activities": [
                     {
-                        "activities": [
-                            {
-                                "name": "android.server.wm.cts\/android.server.wm.intent.Activities$RegularActivity",
-                                "state": "STOPPED"
-                            },
-                            {
-                                "name": "android.server.wm.cts\/android.server.wm.intent.Activities$TaskAffinity1Activity",
-                                "state": "STOPPED"
-                            }
-                        ]
+                        "name": "android.server.wm.cts/android.server.wm.intent.Activities$RegularActivity",
+                        "state": "STOPPED"
+                    },
+                    {
+                        "name": "android.server.wm.cts/android.server.wm.intent.Activities$TaskAffinity1Activity",
+                        "state": "STOPPED"
                     }
                 ]
             }
-        ]
+        ],
+        "resumedActivity": "android.server.wm.cts/android.server.wm.intent.Activities$TaskAffinity1Activity"
     }
-}
+}
\ No newline at end of file
diff --git a/tests/framework/base/windowmanager/intent_tests/newDocumentCases/test-8.json b/tests/framework/base/windowmanager/intent_tests/newDocumentCases/test-8.json
index c8ef9f8..416ed94 100644
--- a/tests/framework/base/windowmanager/intent_tests/newDocumentCases/test-8.json
+++ b/tests/framework/base/windowmanager/intent_tests/newDocumentCases/test-8.json
@@ -36,69 +36,53 @@
         ]
     },
     "initialState": {
-        "stacks": [
+        "tasks": [
             {
-                "tasks": [
+                "activities": [
                     {
-                        "activities": [
-                            {
-                                "name": "android.server.wm.cts\/android.server.wm.intent.Activities$TaskAffinity1Activity",
-                                "state": "RESUMED"
-                            },
-                            {
-                                "name": "android.server.wm.cts\/android.server.wm.intent.Activities$RegularActivity",
-                                "state": "STOPPED"
-                            }
-                        ]
+                        "name": "android.server.wm.cts/android.server.wm.intent.Activities$TaskAffinity1Activity",
+                        "state": "RESUMED"
+                    },
+                    {
+                        "name": "android.server.wm.cts/android.server.wm.intent.Activities$RegularActivity",
+                        "state": "STOPPED"
                     }
-                ],
-                "resumedActivity": "android.server.wm.cts\/android.server.wm.intent.Activities$TaskAffinity1Activity"
+                ]
             },
             {
-                "tasks": [
+                "activities": [
                     {
-                        "activities": [
-                            {
-                                "name": "android.server.wm.cts\/android.server.wm.intent.Activities$RegularActivity",
-                                "state": "STOPPED"
-                            }
-                        ]
+                        "name": "android.server.wm.cts/android.server.wm.intent.Activities$RegularActivity",
+                        "state": "STOPPED"
                     }
                 ]
             }
-        ]
+        ],
+        "resumedActivity": "android.server.wm.cts/android.server.wm.intent.Activities$TaskAffinity1Activity"
     },
     "endState": {
-        "stacks": [
+        "tasks": [
             {
-                "tasks": [
+                "activities": [
                     {
-                        "activities": [
-                            {
-                                "name": "android.server.wm.cts\/android.server.wm.intent.Activities$TaskAffinity1Activity",
-                                "state": "RESUMED"
-                            },
-                            {
-                                "name": "android.server.wm.cts\/android.server.wm.intent.Activities$RegularActivity",
-                                "state": "STOPPED"
-                            }
-                        ]
+                        "name": "android.server.wm.cts/android.server.wm.intent.Activities$TaskAffinity1Activity",
+                        "state": "RESUMED"
+                    },
+                    {
+                        "name": "android.server.wm.cts/android.server.wm.intent.Activities$RegularActivity",
+                        "state": "STOPPED"
                     }
-                ],
-                "resumedActivity": "android.server.wm.cts\/android.server.wm.intent.Activities$TaskAffinity1Activity"
+                ]
             },
             {
-                "tasks": [
+                "activities": [
                     {
-                        "activities": [
-                            {
-                                "name": "android.server.wm.cts\/android.server.wm.intent.Activities$RegularActivity",
-                                "state": "STOPPED"
-                            }
-                        ]
+                        "name": "android.server.wm.cts/android.server.wm.intent.Activities$RegularActivity",
+                        "state": "STOPPED"
                     }
                 ]
             }
-        ]
+        ],
+        "resumedActivity": "android.server.wm.cts/android.server.wm.intent.Activities$TaskAffinity1Activity"
     }
-}
+}
\ No newline at end of file
diff --git a/tests/framework/base/windowmanager/intent_tests/newDocumentCases/test-9.json b/tests/framework/base/windowmanager/intent_tests/newDocumentCases/test-9.json
index 296475f..dd1df6f 100644
--- a/tests/framework/base/windowmanager/intent_tests/newDocumentCases/test-9.json
+++ b/tests/framework/base/windowmanager/intent_tests/newDocumentCases/test-9.json
@@ -36,81 +36,61 @@
         ]
     },
     "initialState": {
-        "stacks": [
+        "tasks": [
             {
-                "tasks": [
+                "activities": [
                     {
-                        "activities": [
-                            {
-                                "name": "android.server.wm.cts\/android.server.wm.intent.Activities$TaskAffinity1Activity",
-                                "state": "RESUMED"
-                            },
-                            {
-                                "name": "android.server.wm.cts\/android.server.wm.intent.Activities$RegularActivity",
-                                "state": "STOPPED"
-                            }
-                        ]
+                        "name": "android.server.wm.cts/android.server.wm.intent.Activities$TaskAffinity1Activity",
+                        "state": "RESUMED"
+                    },
+                    {
+                        "name": "android.server.wm.cts/android.server.wm.intent.Activities$RegularActivity",
+                        "state": "STOPPED"
                     }
-                ],
-                "resumedActivity": "android.server.wm.cts\/android.server.wm.intent.Activities$TaskAffinity1Activity"
+                ]
             },
             {
-                "tasks": [
+                "activities": [
                     {
-                        "activities": [
-                            {
-                                "name": "android.server.wm.cts\/android.server.wm.intent.Activities$RegularActivity",
-                                "state": "STOPPED"
-                            }
-                        ]
+                        "name": "android.server.wm.cts/android.server.wm.intent.Activities$RegularActivity",
+                        "state": "STOPPED"
                     }
                 ]
             }
-        ]
+        ],
+        "resumedActivity": "android.server.wm.cts/android.server.wm.intent.Activities$TaskAffinity1Activity"
     },
     "endState": {
-        "stacks": [
+        "tasks": [
             {
-                "tasks": [
+                "activities": [
                     {
-                        "activities": [
-                            {
-                                "name": "android.server.wm.cts\/android.server.wm.intent.Activities$TaskAffinity1Activity2",
-                                "state": "RESUMED"
-                            }
-                        ]
-                    }
-                ],
-                "resumedActivity": "android.server.wm.cts\/android.server.wm.intent.Activities$TaskAffinity1Activity2"
-            },
-            {
-                "tasks": [
-                    {
-                        "activities": [
-                            {
-                                "name": "android.server.wm.cts\/android.server.wm.intent.Activities$TaskAffinity1Activity",
-                                "state": "STOPPED"
-                            },
-                            {
-                                "name": "android.server.wm.cts\/android.server.wm.intent.Activities$RegularActivity",
-                                "state": "STOPPED"
-                            }
-                        ]
+                        "name": "android.server.wm.cts/android.server.wm.intent.Activities$TaskAffinity1Activity2",
+                        "state": "RESUMED"
                     }
                 ]
             },
             {
-                "tasks": [
+                "activities": [
                     {
-                        "activities": [
-                            {
-                                "name": "android.server.wm.cts\/android.server.wm.intent.Activities$RegularActivity",
-                                "state": "STOPPED"
-                            }
-                        ]
+                        "name": "android.server.wm.cts/android.server.wm.intent.Activities$TaskAffinity1Activity",
+                        "state": "STOPPED"
+                    },
+                    {
+                        "name": "android.server.wm.cts/android.server.wm.intent.Activities$RegularActivity",
+                        "state": "STOPPED"
+                    }
+                ]
+            },
+            {
+                "activities": [
+                    {
+                        "name": "android.server.wm.cts/android.server.wm.intent.Activities$RegularActivity",
+                        "state": "STOPPED"
                     }
                 ]
             }
-        ]
+        ],
+        "resumedActivity": "android.server.wm.cts/android.server.wm.intent.Activities$TaskAffinity1Activity2"
     }
-}
+}
\ No newline at end of file
diff --git a/tests/framework/base/windowmanager/intent_tests/newTask/request_new_task_different_affinity-new_task.json b/tests/framework/base/windowmanager/intent_tests/newTask/request_new_task_different_affinity-new_task.json
index 9d878d8..81cffc1 100644
--- a/tests/framework/base/windowmanager/intent_tests/newTask/request_new_task_different_affinity-new_task.json
+++ b/tests/framework/base/windowmanager/intent_tests/newTask/request_new_task_different_affinity-new_task.json
@@ -18,49 +18,37 @@
     ]
   },
   "initialState": {
-    "stacks": [
+    "tasks": [
       {
-        "tasks": [
+        "activities": [
           {
-            "activities": [
-              {
-                "name": "android.server.wm.cts\/android.server.wm.intent.Activities$TaskAffinity1Activity",
-                "state": "RESUMED"
-              }
-            ]
-          }
-        ],
-        "resumedActivity": "android.server.wm.cts\/android.server.wm.intent.Activities$TaskAffinity1Activity"
-      }
-    ]
-  },
-  "endState": {
-    "stacks": [
-      {
-        "tasks": [
-          {
-            "activities": [
-              {
-                "name": "android.server.wm.cts\/android.server.wm.intent.Activities$RegularActivity",
-                "state": "RESUMED"
-              }
-            ]
-          }
-        ],
-        "resumedActivity": "android.server.wm.cts\/android.server.wm.intent.Activities$RegularActivity"
-      },
-      {
-        "tasks": [
-          {
-            "activities": [
-              {
-                "name": "android.server.wm.cts\/android.server.wm.intent.Activities$TaskAffinity1Activity",
-                "state": "STOPPED"
-              }
-            ]
+            "name": "android.server.wm.cts/android.server.wm.intent.Activities$TaskAffinity1Activity",
+            "state": "RESUMED"
           }
         ]
       }
-    ]
+    ],
+    "resumedActivity": "android.server.wm.cts/android.server.wm.intent.Activities$TaskAffinity1Activity"
+  },
+  "endState": {
+    "tasks": [
+      {
+        "activities": [
+          {
+            "name": "android.server.wm.cts/android.server.wm.intent.Activities$RegularActivity",
+            "state": "RESUMED"
+          }
+        ]
+      },
+      {
+        "activities": [
+          {
+            "name": "android.server.wm.cts/android.server.wm.intent.Activities$TaskAffinity1Activity",
+            "state": "STOPPED"
+          }
+        ]
+      }
+    ],
+    "resumedActivity": "android.server.wm.cts/android.server.wm.intent.Activities$RegularActivity"
   }
-}
+}
\ No newline at end of file
diff --git a/tests/framework/base/windowmanager/intent_tests/newTask/request_new_task_same_affinity-same_task.json b/tests/framework/base/windowmanager/intent_tests/newTask/request_new_task_same_affinity-same_task.json
index 6944973..b8643b2 100644
--- a/tests/framework/base/windowmanager/intent_tests/newTask/request_new_task_same_affinity-same_task.json
+++ b/tests/framework/base/windowmanager/intent_tests/newTask/request_new_task_same_affinity-same_task.json
@@ -18,41 +18,33 @@
     ]
   },
   "initialState": {
-    "stacks": [
+    "tasks": [
       {
-        "tasks": [
+        "activities": [
           {
-            "activities": [
-              {
-                "name": "android.server.wm.cts\/android.server.wm.intent.Activities$TaskAffinity1Activity",
-                "state": "RESUMED"
-              }
-            ]
+            "name": "android.server.wm.cts/android.server.wm.intent.Activities$TaskAffinity1Activity",
+            "state": "RESUMED"
           }
-        ],
-        "resumedActivity": "android.server.wm.cts\/android.server.wm.intent.Activities$TaskAffinity1Activity"
+        ]
       }
-    ]
+    ],
+    "resumedActivity": "android.server.wm.cts/android.server.wm.intent.Activities$TaskAffinity1Activity"
   },
   "endState": {
-    "stacks": [
+    "tasks": [
       {
-        "tasks": [
+        "activities": [
           {
-            "activities": [
-              {
-                "name": "android.server.wm.cts\/android.server.wm.intent.Activities$TaskAffinity1Activity2",
-                "state": "RESUMED"
-              },
-              {
-                "name": "android.server.wm.cts\/android.server.wm.intent.Activities$TaskAffinity1Activity",
-                "state": "STOPPED"
-              }
-            ]
+            "name": "android.server.wm.cts/android.server.wm.intent.Activities$TaskAffinity1Activity2",
+            "state": "RESUMED"
+          },
+          {
+            "name": "android.server.wm.cts/android.server.wm.intent.Activities$TaskAffinity1Activity",
+            "state": "STOPPED"
           }
-        ],
-        "resumedActivity": "android.server.wm.cts\/android.server.wm.intent.Activities$TaskAffinity1Activity2"
+        ]
       }
-    ]
+    ],
+    "resumedActivity": "android.server.wm.cts/android.server.wm.intent.Activities$TaskAffinity1Activity2"
   }
-}
+}
\ No newline at end of file
diff --git a/tests/framework/base/windowmanager/intent_tests/newTask/request_same_task_different_affinity-same_task.json b/tests/framework/base/windowmanager/intent_tests/newTask/request_same_task_different_affinity-same_task.json
index a444299..afda6cf 100644
--- a/tests/framework/base/windowmanager/intent_tests/newTask/request_same_task_different_affinity-same_task.json
+++ b/tests/framework/base/windowmanager/intent_tests/newTask/request_same_task_different_affinity-same_task.json
@@ -18,41 +18,33 @@
     ]
   },
   "initialState": {
-    "stacks": [
+    "tasks": [
       {
-        "tasks": [
+        "activities": [
           {
-            "activities": [
-              {
-                "name": "android.server.wm.cts\/android.server.wm.intent.Activities$TaskAffinity1Activity",
-                "state": "RESUMED"
-              }
-            ]
+            "name": "android.server.wm.cts/android.server.wm.intent.Activities$TaskAffinity1Activity",
+            "state": "RESUMED"
           }
-        ],
-        "resumedActivity": "android.server.wm.cts\/android.server.wm.intent.Activities$TaskAffinity1Activity"
+        ]
       }
-    ]
+    ],
+    "resumedActivity": "android.server.wm.cts/android.server.wm.intent.Activities$TaskAffinity1Activity"
   },
   "endState": {
-    "stacks": [
+    "tasks": [
       {
-        "tasks": [
+        "activities": [
           {
-            "activities": [
-              {
-                "name": "android.server.wm.cts\/android.server.wm.intent.Activities$RegularActivity",
-                "state": "RESUMED"
-              },
-              {
-                "name": "android.server.wm.cts\/android.server.wm.intent.Activities$TaskAffinity1Activity",
-                "state": "STOPPED"
-              }
-            ]
+            "name": "android.server.wm.cts/android.server.wm.intent.Activities$RegularActivity",
+            "state": "RESUMED"
+          },
+          {
+            "name": "android.server.wm.cts/android.server.wm.intent.Activities$TaskAffinity1Activity",
+            "state": "STOPPED"
           }
-        ],
-        "resumedActivity": "android.server.wm.cts\/android.server.wm.intent.Activities$RegularActivity"
+        ]
       }
-    ]
+    ],
+    "resumedActivity": "android.server.wm.cts/android.server.wm.intent.Activities$RegularActivity"
   }
-}
+}
\ No newline at end of file
diff --git a/tests/framework/base/windowmanager/intent_tests/newTask/test-1.json b/tests/framework/base/windowmanager/intent_tests/newTask/test-1.json
index e4accd3..e50cd7e 100644
--- a/tests/framework/base/windowmanager/intent_tests/newTask/test-1.json
+++ b/tests/framework/base/windowmanager/intent_tests/newTask/test-1.json
@@ -18,49 +18,37 @@
         ]
     },
     "initialState": {
-        "stacks": [
+        "tasks": [
             {
-                "tasks": [
+                "activities": [
                     {
-                        "activities": [
-                            {
-                                "name": "android.server.wm.cts\/android.server.wm.intent.Activities$RegularActivity",
-                                "state": "RESUMED"
-                            }
-                        ]
-                    }
-                ],
-                "resumedActivity": "android.server.wm.cts\/android.server.wm.intent.Activities$RegularActivity"
-            }
-        ]
-    },
-    "endState": {
-        "stacks": [
-            {
-                "tasks": [
-                    {
-                        "activities": [
-                            {
-                                "name": "android.server.wm.cts\/android.server.wm.intent.Activities$SingleInstanceActivity",
-                                "state": "RESUMED"
-                            }
-                        ]
-                    }
-                ],
-                "resumedActivity": "android.server.wm.cts\/android.server.wm.intent.Activities$SingleInstanceActivity"
-            },
-            {
-                "tasks": [
-                    {
-                        "activities": [
-                            {
-                                "name": "android.server.wm.cts\/android.server.wm.intent.Activities$RegularActivity",
-                                "state": "STOPPED"
-                            }
-                        ]
+                        "name": "android.server.wm.cts/android.server.wm.intent.Activities$RegularActivity",
+                        "state": "RESUMED"
                     }
                 ]
             }
-        ]
+        ],
+        "resumedActivity": "android.server.wm.cts/android.server.wm.intent.Activities$RegularActivity"
+    },
+    "endState": {
+        "tasks": [
+            {
+                "activities": [
+                    {
+                        "name": "android.server.wm.cts/android.server.wm.intent.Activities$SingleInstanceActivity",
+                        "state": "RESUMED"
+                    }
+                ]
+            },
+            {
+                "activities": [
+                    {
+                        "name": "android.server.wm.cts/android.server.wm.intent.Activities$RegularActivity",
+                        "state": "STOPPED"
+                    }
+                ]
+            }
+        ],
+        "resumedActivity": "android.server.wm.cts/android.server.wm.intent.Activities$SingleInstanceActivity"
     }
-}
+}
\ No newline at end of file
diff --git a/tests/framework/base/windowmanager/intent_tests/newTask/test-10.json b/tests/framework/base/windowmanager/intent_tests/newTask/test-10.json
index 55c049a..9deada0 100644
--- a/tests/framework/base/windowmanager/intent_tests/newTask/test-10.json
+++ b/tests/framework/base/windowmanager/intent_tests/newTask/test-10.json
@@ -18,49 +18,37 @@
         ]
     },
     "initialState": {
-        "stacks": [
+        "tasks": [
             {
-                "tasks": [
+                "activities": [
                     {
-                        "activities": [
-                            {
-                                "name": "android.server.wm.cts\/android.server.wm.intent.Activities$RegularActivity",
-                                "state": "RESUMED"
-                            }
-                        ]
-                    }
-                ],
-                "resumedActivity": "android.server.wm.cts\/android.server.wm.intent.Activities$RegularActivity"
-            }
-        ]
-    },
-    "endState": {
-        "stacks": [
-            {
-                "tasks": [
-                    {
-                        "activities": [
-                            {
-                                "name": "android.server.wm.cts\/android.server.wm.intent.Activities$RegularActivity",
-                                "state": "RESUMED"
-                            }
-                        ]
-                    }
-                ],
-                "resumedActivity": "android.server.wm.cts\/android.server.wm.intent.Activities$RegularActivity"
-            },
-            {
-                "tasks": [
-                    {
-                        "activities": [
-                            {
-                                "name": "android.server.wm.cts\/android.server.wm.intent.Activities$RegularActivity",
-                                "state": "STOPPED"
-                            }
-                        ]
+                        "name": "android.server.wm.cts/android.server.wm.intent.Activities$RegularActivity",
+                        "state": "RESUMED"
                     }
                 ]
             }
-        ]
+        ],
+        "resumedActivity": "android.server.wm.cts/android.server.wm.intent.Activities$RegularActivity"
+    },
+    "endState": {
+        "tasks": [
+            {
+                "activities": [
+                    {
+                        "name": "android.server.wm.cts/android.server.wm.intent.Activities$RegularActivity",
+                        "state": "RESUMED"
+                    }
+                ]
+            },
+            {
+                "activities": [
+                    {
+                        "name": "android.server.wm.cts/android.server.wm.intent.Activities$RegularActivity",
+                        "state": "STOPPED"
+                    }
+                ]
+            }
+        ],
+        "resumedActivity": "android.server.wm.cts/android.server.wm.intent.Activities$RegularActivity"
     }
-}
+}
\ No newline at end of file
diff --git a/tests/framework/base/windowmanager/intent_tests/newTask/test-11.json b/tests/framework/base/windowmanager/intent_tests/newTask/test-11.json
index 7e3ab21..dd409a3 100644
--- a/tests/framework/base/windowmanager/intent_tests/newTask/test-11.json
+++ b/tests/framework/base/windowmanager/intent_tests/newTask/test-11.json
@@ -18,37 +18,29 @@
         ]
     },
     "initialState": {
-        "stacks": [
+        "tasks": [
             {
-                "tasks": [
+                "activities": [
                     {
-                        "activities": [
-                            {
-                                "name": "android.server.wm.cts\/android.server.wm.intent.Activities$SingleInstanceActivity",
-                                "state": "RESUMED"
-                            }
-                        ]
+                        "name": "android.server.wm.cts/android.server.wm.intent.Activities$SingleInstanceActivity",
+                        "state": "RESUMED"
                     }
-                ],
-                "resumedActivity": "android.server.wm.cts\/android.server.wm.intent.Activities$SingleInstanceActivity"
+                ]
             }
-        ]
+        ],
+        "resumedActivity": "android.server.wm.cts/android.server.wm.intent.Activities$SingleInstanceActivity"
     },
     "endState": {
-        "stacks": [
+        "tasks": [
             {
-                "tasks": [
+                "activities": [
                     {
-                        "activities": [
-                            {
-                                "name": "android.server.wm.cts\/android.server.wm.intent.Activities$SingleInstanceActivity",
-                                "state": "RESUMED"
-                            }
-                        ]
+                        "name": "android.server.wm.cts/android.server.wm.intent.Activities$SingleInstanceActivity",
+                        "state": "RESUMED"
                     }
-                ],
-                "resumedActivity": "android.server.wm.cts\/android.server.wm.intent.Activities$SingleInstanceActivity"
+                ]
             }
-        ]
+        ],
+        "resumedActivity": "android.server.wm.cts/android.server.wm.intent.Activities$SingleInstanceActivity"
     }
-}
+}
\ No newline at end of file
diff --git a/tests/framework/base/windowmanager/intent_tests/newTask/test-12.json b/tests/framework/base/windowmanager/intent_tests/newTask/test-12.json
index 563683f..d03569b 100644
--- a/tests/framework/base/windowmanager/intent_tests/newTask/test-12.json
+++ b/tests/framework/base/windowmanager/intent_tests/newTask/test-12.json
@@ -18,37 +18,29 @@
         ]
     },
     "initialState": {
-        "stacks": [
+        "tasks": [
             {
-                "tasks": [
+                "activities": [
                     {
-                        "activities": [
-                            {
-                                "name": "android.server.wm.cts\/android.server.wm.intent.Activities$SingleTaskActivity",
-                                "state": "RESUMED"
-                            }
-                        ]
+                        "name": "android.server.wm.cts/android.server.wm.intent.Activities$SingleTaskActivity",
+                        "state": "RESUMED"
                     }
-                ],
-                "resumedActivity": "android.server.wm.cts\/android.server.wm.intent.Activities$SingleTaskActivity"
+                ]
             }
-        ]
+        ],
+        "resumedActivity": "android.server.wm.cts/android.server.wm.intent.Activities$SingleTaskActivity"
     },
     "endState": {
-        "stacks": [
+        "tasks": [
             {
-                "tasks": [
+                "activities": [
                     {
-                        "activities": [
-                            {
-                                "name": "android.server.wm.cts\/android.server.wm.intent.Activities$SingleTaskActivity",
-                                "state": "RESUMED"
-                            }
-                        ]
+                        "name": "android.server.wm.cts/android.server.wm.intent.Activities$SingleTaskActivity",
+                        "state": "RESUMED"
                     }
-                ],
-                "resumedActivity": "android.server.wm.cts\/android.server.wm.intent.Activities$SingleTaskActivity"
+                ]
             }
-        ]
+        ],
+        "resumedActivity": "android.server.wm.cts/android.server.wm.intent.Activities$SingleTaskActivity"
     }
-}
+}
\ No newline at end of file
diff --git a/tests/framework/base/windowmanager/intent_tests/newTask/test-13.json b/tests/framework/base/windowmanager/intent_tests/newTask/test-13.json
index 0d6fc3d..e3c1119 100644
--- a/tests/framework/base/windowmanager/intent_tests/newTask/test-13.json
+++ b/tests/framework/base/windowmanager/intent_tests/newTask/test-13.json
@@ -18,49 +18,37 @@
         ]
     },
     "initialState": {
-        "stacks": [
+        "tasks": [
             {
-                "tasks": [
+                "activities": [
                     {
-                        "activities": [
-                            {
-                                "name": "android.server.wm.cts\/android.server.wm.intent.Activities$SingleInstanceActivity",
-                                "state": "RESUMED"
-                            }
-                        ]
-                    }
-                ],
-                "resumedActivity": "android.server.wm.cts\/android.server.wm.intent.Activities$SingleInstanceActivity"
-            }
-        ]
-    },
-    "endState": {
-        "stacks": [
-            {
-                "tasks": [
-                    {
-                        "activities": [
-                            {
-                                "name": "android.server.wm.cts\/android.server.wm.intent.Activities$RegularActivity",
-                                "state": "RESUMED"
-                            }
-                        ]
-                    }
-                ],
-                "resumedActivity": "android.server.wm.cts\/android.server.wm.intent.Activities$RegularActivity"
-            },
-            {
-                "tasks": [
-                    {
-                        "activities": [
-                            {
-                                "name": "android.server.wm.cts\/android.server.wm.intent.Activities$SingleInstanceActivity",
-                                "state": "STOPPED"
-                            }
-                        ]
+                        "name": "android.server.wm.cts/android.server.wm.intent.Activities$SingleInstanceActivity",
+                        "state": "RESUMED"
                     }
                 ]
             }
-        ]
+        ],
+        "resumedActivity": "android.server.wm.cts/android.server.wm.intent.Activities$SingleInstanceActivity"
+    },
+    "endState": {
+        "tasks": [
+            {
+                "activities": [
+                    {
+                        "name": "android.server.wm.cts/android.server.wm.intent.Activities$RegularActivity",
+                        "state": "RESUMED"
+                    }
+                ]
+            },
+            {
+                "activities": [
+                    {
+                        "name": "android.server.wm.cts/android.server.wm.intent.Activities$SingleInstanceActivity",
+                        "state": "STOPPED"
+                    }
+                ]
+            }
+        ],
+        "resumedActivity": "android.server.wm.cts/android.server.wm.intent.Activities$RegularActivity"
     }
-}
+}
\ No newline at end of file
diff --git a/tests/framework/base/windowmanager/intent_tests/newTask/test-14.json b/tests/framework/base/windowmanager/intent_tests/newTask/test-14.json
index b430952..3e3af52 100644
--- a/tests/framework/base/windowmanager/intent_tests/newTask/test-14.json
+++ b/tests/framework/base/windowmanager/intent_tests/newTask/test-14.json
@@ -18,41 +18,33 @@
         ]
     },
     "initialState": {
-        "stacks": [
+        "tasks": [
             {
-                "tasks": [
+                "activities": [
                     {
-                        "activities": [
-                            {
-                                "name": "android.server.wm.cts\/android.server.wm.intent.Activities$SingleTaskActivity",
-                                "state": "RESUMED"
-                            }
-                        ]
+                        "name": "android.server.wm.cts/android.server.wm.intent.Activities$SingleTaskActivity",
+                        "state": "RESUMED"
                     }
-                ],
-                "resumedActivity": "android.server.wm.cts\/android.server.wm.intent.Activities$SingleTaskActivity"
+                ]
             }
-        ]
+        ],
+        "resumedActivity": "android.server.wm.cts/android.server.wm.intent.Activities$SingleTaskActivity"
     },
     "endState": {
-        "stacks": [
+        "tasks": [
             {
-                "tasks": [
+                "activities": [
                     {
-                        "activities": [
-                            {
-                                "name": "android.server.wm.cts\/android.server.wm.intent.Activities$RegularActivity",
-                                "state": "RESUMED"
-                            },
-                            {
-                                "name": "android.server.wm.cts\/android.server.wm.intent.Activities$SingleTaskActivity",
-                                "state": "STOPPED"
-                            }
-                        ]
+                        "name": "android.server.wm.cts/android.server.wm.intent.Activities$RegularActivity",
+                        "state": "RESUMED"
+                    },
+                    {
+                        "name": "android.server.wm.cts/android.server.wm.intent.Activities$SingleTaskActivity",
+                        "state": "STOPPED"
                     }
-                ],
-                "resumedActivity": "android.server.wm.cts\/android.server.wm.intent.Activities$RegularActivity"
+                ]
             }
-        ]
+        ],
+        "resumedActivity": "android.server.wm.cts/android.server.wm.intent.Activities$RegularActivity"
     }
-}
+}
\ No newline at end of file
diff --git a/tests/framework/base/windowmanager/intent_tests/newTask/test-15.json b/tests/framework/base/windowmanager/intent_tests/newTask/test-15.json
index 33419d6..bf3fa0d 100644
--- a/tests/framework/base/windowmanager/intent_tests/newTask/test-15.json
+++ b/tests/framework/base/windowmanager/intent_tests/newTask/test-15.json
@@ -18,41 +18,33 @@
         ]
     },
     "initialState": {
-        "stacks": [
+        "tasks": [
             {
-                "tasks": [
+                "activities": [
                     {
-                        "activities": [
-                            {
-                                "name": "android.server.wm.cts\/android.server.wm.intent.Activities$SingleInstanceActivity",
-                                "state": "RESUMED"
-                            }
-                        ]
+                        "name": "android.server.wm.cts/android.server.wm.intent.Activities$SingleInstanceActivity",
+                        "state": "RESUMED"
                     }
-                ],
-                "resumedActivity": "android.server.wm.cts\/android.server.wm.intent.Activities$SingleInstanceActivity"
+                ]
             }
-        ]
+        ],
+        "resumedActivity": "android.server.wm.cts/android.server.wm.intent.Activities$SingleInstanceActivity"
     },
     "endState": {
-        "stacks": [
+        "tasks": [
             {
-                "tasks": [
+                "activities": [
                     {
-                        "activities": [
-                            {
-                                "name": "android.server.wm.cts\/android.server.wm.intent.Activities$RegularActivity",
-                                "state": "RESUMED"
-                            },
-                            {
-                                "name": "android.server.wm.cts\/android.server.wm.intent.Activities$SingleInstanceActivity",
-                                "state": "STOPPED"
-                            }
-                        ]
+                        "name": "android.server.wm.cts/android.server.wm.intent.Activities$RegularActivity",
+                        "state": "RESUMED"
+                    },
+                    {
+                        "name": "android.server.wm.cts/android.server.wm.intent.Activities$SingleInstanceActivity",
+                        "state": "STOPPED"
                     }
-                ],
-                "resumedActivity": "android.server.wm.cts\/android.server.wm.intent.Activities$RegularActivity"
+                ]
             }
-        ]
+        ],
+        "resumedActivity": "android.server.wm.cts/android.server.wm.intent.Activities$RegularActivity"
     }
-}
+}
\ No newline at end of file
diff --git a/tests/framework/base/windowmanager/intent_tests/newTask/test-16.json b/tests/framework/base/windowmanager/intent_tests/newTask/test-16.json
index d6eac92..8ecf183 100644
--- a/tests/framework/base/windowmanager/intent_tests/newTask/test-16.json
+++ b/tests/framework/base/windowmanager/intent_tests/newTask/test-16.json
@@ -24,61 +24,45 @@
         ]
     },
     "initialState": {
-        "stacks": [
+        "tasks": [
             {
-                "tasks": [
+                "activities": [
                     {
-                        "activities": [
-                            {
-                                "name": "android.server.wm.cts\/android.server.wm.intent.Activities$SingleInstanceActivity",
-                                "state": "RESUMED"
-                            }
-                        ]
+                        "name": "android.server.wm.cts/android.server.wm.intent.Activities$SingleInstanceActivity",
+                        "state": "RESUMED"
                     }
-                ],
-                "resumedActivity": "android.server.wm.cts\/android.server.wm.intent.Activities$SingleInstanceActivity"
+                ]
             },
             {
-                "tasks": [
+                "activities": [
                     {
-                        "activities": [
-                            {
-                                "name": "android.server.wm.cts\/android.server.wm.intent.Activities$RegularActivity",
-                                "state": "STOPPED"
-                            }
-                        ]
+                        "name": "android.server.wm.cts/android.server.wm.intent.Activities$RegularActivity",
+                        "state": "STOPPED"
                     }
                 ]
             }
-        ]
+        ],
+        "resumedActivity": "android.server.wm.cts/android.server.wm.intent.Activities$SingleInstanceActivity"
     },
     "endState": {
-        "stacks": [
+        "tasks": [
             {
-                "tasks": [
+                "activities": [
                     {
-                        "activities": [
-                            {
-                                "name": "android.server.wm.cts\/android.server.wm.intent.Activities$RegularActivity",
-                                "state": "RESUMED"
-                            }
-                        ]
+                        "name": "android.server.wm.cts/android.server.wm.intent.Activities$RegularActivity",
+                        "state": "RESUMED"
                     }
-                ],
-                "resumedActivity": "android.server.wm.cts\/android.server.wm.intent.Activities$RegularActivity"
+                ]
             },
             {
-                "tasks": [
+                "activities": [
                     {
-                        "activities": [
-                            {
-                                "name": "android.server.wm.cts\/android.server.wm.intent.Activities$SingleInstanceActivity",
-                                "state": "STOPPED"
-                            }
-                        ]
+                        "name": "android.server.wm.cts/android.server.wm.intent.Activities$SingleInstanceActivity",
+                        "state": "STOPPED"
                     }
                 ]
             }
-        ]
+        ],
+        "resumedActivity": "android.server.wm.cts/android.server.wm.intent.Activities$RegularActivity"
     }
-}
+}
\ No newline at end of file
diff --git a/tests/framework/base/windowmanager/intent_tests/newTask/test-2.json b/tests/framework/base/windowmanager/intent_tests/newTask/test-2.json
index b9acd47..5fdf01c 100644
--- a/tests/framework/base/windowmanager/intent_tests/newTask/test-2.json
+++ b/tests/framework/base/windowmanager/intent_tests/newTask/test-2.json
@@ -18,49 +18,37 @@
         ]
     },
     "initialState": {
-        "stacks": [
+        "tasks": [
             {
-                "tasks": [
+                "activities": [
                     {
-                        "activities": [
-                            {
-                                "name": "android.server.wm.cts\/android.server.wm.intent.Activities$RegularActivity",
-                                "state": "RESUMED"
-                            }
-                        ]
-                    }
-                ],
-                "resumedActivity": "android.server.wm.cts\/android.server.wm.intent.Activities$RegularActivity"
-            }
-        ]
-    },
-    "endState": {
-        "stacks": [
-            {
-                "tasks": [
-                    {
-                        "activities": [
-                            {
-                                "name": "android.server.wm.cts\/android.server.wm.intent.Activities$SingleInstanceActivity",
-                                "state": "RESUMED"
-                            }
-                        ]
-                    }
-                ],
-                "resumedActivity": "android.server.wm.cts\/android.server.wm.intent.Activities$SingleInstanceActivity"
-            },
-            {
-                "tasks": [
-                    {
-                        "activities": [
-                            {
-                                "name": "android.server.wm.cts\/android.server.wm.intent.Activities$RegularActivity",
-                                "state": "STOPPED"
-                            }
-                        ]
+                        "name": "android.server.wm.cts/android.server.wm.intent.Activities$RegularActivity",
+                        "state": "RESUMED"
                     }
                 ]
             }
-        ]
+        ],
+        "resumedActivity": "android.server.wm.cts/android.server.wm.intent.Activities$RegularActivity"
+    },
+    "endState": {
+        "tasks": [
+            {
+                "activities": [
+                    {
+                        "name": "android.server.wm.cts/android.server.wm.intent.Activities$SingleInstanceActivity",
+                        "state": "RESUMED"
+                    }
+                ]
+            },
+            {
+                "activities": [
+                    {
+                        "name": "android.server.wm.cts/android.server.wm.intent.Activities$RegularActivity",
+                        "state": "STOPPED"
+                    }
+                ]
+            }
+        ],
+        "resumedActivity": "android.server.wm.cts/android.server.wm.intent.Activities$SingleInstanceActivity"
     }
-}
+}
\ No newline at end of file
diff --git a/tests/framework/base/windowmanager/intent_tests/newTask/test-3.json b/tests/framework/base/windowmanager/intent_tests/newTask/test-3.json
index 53d01b1..c31e9a7 100644
--- a/tests/framework/base/windowmanager/intent_tests/newTask/test-3.json
+++ b/tests/framework/base/windowmanager/intent_tests/newTask/test-3.json
@@ -18,41 +18,33 @@
         ]
     },
     "initialState": {
-        "stacks": [
+        "tasks": [
             {
-                "tasks": [
+                "activities": [
                     {
-                        "activities": [
-                            {
-                                "name": "android.server.wm.cts\/android.server.wm.intent.Activities$RegularActivity",
-                                "state": "RESUMED"
-                            }
-                        ]
+                        "name": "android.server.wm.cts/android.server.wm.intent.Activities$RegularActivity",
+                        "state": "RESUMED"
                     }
-                ],
-                "resumedActivity": "android.server.wm.cts\/android.server.wm.intent.Activities$RegularActivity"
+                ]
             }
-        ]
+        ],
+        "resumedActivity": "android.server.wm.cts/android.server.wm.intent.Activities$RegularActivity"
     },
     "endState": {
-        "stacks": [
+        "tasks": [
             {
-                "tasks": [
+                "activities": [
                     {
-                        "activities": [
-                            {
-                                "name": "android.server.wm.cts\/android.server.wm.intent.Activities$TaskAffinity1Activity",
-                                "state": "RESUMED"
-                            },
-                            {
-                                "name": "android.server.wm.cts\/android.server.wm.intent.Activities$RegularActivity",
-                                "state": "STOPPED"
-                            }
-                        ]
+                        "name": "android.server.wm.cts/android.server.wm.intent.Activities$TaskAffinity1Activity",
+                        "state": "RESUMED"
+                    },
+                    {
+                        "name": "android.server.wm.cts/android.server.wm.intent.Activities$RegularActivity",
+                        "state": "STOPPED"
                     }
-                ],
-                "resumedActivity": "android.server.wm.cts\/android.server.wm.intent.Activities$TaskAffinity1Activity"
+                ]
             }
-        ]
+        ],
+        "resumedActivity": "android.server.wm.cts/android.server.wm.intent.Activities$TaskAffinity1Activity"
     }
-}
+}
\ No newline at end of file
diff --git a/tests/framework/base/windowmanager/intent_tests/newTask/test-4.json b/tests/framework/base/windowmanager/intent_tests/newTask/test-4.json
index a394a58..cacc025 100644
--- a/tests/framework/base/windowmanager/intent_tests/newTask/test-4.json
+++ b/tests/framework/base/windowmanager/intent_tests/newTask/test-4.json
@@ -18,49 +18,37 @@
         ]
     },
     "initialState": {
-        "stacks": [
+        "tasks": [
             {
-                "tasks": [
+                "activities": [
                     {
-                        "activities": [
-                            {
-                                "name": "android.server.wm.cts\/android.server.wm.intent.Activities$RegularActivity",
-                                "state": "RESUMED"
-                            }
-                        ]
-                    }
-                ],
-                "resumedActivity": "android.server.wm.cts\/android.server.wm.intent.Activities$RegularActivity"
-            }
-        ]
-    },
-    "endState": {
-        "stacks": [
-            {
-                "tasks": [
-                    {
-                        "activities": [
-                            {
-                                "name": "android.server.wm.cts\/android.server.wm.intent.Activities$TaskAffinity1Activity",
-                                "state": "RESUMED"
-                            }
-                        ]
-                    }
-                ],
-                "resumedActivity": "android.server.wm.cts\/android.server.wm.intent.Activities$TaskAffinity1Activity"
-            },
-            {
-                "tasks": [
-                    {
-                        "activities": [
-                            {
-                                "name": "android.server.wm.cts\/android.server.wm.intent.Activities$RegularActivity",
-                                "state": "STOPPED"
-                            }
-                        ]
+                        "name": "android.server.wm.cts/android.server.wm.intent.Activities$RegularActivity",
+                        "state": "RESUMED"
                     }
                 ]
             }
-        ]
+        ],
+        "resumedActivity": "android.server.wm.cts/android.server.wm.intent.Activities$RegularActivity"
+    },
+    "endState": {
+        "tasks": [
+            {
+                "activities": [
+                    {
+                        "name": "android.server.wm.cts/android.server.wm.intent.Activities$TaskAffinity1Activity",
+                        "state": "RESUMED"
+                    }
+                ]
+            },
+            {
+                "activities": [
+                    {
+                        "name": "android.server.wm.cts/android.server.wm.intent.Activities$RegularActivity",
+                        "state": "STOPPED"
+                    }
+                ]
+            }
+        ],
+        "resumedActivity": "android.server.wm.cts/android.server.wm.intent.Activities$TaskAffinity1Activity"
     }
-}
+}
\ No newline at end of file
diff --git a/tests/framework/base/windowmanager/intent_tests/newTask/test-5.json b/tests/framework/base/windowmanager/intent_tests/newTask/test-5.json
index 38d86eb..e581f5f 100644
--- a/tests/framework/base/windowmanager/intent_tests/newTask/test-5.json
+++ b/tests/framework/base/windowmanager/intent_tests/newTask/test-5.json
@@ -18,37 +18,29 @@
         ]
     },
     "initialState": {
-        "stacks": [
+        "tasks": [
             {
-                "tasks": [
+                "activities": [
                     {
-                        "activities": [
-                            {
-                                "name": "android.server.wm.cts\/android.server.wm.intent.Activities$RegularActivity",
-                                "state": "RESUMED"
-                            }
-                        ]
+                        "name": "android.server.wm.cts/android.server.wm.intent.Activities$RegularActivity",
+                        "state": "RESUMED"
                     }
-                ],
-                "resumedActivity": "android.server.wm.cts\/android.server.wm.intent.Activities$RegularActivity"
+                ]
             }
-        ]
+        ],
+        "resumedActivity": "android.server.wm.cts/android.server.wm.intent.Activities$RegularActivity"
     },
     "endState": {
-        "stacks": [
+        "tasks": [
             {
-                "tasks": [
+                "activities": [
                     {
-                        "activities": [
-                            {
-                                "name": "android.server.wm.cts\/android.server.wm.intent.Activities$RegularActivity",
-                                "state": "RESUMED"
-                            }
-                        ]
+                        "name": "android.server.wm.cts/android.server.wm.intent.Activities$RegularActivity",
+                        "state": "RESUMED"
                     }
-                ],
-                "resumedActivity": "android.server.wm.cts\/android.server.wm.intent.Activities$RegularActivity"
+                ]
             }
-        ]
+        ],
+        "resumedActivity": "android.server.wm.cts/android.server.wm.intent.Activities$RegularActivity"
     }
-}
+}
\ No newline at end of file
diff --git a/tests/framework/base/windowmanager/intent_tests/newTask/test-6.json b/tests/framework/base/windowmanager/intent_tests/newTask/test-6.json
index e279673..ad69082 100644
--- a/tests/framework/base/windowmanager/intent_tests/newTask/test-6.json
+++ b/tests/framework/base/windowmanager/intent_tests/newTask/test-6.json
@@ -18,41 +18,33 @@
         ]
     },
     "initialState": {
-        "stacks": [
+        "tasks": [
             {
-                "tasks": [
+                "activities": [
                     {
-                        "activities": [
-                            {
-                                "name": "android.server.wm.cts\/android.server.wm.intent.Activities$RegularActivity",
-                                "state": "RESUMED"
-                            }
-                        ]
+                        "name": "android.server.wm.cts/android.server.wm.intent.Activities$RegularActivity",
+                        "state": "RESUMED"
                     }
-                ],
-                "resumedActivity": "android.server.wm.cts\/android.server.wm.intent.Activities$RegularActivity"
+                ]
             }
-        ]
+        ],
+        "resumedActivity": "android.server.wm.cts/android.server.wm.intent.Activities$RegularActivity"
     },
     "endState": {
-        "stacks": [
+        "tasks": [
             {
-                "tasks": [
+                "activities": [
                     {
-                        "activities": [
-                            {
-                                "name": "android.server.wm.cts\/android.server.wm.intent.Activities$SingleTopActivity",
-                                "state": "RESUMED"
-                            },
-                            {
-                                "name": "android.server.wm.cts\/android.server.wm.intent.Activities$RegularActivity",
-                                "state": "STOPPED"
-                            }
-                        ]
+                        "name": "android.server.wm.cts/android.server.wm.intent.Activities$SingleTopActivity",
+                        "state": "RESUMED"
+                    },
+                    {
+                        "name": "android.server.wm.cts/android.server.wm.intent.Activities$RegularActivity",
+                        "state": "STOPPED"
                     }
-                ],
-                "resumedActivity": "android.server.wm.cts\/android.server.wm.intent.Activities$SingleTopActivity"
+                ]
             }
-        ]
+        ],
+        "resumedActivity": "android.server.wm.cts/android.server.wm.intent.Activities$SingleTopActivity"
     }
-}
+}
\ No newline at end of file
diff --git a/tests/framework/base/windowmanager/intent_tests/newTask/test-7.json b/tests/framework/base/windowmanager/intent_tests/newTask/test-7.json
index a7a8232..1cb96b0 100644
--- a/tests/framework/base/windowmanager/intent_tests/newTask/test-7.json
+++ b/tests/framework/base/windowmanager/intent_tests/newTask/test-7.json
@@ -30,69 +30,53 @@
         ]
     },
     "initialState": {
-        "stacks": [
+        "tasks": [
             {
-                "tasks": [
+                "activities": [
                     {
-                        "activities": [
-                            {
-                                "name": "android.server.wm.cts\/android.server.wm.intent.Activities$TaskAffinity1Activity",
-                                "state": "RESUMED"
-                            }
-                        ]
+                        "name": "android.server.wm.cts/android.server.wm.intent.Activities$TaskAffinity1Activity",
+                        "state": "RESUMED"
                     }
-                ],
-                "resumedActivity": "android.server.wm.cts\/android.server.wm.intent.Activities$TaskAffinity1Activity"
+                ]
             },
             {
-                "tasks": [
+                "activities": [
                     {
-                        "activities": [
-                            {
-                                "name": "android.server.wm.cts\/android.server.wm.intent.Activities$RegularActivity",
-                                "state": "STOPPED"
-                            },
-                            {
-                                "name": "android.server.wm.cts\/android.server.wm.intent.Activities$TaskAffinity1Activity",
-                                "state": "STOPPED"
-                            }
-                        ]
+                        "name": "android.server.wm.cts/android.server.wm.intent.Activities$RegularActivity",
+                        "state": "STOPPED"
+                    },
+                    {
+                        "name": "android.server.wm.cts/android.server.wm.intent.Activities$TaskAffinity1Activity",
+                        "state": "STOPPED"
                     }
                 ]
             }
-        ]
+        ],
+        "resumedActivity": "android.server.wm.cts/android.server.wm.intent.Activities$TaskAffinity1Activity"
     },
     "endState": {
-        "stacks": [
+        "tasks": [
             {
-                "tasks": [
+                "activities": [
                     {
-                        "activities": [
-                            {
-                                "name": "android.server.wm.cts\/android.server.wm.intent.Activities$TaskAffinity1Activity",
-                                "state": "RESUMED"
-                            }
-                        ]
+                        "name": "android.server.wm.cts/android.server.wm.intent.Activities$TaskAffinity1Activity",
+                        "state": "RESUMED"
                     }
-                ],
-                "resumedActivity": "android.server.wm.cts\/android.server.wm.intent.Activities$TaskAffinity1Activity"
+                ]
             },
             {
-                "tasks": [
+                "activities": [
                     {
-                        "activities": [
-                            {
-                                "name": "android.server.wm.cts\/android.server.wm.intent.Activities$RegularActivity",
-                                "state": "STOPPED"
-                            },
-                            {
-                                "name": "android.server.wm.cts\/android.server.wm.intent.Activities$TaskAffinity1Activity",
-                                "state": "STOPPED"
-                            }
-                        ]
+                        "name": "android.server.wm.cts/android.server.wm.intent.Activities$RegularActivity",
+                        "state": "STOPPED"
+                    },
+                    {
+                        "name": "android.server.wm.cts/android.server.wm.intent.Activities$TaskAffinity1Activity",
+                        "state": "STOPPED"
                     }
                 ]
             }
-        ]
+        ],
+        "resumedActivity": "android.server.wm.cts/android.server.wm.intent.Activities$TaskAffinity1Activity"
     }
-}
+}
\ No newline at end of file
diff --git a/tests/framework/base/windowmanager/intent_tests/newTask/test-8.json b/tests/framework/base/windowmanager/intent_tests/newTask/test-8.json
index bf57d0c..223162f 100644
--- a/tests/framework/base/windowmanager/intent_tests/newTask/test-8.json
+++ b/tests/framework/base/windowmanager/intent_tests/newTask/test-8.json
@@ -36,69 +36,53 @@
         ]
     },
     "initialState": {
-        "stacks": [
+        "tasks": [
             {
-                "tasks": [
+                "activities": [
                     {
-                        "activities": [
-                            {
-                                "name": "android.server.wm.cts\/android.server.wm.intent.Activities$TaskAffinity1Activity",
-                                "state": "RESUMED"
-                            },
-                            {
-                                "name": "android.server.wm.cts\/android.server.wm.intent.Activities$RegularActivity",
-                                "state": "STOPPED"
-                            }
-                        ]
+                        "name": "android.server.wm.cts/android.server.wm.intent.Activities$TaskAffinity1Activity",
+                        "state": "RESUMED"
+                    },
+                    {
+                        "name": "android.server.wm.cts/android.server.wm.intent.Activities$RegularActivity",
+                        "state": "STOPPED"
                     }
-                ],
-                "resumedActivity": "android.server.wm.cts\/android.server.wm.intent.Activities$TaskAffinity1Activity"
+                ]
             },
             {
-                "tasks": [
+                "activities": [
                     {
-                        "activities": [
-                            {
-                                "name": "android.server.wm.cts\/android.server.wm.intent.Activities$RegularActivity",
-                                "state": "STOPPED"
-                            }
-                        ]
+                        "name": "android.server.wm.cts/android.server.wm.intent.Activities$RegularActivity",
+                        "state": "STOPPED"
                     }
                 ]
             }
-        ]
+        ],
+        "resumedActivity": "android.server.wm.cts/android.server.wm.intent.Activities$TaskAffinity1Activity"
     },
     "endState": {
-        "stacks": [
+        "tasks": [
             {
-                "tasks": [
+                "activities": [
                     {
-                        "activities": [
-                            {
-                                "name": "android.server.wm.cts\/android.server.wm.intent.Activities$TaskAffinity1Activity",
-                                "state": "RESUMED"
-                            },
-                            {
-                                "name": "android.server.wm.cts\/android.server.wm.intent.Activities$RegularActivity",
-                                "state": "STOPPED"
-                            }
-                        ]
+                        "name": "android.server.wm.cts/android.server.wm.intent.Activities$TaskAffinity1Activity",
+                        "state": "RESUMED"
+                    },
+                    {
+                        "name": "android.server.wm.cts/android.server.wm.intent.Activities$RegularActivity",
+                        "state": "STOPPED"
                     }
-                ],
-                "resumedActivity": "android.server.wm.cts\/android.server.wm.intent.Activities$TaskAffinity1Activity"
+                ]
             },
             {
-                "tasks": [
+                "activities": [
                     {
-                        "activities": [
-                            {
-                                "name": "android.server.wm.cts\/android.server.wm.intent.Activities$RegularActivity",
-                                "state": "STOPPED"
-                            }
-                        ]
+                        "name": "android.server.wm.cts/android.server.wm.intent.Activities$RegularActivity",
+                        "state": "STOPPED"
                     }
                 ]
             }
-        ]
+        ],
+        "resumedActivity": "android.server.wm.cts/android.server.wm.intent.Activities$TaskAffinity1Activity"
     }
-}
+}
\ No newline at end of file
diff --git a/tests/framework/base/windowmanager/intent_tests/newTask/test-9.json b/tests/framework/base/windowmanager/intent_tests/newTask/test-9.json
index 5c1bd4e..18e4a34 100644
--- a/tests/framework/base/windowmanager/intent_tests/newTask/test-9.json
+++ b/tests/framework/base/windowmanager/intent_tests/newTask/test-9.json
@@ -36,73 +36,57 @@
         ]
     },
     "initialState": {
-        "stacks": [
+        "tasks": [
             {
-                "tasks": [
+                "activities": [
                     {
-                        "activities": [
-                            {
-                                "name": "android.server.wm.cts\/android.server.wm.intent.Activities$TaskAffinity1Activity",
-                                "state": "RESUMED"
-                            },
-                            {
-                                "name": "android.server.wm.cts\/android.server.wm.intent.Activities$RegularActivity",
-                                "state": "STOPPED"
-                            }
-                        ]
+                        "name": "android.server.wm.cts/android.server.wm.intent.Activities$TaskAffinity1Activity",
+                        "state": "RESUMED"
+                    },
+                    {
+                        "name": "android.server.wm.cts/android.server.wm.intent.Activities$RegularActivity",
+                        "state": "STOPPED"
                     }
-                ],
-                "resumedActivity": "android.server.wm.cts\/android.server.wm.intent.Activities$TaskAffinity1Activity"
+                ]
             },
             {
-                "tasks": [
+                "activities": [
                     {
-                        "activities": [
-                            {
-                                "name": "android.server.wm.cts\/android.server.wm.intent.Activities$RegularActivity",
-                                "state": "STOPPED"
-                            }
-                        ]
+                        "name": "android.server.wm.cts/android.server.wm.intent.Activities$RegularActivity",
+                        "state": "STOPPED"
                     }
                 ]
             }
-        ]
+        ],
+        "resumedActivity": "android.server.wm.cts/android.server.wm.intent.Activities$TaskAffinity1Activity"
     },
     "endState": {
-        "stacks": [
+        "tasks": [
             {
-                "tasks": [
+                "activities": [
                     {
-                        "activities": [
-                            {
-                                "name": "android.server.wm.cts\/android.server.wm.intent.Activities$TaskAffinity1Activity2",
-                                "state": "RESUMED"
-                            },
-                            {
-                                "name": "android.server.wm.cts\/android.server.wm.intent.Activities$TaskAffinity1Activity",
-                                "state": "STOPPED"
-                            },
-                            {
-                                "name": "android.server.wm.cts\/android.server.wm.intent.Activities$RegularActivity",
-                                "state": "STOPPED"
-                            }
-                        ]
+                        "name": "android.server.wm.cts/android.server.wm.intent.Activities$TaskAffinity1Activity2",
+                        "state": "RESUMED"
+                    },
+                    {
+                        "name": "android.server.wm.cts/android.server.wm.intent.Activities$TaskAffinity1Activity",
+                        "state": "STOPPED"
+                    },
+                    {
+                        "name": "android.server.wm.cts/android.server.wm.intent.Activities$RegularActivity",
+                        "state": "STOPPED"
                     }
-                ],
-                "resumedActivity": "android.server.wm.cts\/android.server.wm.intent.Activities$TaskAffinity1Activity2"
+                ]
             },
             {
-                "tasks": [
+                "activities": [
                     {
-                        "activities": [
-                            {
-                                "name": "android.server.wm.cts\/android.server.wm.intent.Activities$RegularActivity",
-                                "state": "STOPPED"
-                            }
-                        ]
+                        "name": "android.server.wm.cts/android.server.wm.intent.Activities$RegularActivity",
+                        "state": "STOPPED"
                     }
                 ]
             }
-        ]
+        ],
+        "resumedActivity": "android.server.wm.cts/android.server.wm.intent.Activities$TaskAffinity1Activity2"
     }
-}
+}
\ No newline at end of file
diff --git a/tests/framework/base/windowmanager/intent_tests/relinquishTaskIdentity/keep_affinity-request_new_task_with_same_affinity-same_task.json b/tests/framework/base/windowmanager/intent_tests/relinquishTaskIdentity/keep_affinity-request_new_task_with_same_affinity-same_task.json
index 3dd2c99..5df1073 100644
--- a/tests/framework/base/windowmanager/intent_tests/relinquishTaskIdentity/keep_affinity-request_new_task_with_same_affinity-same_task.json
+++ b/tests/framework/base/windowmanager/intent_tests/relinquishTaskIdentity/keep_affinity-request_new_task_with_same_affinity-same_task.json
@@ -24,49 +24,41 @@
     ]
   },
   "initialState": {
-    "stacks": [
+    "tasks": [
       {
-        "tasks": [
+        "activities": [
           {
-            "activities": [
-              {
-                "name": "android.server.wm.cts\/android.server.wm.intent.Activities$TaskAffinity1Activity",
-                "state": "RESUMED"
-              },
-              {
-                "name": "android.server.wm.cts\/android.server.wm.intent.Activities$TaskAffinity1RelinquishTaskIdentityActivity",
-                "state": "STOPPED"
-              }
-            ]
+            "name": "android.server.wm.cts/android.server.wm.intent.Activities$TaskAffinity1Activity",
+            "state": "RESUMED"
+          },
+          {
+            "name": "android.server.wm.cts/android.server.wm.intent.Activities$TaskAffinity1RelinquishTaskIdentityActivity",
+            "state": "STOPPED"
           }
-        ],
-        "resumedActivity": "android.server.wm.cts\/android.server.wm.intent.Activities$TaskAffinity1Activity"
+        ]
       }
-    ]
+    ],
+    "resumedActivity": "android.server.wm.cts/android.server.wm.intent.Activities$TaskAffinity1Activity"
   },
   "endState": {
-    "stacks": [
+    "tasks": [
       {
-        "tasks": [
+        "activities": [
           {
-            "activities": [
-              {
-                "name": "android.server.wm.cts\/android.server.wm.intent.Activities$TaskAffinity1Activity2",
-                "state": "RESUMED"
-              },
-              {
-                "name": "android.server.wm.cts\/android.server.wm.intent.Activities$TaskAffinity1Activity",
-                "state": "STOPPED"
-              },
-              {
-                "name": "android.server.wm.cts\/android.server.wm.intent.Activities$TaskAffinity1RelinquishTaskIdentityActivity",
-                "state": "STOPPED"
-              }
-            ]
+            "name": "android.server.wm.cts/android.server.wm.intent.Activities$TaskAffinity1Activity2",
+            "state": "RESUMED"
+          },
+          {
+            "name": "android.server.wm.cts/android.server.wm.intent.Activities$TaskAffinity1Activity",
+            "state": "STOPPED"
+          },
+          {
+            "name": "android.server.wm.cts/android.server.wm.intent.Activities$TaskAffinity1RelinquishTaskIdentityActivity",
+            "state": "STOPPED"
           }
-        ],
-        "resumedActivity": "android.server.wm.cts\/android.server.wm.intent.Activities$TaskAffinity1Activity2"
+        ]
       }
-    ]
+    ],
+    "resumedActivity": "android.server.wm.cts/android.server.wm.intent.Activities$TaskAffinity1Activity2"
   }
-}
+}
\ No newline at end of file
diff --git a/tests/framework/base/windowmanager/intent_tests/relinquishTaskIdentity/request_change_affinity-request_new_task_with_changed_affinity-new_task.json b/tests/framework/base/windowmanager/intent_tests/relinquishTaskIdentity/request_change_affinity-request_new_task_with_changed_affinity-new_task.json
index 53f01b5..e3abfe9 100644
--- a/tests/framework/base/windowmanager/intent_tests/relinquishTaskIdentity/request_change_affinity-request_new_task_with_changed_affinity-new_task.json
+++ b/tests/framework/base/windowmanager/intent_tests/relinquishTaskIdentity/request_change_affinity-request_new_task_with_changed_affinity-new_task.json
@@ -25,57 +25,45 @@
     ]
   },
   "initialState": {
-    "stacks": [
+    "tasks": [
       {
-        "tasks": [
+        "activities": [
           {
-            "activities": [
-              {
-                "name": "android.server.wm.cts\/android.server.wm.intent.Activities$TaskAffinity1Activity",
-                "state": "RESUMED"
-              },
-              {
-                "name": "android.server.wm.cts\/android.server.wm.intent.Activities$RelinquishTaskIdentityActivity",
-                "state": "STOPPED"
-              }
-            ]
-          }
-        ],
-        "resumedActivity": "android.server.wm.cts\/android.server.wm.intent.Activities$TaskAffinity1Activity"
-      }
-    ]
-  },
-  "endState": {
-    "stacks": [
-      {
-        "tasks": [
+            "name": "android.server.wm.cts/android.server.wm.intent.Activities$TaskAffinity1Activity",
+            "state": "RESUMED"
+          },
           {
-            "activities": [
-              {
-                "name": "android.server.wm.cts\/android.server.wm.intent.Activities$TaskAffinity1Activity2",
-                "state": "RESUMED"
-              }
-            ]
-          }
-        ],
-        "resumedActivity": "android.server.wm.cts\/android.server.wm.intent.Activities$TaskAffinity1Activity2"
-      },
-      {
-        "tasks": [
-          {
-            "activities": [
-              {
-                "name": "android.server.wm.cts\/android.server.wm.intent.Activities$TaskAffinity1Activity",
-                "state": "STOPPED"
-              },
-              {
-                "name": "android.server.wm.cts\/android.server.wm.intent.Activities$RelinquishTaskIdentityActivity",
-                "state": "STOPPED"
-              }
-            ]
+            "name": "android.server.wm.cts/android.server.wm.intent.Activities$RelinquishTaskIdentityActivity",
+            "state": "STOPPED"
           }
         ]
       }
-    ]
+    ],
+    "resumedActivity": "android.server.wm.cts/android.server.wm.intent.Activities$TaskAffinity1Activity"
+  },
+  "endState": {
+    "tasks": [
+      {
+        "activities": [
+          {
+            "name": "android.server.wm.cts/android.server.wm.intent.Activities$TaskAffinity1Activity2",
+            "state": "RESUMED"
+          }
+        ]
+      },
+      {
+        "activities": [
+          {
+            "name": "android.server.wm.cts/android.server.wm.intent.Activities$TaskAffinity1Activity",
+            "state": "STOPPED"
+          },
+          {
+            "name": "android.server.wm.cts/android.server.wm.intent.Activities$RelinquishTaskIdentityActivity",
+            "state": "STOPPED"
+          }
+        ]
+      }
+    ],
+    "resumedActivity": "android.server.wm.cts/android.server.wm.intent.Activities$TaskAffinity1Activity2"
   }
-}
+}
\ No newline at end of file
diff --git a/tests/framework/base/windowmanager/intent_tests/relinquishTaskIdentity/request_change_affinity-request_new_task_with_old_affinity-same_task.json b/tests/framework/base/windowmanager/intent_tests/relinquishTaskIdentity/request_change_affinity-request_new_task_with_old_affinity-same_task.json
index 2ec6f78..6ddb36c 100644
--- a/tests/framework/base/windowmanager/intent_tests/relinquishTaskIdentity/request_change_affinity-request_new_task_with_old_affinity-same_task.json
+++ b/tests/framework/base/windowmanager/intent_tests/relinquishTaskIdentity/request_change_affinity-request_new_task_with_old_affinity-same_task.json
@@ -25,49 +25,41 @@
     ]
   },
   "initialState": {
-    "stacks": [
+    "tasks": [
       {
-        "tasks": [
+        "activities": [
           {
-            "activities": [
-              {
-                "name": "android.server.wm.cts\/android.server.wm.intent.Activities$TaskAffinity1Activity",
-                "state": "RESUMED"
-              },
-              {
-                "name": "android.server.wm.cts\/android.server.wm.intent.Activities$RelinquishTaskIdentityActivity",
-                "state": "STOPPED"
-              }
-            ]
+            "name": "android.server.wm.cts/android.server.wm.intent.Activities$TaskAffinity1Activity",
+            "state": "RESUMED"
+          },
+          {
+            "name": "android.server.wm.cts/android.server.wm.intent.Activities$RelinquishTaskIdentityActivity",
+            "state": "STOPPED"
           }
-        ],
-        "resumedActivity": "android.server.wm.cts\/android.server.wm.intent.Activities$TaskAffinity1Activity"
+        ]
       }
-    ]
+    ],
+    "resumedActivity": "android.server.wm.cts/android.server.wm.intent.Activities$TaskAffinity1Activity"
   },
   "endState": {
-    "stacks": [
+    "tasks": [
       {
-        "tasks": [
+        "activities": [
           {
-            "activities": [
-              {
-                "name": "android.server.wm.cts\/android.server.wm.intent.Activities$RegularActivity",
-                "state": "RESUMED"
-              },
-              {
-                "name": "android.server.wm.cts\/android.server.wm.intent.Activities$TaskAffinity1Activity",
-                "state": "STOPPED"
-              },
-              {
-                "name": "android.server.wm.cts\/android.server.wm.intent.Activities$RelinquishTaskIdentityActivity",
-                "state": "STOPPED"
-              }
-            ]
+            "name": "android.server.wm.cts/android.server.wm.intent.Activities$RegularActivity",
+            "state": "RESUMED"
+          },
+          {
+            "name": "android.server.wm.cts/android.server.wm.intent.Activities$TaskAffinity1Activity",
+            "state": "STOPPED"
+          },
+          {
+            "name": "android.server.wm.cts/android.server.wm.intent.Activities$RelinquishTaskIdentityActivity",
+            "state": "STOPPED"
           }
-        ],
-        "resumedActivity": "android.server.wm.cts\/android.server.wm.intent.Activities$RegularActivity"
+        ]
       }
-    ]
+    ],
+    "resumedActivity": "android.server.wm.cts/android.server.wm.intent.Activities$RegularActivity"
   }
-}
+}
\ No newline at end of file
diff --git a/tests/framework/base/windowmanager/intent_tests/relinquishTaskIdentity/request_change_affinity-request_same_task_with_changed_affinity-same_task.json b/tests/framework/base/windowmanager/intent_tests/relinquishTaskIdentity/request_change_affinity-request_same_task_with_changed_affinity-same_task.json
index 7e31db4..9d19f4a 100644
--- a/tests/framework/base/windowmanager/intent_tests/relinquishTaskIdentity/request_change_affinity-request_same_task_with_changed_affinity-same_task.json
+++ b/tests/framework/base/windowmanager/intent_tests/relinquishTaskIdentity/request_change_affinity-request_same_task_with_changed_affinity-same_task.json
@@ -25,49 +25,41 @@
     ]
   },
   "initialState": {
-    "stacks": [
+    "tasks": [
       {
-        "tasks": [
+        "activities": [
           {
-            "activities": [
-              {
-                "name": "android.server.wm.cts\/android.server.wm.intent.Activities$TaskAffinity1Activity",
-                "state": "RESUMED"
-              },
-              {
-                "name": "android.server.wm.cts\/android.server.wm.intent.Activities$RelinquishTaskIdentityActivity",
-                "state": "STOPPED"
-              }
-            ]
+            "name": "android.server.wm.cts/android.server.wm.intent.Activities$TaskAffinity1Activity",
+            "state": "RESUMED"
+          },
+          {
+            "name": "android.server.wm.cts/android.server.wm.intent.Activities$RelinquishTaskIdentityActivity",
+            "state": "STOPPED"
           }
-        ],
-        "resumedActivity": "android.server.wm.cts\/android.server.wm.intent.Activities$TaskAffinity1Activity"
+        ]
       }
-    ]
+    ],
+    "resumedActivity": "android.server.wm.cts/android.server.wm.intent.Activities$TaskAffinity1Activity"
   },
   "endState": {
-    "stacks": [
+    "tasks": [
       {
-        "tasks": [
+        "activities": [
           {
-            "activities": [
-              {
-                "name": "android.server.wm.cts\/android.server.wm.intent.Activities$TaskAffinity1Activity2",
-                "state": "RESUMED"
-              },
-              {
-                "name": "android.server.wm.cts\/android.server.wm.intent.Activities$TaskAffinity1Activity",
-                "state": "STOPPED"
-              },
-              {
-                "name": "android.server.wm.cts\/android.server.wm.intent.Activities$RelinquishTaskIdentityActivity",
-                "state": "STOPPED"
-              }
-            ]
+            "name": "android.server.wm.cts/android.server.wm.intent.Activities$TaskAffinity1Activity2",
+            "state": "RESUMED"
+          },
+          {
+            "name": "android.server.wm.cts/android.server.wm.intent.Activities$TaskAffinity1Activity",
+            "state": "STOPPED"
+          },
+          {
+            "name": "android.server.wm.cts/android.server.wm.intent.Activities$RelinquishTaskIdentityActivity",
+            "state": "STOPPED"
           }
-        ],
-        "resumedActivity": "android.server.wm.cts\/android.server.wm.intent.Activities$TaskAffinity1Activity2"
+        ]
       }
-    ]
+    ],
+    "resumedActivity": "android.server.wm.cts/android.server.wm.intent.Activities$TaskAffinity1Activity2"
   }
-}
+}
\ No newline at end of file
diff --git a/tests/framework/base/windowmanager/intent_tests/relinquishTaskIdentity/request_change_affinity-request_same_task_with_old_affinity-same_task.json b/tests/framework/base/windowmanager/intent_tests/relinquishTaskIdentity/request_change_affinity-request_same_task_with_old_affinity-same_task.json
index afd155a..72fdff1 100644
--- a/tests/framework/base/windowmanager/intent_tests/relinquishTaskIdentity/request_change_affinity-request_same_task_with_old_affinity-same_task.json
+++ b/tests/framework/base/windowmanager/intent_tests/relinquishTaskIdentity/request_change_affinity-request_same_task_with_old_affinity-same_task.json
@@ -25,49 +25,41 @@
     ]
   },
   "initialState": {
-    "stacks": [
+    "tasks": [
       {
-        "tasks": [
+        "activities": [
           {
-            "activities": [
-              {
-                "name": "android.server.wm.cts\/android.server.wm.intent.Activities$TaskAffinity1Activity",
-                "state": "RESUMED"
-              },
-              {
-                "name": "android.server.wm.cts\/android.server.wm.intent.Activities$RelinquishTaskIdentityActivity",
-                "state": "STOPPED"
-              }
-            ]
+            "name": "android.server.wm.cts/android.server.wm.intent.Activities$TaskAffinity1Activity",
+            "state": "RESUMED"
+          },
+          {
+            "name": "android.server.wm.cts/android.server.wm.intent.Activities$RelinquishTaskIdentityActivity",
+            "state": "STOPPED"
           }
-        ],
-        "resumedActivity": "android.server.wm.cts\/android.server.wm.intent.Activities$TaskAffinity1Activity"
+        ]
       }
-    ]
+    ],
+    "resumedActivity": "android.server.wm.cts/android.server.wm.intent.Activities$TaskAffinity1Activity"
   },
   "endState": {
-    "stacks": [
+    "tasks": [
       {
-        "tasks": [
+        "activities": [
           {
-            "activities": [
-              {
-                "name": "android.server.wm.cts\/android.server.wm.intent.Activities$RegularActivity",
-                "state": "RESUMED"
-              },
-              {
-                "name": "android.server.wm.cts\/android.server.wm.intent.Activities$TaskAffinity1Activity",
-                "state": "STOPPED"
-              },
-              {
-                "name": "android.server.wm.cts\/android.server.wm.intent.Activities$RelinquishTaskIdentityActivity",
-                "state": "STOPPED"
-              }
-            ]
+            "name": "android.server.wm.cts/android.server.wm.intent.Activities$RegularActivity",
+            "state": "RESUMED"
+          },
+          {
+            "name": "android.server.wm.cts/android.server.wm.intent.Activities$TaskAffinity1Activity",
+            "state": "STOPPED"
+          },
+          {
+            "name": "android.server.wm.cts/android.server.wm.intent.Activities$RelinquishTaskIdentityActivity",
+            "state": "STOPPED"
           }
-        ],
-        "resumedActivity": "android.server.wm.cts\/android.server.wm.intent.Activities$RegularActivity"
+        ]
       }
-    ]
+    ],
+    "resumedActivity": "android.server.wm.cts/android.server.wm.intent.Activities$RegularActivity"
   }
-}
+}
\ No newline at end of file
diff --git a/tests/framework/base/windowmanager/intent_tests/relinquishTaskIdentity/request_new_task_with_different_affinity-new_task.json b/tests/framework/base/windowmanager/intent_tests/relinquishTaskIdentity/request_new_task_with_different_affinity-new_task.json
index cd6a3a4..d38f653 100644
--- a/tests/framework/base/windowmanager/intent_tests/relinquishTaskIdentity/request_new_task_with_different_affinity-new_task.json
+++ b/tests/framework/base/windowmanager/intent_tests/relinquishTaskIdentity/request_new_task_with_different_affinity-new_task.json
@@ -18,49 +18,37 @@
     ]
   },
   "initialState": {
-    "stacks": [
+    "tasks": [
       {
-        "tasks": [
+        "activities": [
           {
-            "activities": [
-              {
-                "name": "android.server.wm.cts\/android.server.wm.intent.Activities$TaskAffinity1RelinquishTaskIdentityActivity",
-                "state": "RESUMED"
-              }
-            ]
-          }
-        ],
-        "resumedActivity": "android.server.wm.cts\/android.server.wm.intent.Activities$TaskAffinity1RelinquishTaskIdentityActivity"
-      }
-    ]
-  },
-  "endState": {
-    "stacks": [
-      {
-        "tasks": [
-          {
-            "activities": [
-              {
-                "name": "android.server.wm.cts\/android.server.wm.intent.Activities$RegularActivity",
-                "state": "RESUMED"
-              }
-            ]
-          }
-        ],
-        "resumedActivity": "android.server.wm.cts\/android.server.wm.intent.Activities$RegularActivity"
-      },
-      {
-        "tasks": [
-          {
-            "activities": [
-              {
-                "name": "android.server.wm.cts\/android.server.wm.intent.Activities$TaskAffinity1RelinquishTaskIdentityActivity",
-                "state": "STOPPED"
-              }
-            ]
+            "name": "android.server.wm.cts/android.server.wm.intent.Activities$TaskAffinity1RelinquishTaskIdentityActivity",
+            "state": "RESUMED"
           }
         ]
       }
-    ]
+    ],
+    "resumedActivity": "android.server.wm.cts/android.server.wm.intent.Activities$TaskAffinity1RelinquishTaskIdentityActivity"
+  },
+  "endState": {
+    "tasks": [
+      {
+        "activities": [
+          {
+            "name": "android.server.wm.cts/android.server.wm.intent.Activities$RegularActivity",
+            "state": "RESUMED"
+          }
+        ]
+      },
+      {
+        "activities": [
+          {
+            "name": "android.server.wm.cts/android.server.wm.intent.Activities$TaskAffinity1RelinquishTaskIdentityActivity",
+            "state": "STOPPED"
+          }
+        ]
+      }
+    ],
+    "resumedActivity": "android.server.wm.cts/android.server.wm.intent.Activities$RegularActivity"
   }
-}
+}
\ No newline at end of file
diff --git a/tests/framework/base/windowmanager/intent_tests/relinquishTaskIdentity/request_new_task_with_same_affinity-same_task.json b/tests/framework/base/windowmanager/intent_tests/relinquishTaskIdentity/request_new_task_with_same_affinity-same_task.json
index 999ee82..59e764b 100644
--- a/tests/framework/base/windowmanager/intent_tests/relinquishTaskIdentity/request_new_task_with_same_affinity-same_task.json
+++ b/tests/framework/base/windowmanager/intent_tests/relinquishTaskIdentity/request_new_task_with_same_affinity-same_task.json
@@ -18,41 +18,33 @@
     ]
   },
   "initialState": {
-    "stacks": [
+    "tasks": [
       {
-        "tasks": [
+        "activities": [
           {
-            "activities": [
-              {
-                "name": "android.server.wm.cts\/android.server.wm.intent.Activities$TaskAffinity1RelinquishTaskIdentityActivity",
-                "state": "RESUMED"
-              }
-            ]
+            "name": "android.server.wm.cts/android.server.wm.intent.Activities$TaskAffinity1RelinquishTaskIdentityActivity",
+            "state": "RESUMED"
           }
-        ],
-        "resumedActivity": "android.server.wm.cts\/android.server.wm.intent.Activities$TaskAffinity1RelinquishTaskIdentityActivity"
+        ]
       }
-    ]
+    ],
+    "resumedActivity": "android.server.wm.cts/android.server.wm.intent.Activities$TaskAffinity1RelinquishTaskIdentityActivity"
   },
   "endState": {
-    "stacks": [
+    "tasks": [
       {
-        "tasks": [
+        "activities": [
           {
-            "activities": [
-              {
-                "name": "android.server.wm.cts\/android.server.wm.intent.Activities$TaskAffinity1Activity",
-                "state": "RESUMED"
-              },
-              {
-                "name": "android.server.wm.cts\/android.server.wm.intent.Activities$TaskAffinity1RelinquishTaskIdentityActivity",
-                "state": "STOPPED"
-              }
-            ]
+            "name": "android.server.wm.cts/android.server.wm.intent.Activities$TaskAffinity1Activity",
+            "state": "RESUMED"
+          },
+          {
+            "name": "android.server.wm.cts/android.server.wm.intent.Activities$TaskAffinity1RelinquishTaskIdentityActivity",
+            "state": "STOPPED"
           }
-        ],
-        "resumedActivity": "android.server.wm.cts\/android.server.wm.intent.Activities$TaskAffinity1Activity"
+        ]
       }
-    ]
+    ],
+    "resumedActivity": "android.server.wm.cts/android.server.wm.intent.Activities$TaskAffinity1Activity"
   }
-}
+}
\ No newline at end of file
diff --git a/tests/framework/base/windowmanager/intent_tests/relinquishTaskIdentity/request_same_task_with_different_affinity-same_task.json b/tests/framework/base/windowmanager/intent_tests/relinquishTaskIdentity/request_same_task_with_different_affinity-same_task.json
index d0ec60c..0994b60 100644
--- a/tests/framework/base/windowmanager/intent_tests/relinquishTaskIdentity/request_same_task_with_different_affinity-same_task.json
+++ b/tests/framework/base/windowmanager/intent_tests/relinquishTaskIdentity/request_same_task_with_different_affinity-same_task.json
@@ -18,41 +18,33 @@
     ]
   },
   "initialState": {
-    "stacks": [
+    "tasks": [
       {
-        "tasks": [
+        "activities": [
           {
-            "activities": [
-              {
-                "name": "android.server.wm.cts\/android.server.wm.intent.Activities$TaskAffinity1RelinquishTaskIdentityActivity",
-                "state": "RESUMED"
-              }
-            ]
+            "name": "android.server.wm.cts/android.server.wm.intent.Activities$TaskAffinity1RelinquishTaskIdentityActivity",
+            "state": "RESUMED"
           }
-        ],
-        "resumedActivity": "android.server.wm.cts\/android.server.wm.intent.Activities$TaskAffinity1RelinquishTaskIdentityActivity"
+        ]
       }
-    ]
+    ],
+    "resumedActivity": "android.server.wm.cts/android.server.wm.intent.Activities$TaskAffinity1RelinquishTaskIdentityActivity"
   },
   "endState": {
-    "stacks": [
+    "tasks": [
       {
-        "tasks": [
+        "activities": [
           {
-            "activities": [
-              {
-                "name": "android.server.wm.cts\/android.server.wm.intent.Activities$RegularActivity",
-                "state": "RESUMED"
-              },
-              {
-                "name": "android.server.wm.cts\/android.server.wm.intent.Activities$TaskAffinity1RelinquishTaskIdentityActivity",
-                "state": "STOPPED"
-              }
-            ]
+            "name": "android.server.wm.cts/android.server.wm.intent.Activities$RegularActivity",
+            "state": "RESUMED"
+          },
+          {
+            "name": "android.server.wm.cts/android.server.wm.intent.Activities$TaskAffinity1RelinquishTaskIdentityActivity",
+            "state": "STOPPED"
           }
-        ],
-        "resumedActivity": "android.server.wm.cts\/android.server.wm.intent.Activities$RegularActivity"
+        ]
       }
-    ]
+    ],
+    "resumedActivity": "android.server.wm.cts/android.server.wm.intent.Activities$RegularActivity"
   }
-}
+}
\ No newline at end of file
diff --git a/tests/framework/base/windowmanager/intent_tests/reorderToFront/reorder-to-front.json b/tests/framework/base/windowmanager/intent_tests/reorderToFront/reorder-to-front.json
index 9daaa0f..923d407 100644
--- a/tests/framework/base/windowmanager/intent_tests/reorderToFront/reorder-to-front.json
+++ b/tests/framework/base/windowmanager/intent_tests/reorderToFront/reorder-to-front.json
@@ -36,61 +36,53 @@
         ]
     },
     "initialState": {
-        "stacks": [
+        "tasks": [
             {
-                "tasks": [
+                "activities": [
                     {
-                        "activities": [
-                            {
-                                "name": "android.server.wm.cts\/android.server.wm.intent.Activities$RegularActivity",
-                                "state": "RESUMED"
-                            },
-                            {
-                                "name": "android.server.wm.cts\/android.server.wm.intent.Activities$TaskAffinity2Activity",
-                                "state": "STOPPED"
-                            },
-                            {
-                                "name": "android.server.wm.cts\/android.server.wm.intent.Activities$TaskAffinity1Activity",
-                                "state": "STOPPED"
-                            },
-                            {
-                                "name": "android.server.wm.cts\/android.server.wm.intent.Activities$RegularActivity",
-                                "state": "STOPPED"
-                            }
-                        ]
+                        "name": "android.server.wm.cts/android.server.wm.intent.Activities$RegularActivity",
+                        "state": "RESUMED"
+                    },
+                    {
+                        "name": "android.server.wm.cts/android.server.wm.intent.Activities$TaskAffinity2Activity",
+                        "state": "STOPPED"
+                    },
+                    {
+                        "name": "android.server.wm.cts/android.server.wm.intent.Activities$TaskAffinity1Activity",
+                        "state": "STOPPED"
+                    },
+                    {
+                        "name": "android.server.wm.cts/android.server.wm.intent.Activities$RegularActivity",
+                        "state": "STOPPED"
                     }
-                ],
-                "resumedActivity": "android.server.wm.cts\/android.server.wm.intent.Activities$RegularActivity"
+                ]
             }
-        ]
+        ],
+        "resumedActivity": "android.server.wm.cts/android.server.wm.intent.Activities$RegularActivity"
     },
     "endState": {
-        "stacks": [
+        "tasks": [
             {
-                "tasks": [
+                "activities": [
                     {
-                        "activities": [
-                            {
-                                "name": "android.server.wm.cts\/android.server.wm.intent.Activities$TaskAffinity1Activity",
-                                "state": "RESUMED"
-                            },
-                            {
-                                "name": "android.server.wm.cts\/android.server.wm.intent.Activities$RegularActivity",
-                                "state": "STOPPED"
-                            },
-                            {
-                                "name": "android.server.wm.cts\/android.server.wm.intent.Activities$TaskAffinity2Activity",
-                                "state": "STOPPED"
-                            },
-                            {
-                                "name": "android.server.wm.cts\/android.server.wm.intent.Activities$RegularActivity",
-                                "state": "STOPPED"
-                            }
-                        ]
+                        "name": "android.server.wm.cts/android.server.wm.intent.Activities$TaskAffinity1Activity",
+                        "state": "RESUMED"
+                    },
+                    {
+                        "name": "android.server.wm.cts/android.server.wm.intent.Activities$RegularActivity",
+                        "state": "STOPPED"
+                    },
+                    {
+                        "name": "android.server.wm.cts/android.server.wm.intent.Activities$TaskAffinity2Activity",
+                        "state": "STOPPED"
+                    },
+                    {
+                        "name": "android.server.wm.cts/android.server.wm.intent.Activities$RegularActivity",
+                        "state": "STOPPED"
                     }
-                ],
-                "resumedActivity": "android.server.wm.cts\/android.server.wm.intent.Activities$TaskAffinity1Activity"
+                ]
             }
-        ]
+        ],
+        "resumedActivity": "android.server.wm.cts/android.server.wm.intent.Activities$TaskAffinity1Activity"
     }
-}
+}
\ No newline at end of file
diff --git a/tests/framework/base/windowmanager/intent_tests/reorderToFront/reorder-to-front_with_new-task_on_different_affinity.json b/tests/framework/base/windowmanager/intent_tests/reorderToFront/reorder-to-front_with_new-task_on_different_affinity.json
index ab9ae9b..804ef10 100644
--- a/tests/framework/base/windowmanager/intent_tests/reorderToFront/reorder-to-front_with_new-task_on_different_affinity.json
+++ b/tests/framework/base/windowmanager/intent_tests/reorderToFront/reorder-to-front_with_new-task_on_different_affinity.json
@@ -31,65 +31,53 @@
         ]
     },
     "initialState": {
-        "stacks": [
+        "tasks": [
             {
-                "tasks": [
+                "activities": [
                     {
-                        "activities": [
-                            {
-                                "name": "android.server.wm.cts\/android.server.wm.intent.Activities$TaskAffinity2Activity",
-                                "state": "RESUMED"
-                            },
-                            {
-                                "name": "android.server.wm.cts\/android.server.wm.intent.Activities$TaskAffinity1Activity",
-                                "state": "STOPPED"
-                            },
-                            {
-                                "name": "android.server.wm.cts\/android.server.wm.intent.Activities$RegularActivity",
-                                "state": "STOPPED"
-                            }
-                        ]
-                    }
-                ],
-                "resumedActivity": "android.server.wm.cts\/android.server.wm.intent.Activities$TaskAffinity2Activity"
-            }
-        ]
-    },
-    "endState": {
-        "stacks": [
-            {
-                "tasks": [
+                        "name": "android.server.wm.cts/android.server.wm.intent.Activities$TaskAffinity2Activity",
+                        "state": "RESUMED"
+                    },
                     {
-                        "activities": [
-                            {
-                                "name": "android.server.wm.cts\/android.server.wm.intent.Activities$TaskAffinity1Activity",
-                                "state": "RESUMED"
-                            }
-                        ]
-                    }
-                ],
-                "resumedActivity": "android.server.wm.cts\/android.server.wm.intent.Activities$TaskAffinity1Activity"
-            },
-            {
-                "tasks": [
+                        "name": "android.server.wm.cts/android.server.wm.intent.Activities$TaskAffinity1Activity",
+                        "state": "STOPPED"
+                    },
                     {
-                        "activities": [
-                            {
-                                "name": "android.server.wm.cts\/android.server.wm.intent.Activities$TaskAffinity2Activity",
-                                "state": "STOPPED"
-                            },
-                            {
-                                "name": "android.server.wm.cts\/android.server.wm.intent.Activities$TaskAffinity1Activity",
-                                "state": "STOPPED"
-                            },
-                            {
-                                "name": "android.server.wm.cts\/android.server.wm.intent.Activities$RegularActivity",
-                                "state": "STOPPED"
-                            }
-                        ]
+                        "name": "android.server.wm.cts/android.server.wm.intent.Activities$RegularActivity",
+                        "state": "STOPPED"
                     }
                 ]
             }
-        ]
+        ],
+        "resumedActivity": "android.server.wm.cts/android.server.wm.intent.Activities$TaskAffinity2Activity"
+    },
+    "endState": {
+        "tasks": [
+            {
+                "activities": [
+                    {
+                        "name": "android.server.wm.cts/android.server.wm.intent.Activities$TaskAffinity1Activity",
+                        "state": "RESUMED"
+                    }
+                ]
+            },
+            {
+                "activities": [
+                    {
+                        "name": "android.server.wm.cts/android.server.wm.intent.Activities$TaskAffinity2Activity",
+                        "state": "STOPPED"
+                    },
+                    {
+                        "name": "android.server.wm.cts/android.server.wm.intent.Activities$TaskAffinity1Activity",
+                        "state": "STOPPED"
+                    },
+                    {
+                        "name": "android.server.wm.cts/android.server.wm.intent.Activities$RegularActivity",
+                        "state": "STOPPED"
+                    }
+                ]
+            }
+        ],
+        "resumedActivity": "android.server.wm.cts/android.server.wm.intent.Activities$TaskAffinity1Activity"
     }
-}
+}
\ No newline at end of file
diff --git a/tests/framework/base/windowmanager/intent_tests/resetTaskIfNeeded/reset-task.json b/tests/framework/base/windowmanager/intent_tests/resetTaskIfNeeded/reset-task.json
index 5d5aae5..e58e834 100644
--- a/tests/framework/base/windowmanager/intent_tests/resetTaskIfNeeded/reset-task.json
+++ b/tests/framework/base/windowmanager/intent_tests/resetTaskIfNeeded/reset-task.json
@@ -18,41 +18,33 @@
         ]
     },
     "initialState": {
-        "stacks": [
+        "tasks": [
             {
-                "tasks": [
+                "activities": [
                     {
-                        "activities": [
-                            {
-                                "name": "android.server.wm.cts\/android.server.wm.intent.Activities$RegularActivity",
-                                "state": "RESUMED"
-                            }
-                        ]
+                        "name": "android.server.wm.cts/android.server.wm.intent.Activities$RegularActivity",
+                        "state": "RESUMED"
                     }
-                ],
-                "resumedActivity": "android.server.wm.cts\/android.server.wm.intent.Activities$RegularActivity"
+                ]
             }
-        ]
+        ],
+        "resumedActivity": "android.server.wm.cts/android.server.wm.intent.Activities$RegularActivity"
     },
     "endState": {
-        "stacks": [
+        "tasks": [
             {
-                "tasks": [
+                "activities": [
                     {
-                        "activities": [
-                            {
-                                "name": "android.server.wm.cts\/android.server.wm.intent.Activities$NoHistoryActivity",
-                                "state": "RESUMED"
-                            },
-                            {
-                                "name": "android.server.wm.cts\/android.server.wm.intent.Activities$RegularActivity",
-                                "state": "STOPPED"
-                            }
-                        ]
+                        "name": "android.server.wm.cts/android.server.wm.intent.Activities$NoHistoryActivity",
+                        "state": "RESUMED"
+                    },
+                    {
+                        "name": "android.server.wm.cts/android.server.wm.intent.Activities$RegularActivity",
+                        "state": "STOPPED"
                     }
-                ],
-                "resumedActivity": "android.server.wm.cts\/android.server.wm.intent.Activities$NoHistoryActivity"
+                ]
             }
-        ]
+        ],
+        "resumedActivity": "android.server.wm.cts/android.server.wm.intent.Activities$NoHistoryActivity"
     }
-}
+}
\ No newline at end of file
diff --git a/tests/framework/base/windowmanager/intent_tests/resetTaskIfNeeded/reset-task_reparent_affinity_in.json b/tests/framework/base/windowmanager/intent_tests/resetTaskIfNeeded/reset-task_reparent_affinity_in.json
index a4d1b7f..9fa2d5a 100644
--- a/tests/framework/base/windowmanager/intent_tests/resetTaskIfNeeded/reset-task_reparent_affinity_in.json
+++ b/tests/framework/base/windowmanager/intent_tests/resetTaskIfNeeded/reset-task_reparent_affinity_in.json
@@ -24,57 +24,45 @@
         ]
     },
     "initialState": {
-        "stacks": [
+        "tasks": [
             {
-                "tasks": [
+                "activities": [
                     {
-                        "activities": [
-                            {
-                                "name": "android.server.wm.cts\/android.server.wm.intent.Activities$TaskAffinity1Activity",
-                                "state": "RESUMED"
-                            },
-                            {
-                                "name": "android.server.wm.cts\/android.server.wm.intent.Activities$RegularActivity",
-                                "state": "STOPPED"
-                            }
-                        ]
-                    }
-                ],
-                "resumedActivity": "android.server.wm.cts\/android.server.wm.intent.Activities$TaskAffinity1Activity"
-            }
-        ]
-    },
-    "endState": {
-        "stacks": [
-           {
-                "tasks": [
+                        "name": "android.server.wm.cts/android.server.wm.intent.Activities$TaskAffinity1Activity",
+                        "state": "RESUMED"
+                    },
                     {
-                        "activities": [
-                            {
-                                "name": "android.server.wm.cts\/android.server.wm.intent.Activities$TaskAffinity1Activity",
-                                "state": "RESUMED"
-                            },
-                            {
-                                "name": "android.server.wm.cts\/android.server.wm.intent.Activities$TaskAffinity1Activity2",
-                                "state": "INITIALIZING"
-                            }
-                        ]
-                    }
-                ],
-                "resumedActivity": "android.server.wm.cts\/android.server.wm.intent.Activities$TaskAffinity1Activity"
-            },
-            {
-                "tasks": [
-                    {
-                        "activities": [
-                            {
-                                "name": "android.server.wm.cts\/android.server.wm.intent.Activities$RegularActivity",
-                                "state": "STOPPED"
-                            }
-                        ]
+                        "name": "android.server.wm.cts/android.server.wm.intent.Activities$RegularActivity",
+                        "state": "STOPPED"
                     }
                 ]
             }
-         ]
+        ],
+        "resumedActivity": "android.server.wm.cts/android.server.wm.intent.Activities$TaskAffinity1Activity"
+    },
+    "endState": {
+        "tasks": [
+            {
+                "activities": [
+                    {
+                        "name": "android.server.wm.cts/android.server.wm.intent.Activities$TaskAffinity1Activity",
+                        "state": "RESUMED"
+                    },
+                    {
+                        "name": "android.server.wm.cts/android.server.wm.intent.Activities$TaskAffinity1Activity2",
+                        "state": "INITIALIZING"
+                    }
+                ]
+            },
+            {
+                "activities": [
+                    {
+                        "name": "android.server.wm.cts/android.server.wm.intent.Activities$RegularActivity",
+                        "state": "STOPPED"
+                    }
+                ]
+            }
+        ],
+        "resumedActivity": "android.server.wm.cts/android.server.wm.intent.Activities$TaskAffinity1Activity"
     }
-}
+}
\ No newline at end of file
diff --git a/tests/framework/base/windowmanager/intent_tests/resetTaskIfNeeded/reset-task_reparent_affinity_in_and_out.json b/tests/framework/base/windowmanager/intent_tests/resetTaskIfNeeded/reset-task_reparent_affinity_in_and_out.json
index 86e0f65..ec6cf77 100644
--- a/tests/framework/base/windowmanager/intent_tests/resetTaskIfNeeded/reset-task_reparent_affinity_in_and_out.json
+++ b/tests/framework/base/windowmanager/intent_tests/resetTaskIfNeeded/reset-task_reparent_affinity_in_and_out.json
@@ -36,85 +36,65 @@
         ]
     },
     "initialState": {
-        "stacks": [
+        "tasks": [
             {
-                "tasks": [
+                "activities": [
                     {
-                        "activities": [
-                            {
-                                "name": "android.server.wm.cts\/android.server.wm.intent.Activities$TaskAffinity1Activity2",
-                                "state": "RESUMED"
-                            },
-                            {
-                                "name": "android.server.wm.cts\/android.server.wm.intent.Activities$RegularActivity",
-                                "state": "STOPPED"
-                            }
-                        ]
+                        "name": "android.server.wm.cts/android.server.wm.intent.Activities$TaskAffinity1Activity2",
+                        "state": "RESUMED"
+                    },
+                    {
+                        "name": "android.server.wm.cts/android.server.wm.intent.Activities$RegularActivity",
+                        "state": "STOPPED"
                     }
-                ],
-                "resumedActivity": "android.server.wm.cts\/android.server.wm.intent.Activities$TaskAffinity1Activity2"
+                ]
             },
             {
-                "tasks": [
+                "activities": [
                     {
-                        "activities": [
-                            {
-                                "name": "android.server.wm.cts\/android.server.wm.intent.Activities$TaskAffinity2Activity",
-                                "state": "STOPPED"
-                            },
-                            {
-                                "name": "android.server.wm.cts\/android.server.wm.intent.Activities$TaskAffinity1Activity",
-                                "state": "STOPPED"
-                            }
-                        ]
+                        "name": "android.server.wm.cts/android.server.wm.intent.Activities$TaskAffinity2Activity",
+                        "state": "STOPPED"
+                    },
+                    {
+                        "name": "android.server.wm.cts/android.server.wm.intent.Activities$TaskAffinity1Activity",
+                        "state": "STOPPED"
                     }
                 ]
             }
-        ]
+        ],
+        "resumedActivity": "android.server.wm.cts/android.server.wm.intent.Activities$TaskAffinity1Activity2"
     },
     "endState": {
-        "stacks": [
-          {
-                "tasks": [
-                    {
-                        "activities": [
-                            {
-                                "name": "android.server.wm.cts\/android.server.wm.intent.Activities$TaskAffinity1Activity2",
-                                "state": "RESUMED"
-                            },
-                            {
-                                "name": "android.server.wm.cts\/android.server.wm.intent.Activities$TaskAffinity1Activity",
-                                "state": "STOPPED"
-                            }
-                        ]
-                    }
-                ],
-                "resumedActivity": "android.server.wm.cts\/android.server.wm.intent.Activities$TaskAffinity1Activity2"
-            },
+        "tasks": [
             {
-                "tasks": [
+                "activities": [
                     {
-                        "activities": [
-                            {
-                                "name": "android.server.wm.cts\/android.server.wm.intent.Activities$RegularActivity",
-                                "state": "STOPPED"
-                            }
-                        ]
+                        "name": "android.server.wm.cts/android.server.wm.intent.Activities$TaskAffinity1Activity2",
+                        "state": "RESUMED"
+                    },
+                    {
+                        "name": "android.server.wm.cts/android.server.wm.intent.Activities$TaskAffinity1Activity",
+                        "state": "STOPPED"
                     }
                 ]
             },
             {
-                "tasks": [
+                "activities": [
                     {
-                        "activities": [
-                            {
-                                "name": "android.server.wm.cts\/android.server.wm.intent.Activities$TaskAffinity2Activity",
-                                "state": "STOPPED"
-                            }
-                        ]
+                        "name": "android.server.wm.cts/android.server.wm.intent.Activities$RegularActivity",
+                        "state": "STOPPED"
+                    }
+                ]
+            },
+            {
+                "activities": [
+                    {
+                        "name": "android.server.wm.cts/android.server.wm.intent.Activities$TaskAffinity2Activity",
+                        "state": "STOPPED"
                     }
                 ]
             }
-         ]
+        ],
+        "resumedActivity": "android.server.wm.cts/android.server.wm.intent.Activities$TaskAffinity1Activity2"
     }
-}
+}
\ No newline at end of file
diff --git a/tests/framework/base/windowmanager/intent_tests/resetTaskIfNeeded/reset-task_with_new-task.json b/tests/framework/base/windowmanager/intent_tests/resetTaskIfNeeded/reset-task_with_new-task.json
index c059027..89e8664 100644
--- a/tests/framework/base/windowmanager/intent_tests/resetTaskIfNeeded/reset-task_with_new-task.json
+++ b/tests/framework/base/windowmanager/intent_tests/resetTaskIfNeeded/reset-task_with_new-task.json
@@ -18,37 +18,29 @@
         ]
     },
     "initialState": {
-        "stacks": [
+        "tasks": [
             {
-                "tasks": [
+                "activities": [
                     {
-                        "activities": [
-                            {
-                                "name": "android.server.wm.cts\/android.server.wm.intent.Activities$RegularActivity",
-                                "state": "RESUMED"
-                            }
-                        ]
+                        "name": "android.server.wm.cts/android.server.wm.intent.Activities$RegularActivity",
+                        "state": "RESUMED"
                     }
-                ],
-                "resumedActivity": "android.server.wm.cts\/android.server.wm.intent.Activities$RegularActivity"
+                ]
             }
-        ]
+        ],
+        "resumedActivity": "android.server.wm.cts/android.server.wm.intent.Activities$RegularActivity"
     },
     "endState": {
-        "stacks": [
+        "tasks": [
             {
-                "tasks": [
+                "activities": [
                     {
-                        "activities": [
-                            {
-                                "name": "android.server.wm.cts\/android.server.wm.intent.Activities$RegularActivity",
-                                "state": "RESUMED"
-                            }
-                        ]
+                        "name": "android.server.wm.cts/android.server.wm.intent.Activities$RegularActivity",
+                        "state": "RESUMED"
                     }
-                ],
-                "resumedActivity": "android.server.wm.cts\/android.server.wm.intent.Activities$RegularActivity"
+                ]
             }
-        ]
+        ],
+        "resumedActivity": "android.server.wm.cts/android.server.wm.intent.Activities$RegularActivity"
     }
-}
+}
\ No newline at end of file
diff --git a/tests/framework/base/windowmanager/intent_tests/resetTaskIfNeeded/reset-task_with_new-task_new_document.json b/tests/framework/base/windowmanager/intent_tests/resetTaskIfNeeded/reset-task_with_new-task_new_document.json
index 27931ba..171348b 100644
--- a/tests/framework/base/windowmanager/intent_tests/resetTaskIfNeeded/reset-task_with_new-task_new_document.json
+++ b/tests/framework/base/windowmanager/intent_tests/resetTaskIfNeeded/reset-task_with_new-task_new_document.json
@@ -18,49 +18,37 @@
         ]
     },
     "initialState": {
-        "stacks": [
+        "tasks": [
             {
-                "tasks": [
+                "activities": [
                     {
-                        "activities": [
-                            {
-                                "name": "android.server.wm.cts\/android.server.wm.intent.Activities$RegularActivity",
-                                "state": "RESUMED"
-                            }
-                        ]
-                    }
-                ],
-                "resumedActivity": "android.server.wm.cts\/android.server.wm.intent.Activities$RegularActivity"
-            }
-        ]
-    },
-    "endState": {
-        "stacks": [
-            {
-                "tasks": [
-                    {
-                        "activities": [
-                            {
-                                "name": "android.server.wm.cts\/android.server.wm.intent.Activities$NoHistoryActivity",
-                                "state": "RESUMED"
-                            }
-                        ]
-                    }
-                ],
-                "resumedActivity": "android.server.wm.cts\/android.server.wm.intent.Activities$NoHistoryActivity"
-            },
-            {
-                "tasks": [
-                    {
-                        "activities": [
-                            {
-                                "name": "android.server.wm.cts\/android.server.wm.intent.Activities$RegularActivity",
-                                "state": "STOPPED"
-                            }
-                        ]
+                        "name": "android.server.wm.cts/android.server.wm.intent.Activities$RegularActivity",
+                        "state": "RESUMED"
                     }
                 ]
             }
-        ]
+        ],
+        "resumedActivity": "android.server.wm.cts/android.server.wm.intent.Activities$RegularActivity"
+    },
+    "endState": {
+        "tasks": [
+            {
+                "activities": [
+                    {
+                        "name": "android.server.wm.cts/android.server.wm.intent.Activities$NoHistoryActivity",
+                        "state": "RESUMED"
+                    }
+                ]
+            },
+            {
+                "activities": [
+                    {
+                        "name": "android.server.wm.cts/android.server.wm.intent.Activities$RegularActivity",
+                        "state": "STOPPED"
+                    }
+                ]
+            }
+        ],
+        "resumedActivity": "android.server.wm.cts/android.server.wm.intent.Activities$NoHistoryActivity"
     }
-}
+}
\ No newline at end of file
diff --git a/tests/framework/base/windowmanager/intent_tests/resetTaskIfNeeded/test-1.json b/tests/framework/base/windowmanager/intent_tests/resetTaskIfNeeded/test-1.json
index 2cf1652..faad3cf 100644
--- a/tests/framework/base/windowmanager/intent_tests/resetTaskIfNeeded/test-1.json
+++ b/tests/framework/base/windowmanager/intent_tests/resetTaskIfNeeded/test-1.json
@@ -24,53 +24,41 @@
         ]
     },
     "initialState": {
-        "stacks": [
+        "tasks": [
             {
-                "tasks": [
+                "activities": [
                     {
-                        "activities": [
-                            {
-                                "name": "android.server.wm.cts\/android.server.wm.intent.Activities$TaskAffinity1Activity",
-                                "state": "RESUMED"
-                            },
-                            {
-                                "name": "android.server.wm.cts\/android.server.wm.intent.Activities$RegularActivity",
-                                "state": "STOPPED"
-                            }
-                        ]
-                    }
-                ],
-                "resumedActivity": "android.server.wm.cts\/android.server.wm.intent.Activities$TaskAffinity1Activity"
-            }
-        ]
-    },
-    "endState": {
-        "stacks": [
-            {
-                "tasks": [
+                        "name": "android.server.wm.cts/android.server.wm.intent.Activities$TaskAffinity1Activity",
+                        "state": "RESUMED"
+                    },
                     {
-                        "activities": [
-                            {
-                                "name": "android.server.wm.cts\/android.server.wm.intent.Activities$RegularActivity",
-                                "state": "RESUMED"
-                            }
-                        ]
-                    }
-                ],
-                "resumedActivity": "android.server.wm.cts\/android.server.wm.intent.Activities$RegularActivity"
-            },
-            {
-                "tasks": [
-                    {
-                        "activities": [
-                            {
-                                "name": "android.server.wm.cts\/android.server.wm.intent.Activities$TaskAffinity1Activity",
-                                "state": "STOPPED"
-                            }
-                        ]
+                        "name": "android.server.wm.cts/android.server.wm.intent.Activities$RegularActivity",
+                        "state": "STOPPED"
                     }
                 ]
             }
-        ]
+        ],
+        "resumedActivity": "android.server.wm.cts/android.server.wm.intent.Activities$TaskAffinity1Activity"
+    },
+    "endState": {
+        "tasks": [
+            {
+                "activities": [
+                    {
+                        "name": "android.server.wm.cts/android.server.wm.intent.Activities$RegularActivity",
+                        "state": "RESUMED"
+                    }
+                ]
+            },
+            {
+                "activities": [
+                    {
+                        "name": "android.server.wm.cts/android.server.wm.intent.Activities$TaskAffinity1Activity",
+                        "state": "STOPPED"
+                    }
+                ]
+            }
+        ],
+        "resumedActivity": "android.server.wm.cts/android.server.wm.intent.Activities$RegularActivity"
     }
-}
+}
\ No newline at end of file
diff --git a/tests/framework/base/windowmanager/intent_tests/resetTaskIfNeeded/test-2.json b/tests/framework/base/windowmanager/intent_tests/resetTaskIfNeeded/test-2.json
index fc3634c..0f1bfca 100644
--- a/tests/framework/base/windowmanager/intent_tests/resetTaskIfNeeded/test-2.json
+++ b/tests/framework/base/windowmanager/intent_tests/resetTaskIfNeeded/test-2.json
@@ -24,45 +24,37 @@
         ]
     },
     "initialState": {
-        "stacks": [
+        "tasks": [
             {
-                "tasks": [
+                "activities": [
                     {
-                        "activities": [
-                            {
-                                "name": "android.server.wm.cts\/android.server.wm.intent.Activities$TaskAffinity1Activity",
-                                "state": "RESUMED"
-                            },
-                            {
-                                "name": "android.server.wm.cts\/android.server.wm.intent.Activities$RegularActivity",
-                                "state": "STOPPED"
-                            }
-                        ]
+                        "name": "android.server.wm.cts/android.server.wm.intent.Activities$TaskAffinity1Activity",
+                        "state": "RESUMED"
+                    },
+                    {
+                        "name": "android.server.wm.cts/android.server.wm.intent.Activities$RegularActivity",
+                        "state": "STOPPED"
                     }
-                ],
-                "resumedActivity": "android.server.wm.cts\/android.server.wm.intent.Activities$TaskAffinity1Activity"
+                ]
             }
-        ]
+        ],
+        "resumedActivity": "android.server.wm.cts/android.server.wm.intent.Activities$TaskAffinity1Activity"
     },
     "endState": {
-        "stacks": [
+        "tasks": [
             {
-                "tasks": [
+                "activities": [
                     {
-                        "activities": [
-                            {
-                                "name": "android.server.wm.cts\/android.server.wm.intent.Activities$TaskAffinity1Activity",
-                                "state": "RESUMED"
-                            },
-                            {
-                                "name": "android.server.wm.cts\/android.server.wm.intent.Activities$RegularActivity",
-                                "state": "STOPPED"
-                            }
-                        ]
+                        "name": "android.server.wm.cts/android.server.wm.intent.Activities$TaskAffinity1Activity",
+                        "state": "RESUMED"
+                    },
+                    {
+                        "name": "android.server.wm.cts/android.server.wm.intent.Activities$RegularActivity",
+                        "state": "STOPPED"
                     }
-                ],
-                "resumedActivity": "android.server.wm.cts\/android.server.wm.intent.Activities$TaskAffinity1Activity"
+                ]
             }
-        ]
+        ],
+        "resumedActivity": "android.server.wm.cts/android.server.wm.intent.Activities$TaskAffinity1Activity"
     }
-}
+}
\ No newline at end of file
diff --git a/tests/framework/base/windowmanager/intent_tests/resetTaskIfNeeded/test-3.json b/tests/framework/base/windowmanager/intent_tests/resetTaskIfNeeded/test-3.json
index c89cdd3..3acfbee 100644
--- a/tests/framework/base/windowmanager/intent_tests/resetTaskIfNeeded/test-3.json
+++ b/tests/framework/base/windowmanager/intent_tests/resetTaskIfNeeded/test-3.json
@@ -30,77 +30,57 @@
         ]
     },
     "initialState": {
-        "stacks": [
+        "tasks": [
             {
-                "tasks": [
+                "activities": [
                     {
-                        "activities": [
-                            {
-                                "name": "android.server.wm.cts\/android.server.wm.intent.Activities$TaskAffinity1Activity",
-                                "state": "RESUMED"
-                            }
-                        ]
+                        "name": "android.server.wm.cts/android.server.wm.intent.Activities$TaskAffinity1Activity",
+                        "state": "RESUMED"
                     }
-                ],
-                "resumedActivity": "android.server.wm.cts\/android.server.wm.intent.Activities$TaskAffinity1Activity"
+                ]
             },
             {
-                "tasks": [
+                "activities": [
                     {
-                        "activities": [
-                            {
-                                "name": "android.server.wm.cts\/android.server.wm.intent.Activities$TaskAffinity1Activity",
-                                "state": "STOPPED"
-                            },
-                            {
-                                "name": "android.server.wm.cts\/android.server.wm.intent.Activities$RegularActivity",
-                                "state": "STOPPED"
-                            }
-                        ]
+                        "name": "android.server.wm.cts/android.server.wm.intent.Activities$TaskAffinity1Activity",
+                        "state": "STOPPED"
+                    },
+                    {
+                        "name": "android.server.wm.cts/android.server.wm.intent.Activities$RegularActivity",
+                        "state": "STOPPED"
                     }
                 ]
             }
-        ]
+        ],
+        "resumedActivity": "android.server.wm.cts/android.server.wm.intent.Activities$TaskAffinity1Activity"
     },
     "endState": {
-        "stacks": [
+        "tasks": [
             {
-                "tasks": [
+                "activities": [
                     {
-                        "activities": [
-                            {
-                                "name": "android.server.wm.cts\/android.server.wm.intent.Activities$RegularActivity",
-                                "state": "RESUMED"
-                            }
-                        ]
-                    }
-                ],
-                "resumedActivity": "android.server.wm.cts\/android.server.wm.intent.Activities$RegularActivity"
-            },
-            {
-                "tasks": [
-                    {
-                        "activities": [
-                            {
-                                "name": "android.server.wm.cts\/android.server.wm.intent.Activities$TaskAffinity1Activity",
-                                "state": "STOPPED"
-                            }
-                        ]
+                        "name": "android.server.wm.cts/android.server.wm.intent.Activities$RegularActivity",
+                        "state": "RESUMED"
                     }
                 ]
             },
             {
-                "tasks": [
+                "activities": [
                     {
-                        "activities": [
-                            {
-                                "name": "android.server.wm.cts\/android.server.wm.intent.Activities$TaskAffinity1Activity",
-                                "state": "STOPPED"
-                            }
-                        ]
+                        "name": "android.server.wm.cts/android.server.wm.intent.Activities$TaskAffinity1Activity",
+                        "state": "STOPPED"
+                    }
+                ]
+            },
+            {
+                "activities": [
+                    {
+                        "name": "android.server.wm.cts/android.server.wm.intent.Activities$TaskAffinity1Activity",
+                        "state": "STOPPED"
                     }
                 ]
             }
-        ]
+        ],
+        "resumedActivity": "android.server.wm.cts/android.server.wm.intent.Activities$RegularActivity"
     }
-}
+}
\ No newline at end of file
diff --git a/tests/framework/base/windowmanager/intent_tests/resetTaskIfNeeded/test-4.json b/tests/framework/base/windowmanager/intent_tests/resetTaskIfNeeded/test-4.json
index d8f3f7f..a3b9d97 100644
--- a/tests/framework/base/windowmanager/intent_tests/resetTaskIfNeeded/test-4.json
+++ b/tests/framework/base/windowmanager/intent_tests/resetTaskIfNeeded/test-4.json
@@ -30,61 +30,49 @@
         ]
     },
     "initialState": {
-        "stacks": [
+        "tasks": [
             {
-                "tasks": [
+                "activities": [
                     {
-                        "activities": [
-                            {
-                                "name": "android.server.wm.cts\/android.server.wm.intent.Activities$TaskAffinity1Activity2",
-                                "state": "RESUMED"
-                            },
-                            {
-                                "name": "android.server.wm.cts\/android.server.wm.intent.Activities$TaskAffinity1Activity",
-                                "state": "STOPPED"
-                            },
-                            {
-                                "name": "android.server.wm.cts\/android.server.wm.intent.Activities$RegularActivity",
-                                "state": "STOPPED"
-                            }
-                        ]
-                    }
-                ],
-                "resumedActivity": "android.server.wm.cts\/android.server.wm.intent.Activities$TaskAffinity1Activity2"
-            }
-        ]
-    },
-    "endState": {
-        "stacks": [
-            {
-                "tasks": [
+                        "name": "android.server.wm.cts/android.server.wm.intent.Activities$TaskAffinity1Activity2",
+                        "state": "RESUMED"
+                    },
                     {
-                        "activities": [
-                            {
-                                "name": "android.server.wm.cts\/android.server.wm.intent.Activities$RegularActivity",
-                                "state": "RESUMED"
-                            }
-                        ]
-                    }
-                ],
-                "resumedActivity": "android.server.wm.cts\/android.server.wm.intent.Activities$RegularActivity"
-            },
-            {
-                "tasks": [
+                        "name": "android.server.wm.cts/android.server.wm.intent.Activities$TaskAffinity1Activity",
+                        "state": "STOPPED"
+                    },
                     {
-                        "activities": [
-                            {
-                                "name": "android.server.wm.cts\/android.server.wm.intent.Activities$TaskAffinity1Activity2",
-                                "state": "STOPPED"
-                            },
-                            {
-                                "name": "android.server.wm.cts\/android.server.wm.intent.Activities$TaskAffinity1Activity",
-                                "state": "STOPPED"
-                            }
-                        ]
+                        "name": "android.server.wm.cts/android.server.wm.intent.Activities$RegularActivity",
+                        "state": "STOPPED"
                     }
                 ]
             }
-        ]
+        ],
+        "resumedActivity": "android.server.wm.cts/android.server.wm.intent.Activities$TaskAffinity1Activity2"
+    },
+    "endState": {
+        "tasks": [
+            {
+                "activities": [
+                    {
+                        "name": "android.server.wm.cts/android.server.wm.intent.Activities$RegularActivity",
+                        "state": "RESUMED"
+                    }
+                ]
+            },
+            {
+                "activities": [
+                    {
+                        "name": "android.server.wm.cts/android.server.wm.intent.Activities$TaskAffinity1Activity2",
+                        "state": "STOPPED"
+                    },
+                    {
+                        "name": "android.server.wm.cts/android.server.wm.intent.Activities$TaskAffinity1Activity",
+                        "state": "STOPPED"
+                    }
+                ]
+            }
+        ],
+        "resumedActivity": "android.server.wm.cts/android.server.wm.intent.Activities$RegularActivity"
     }
-}
+}
\ No newline at end of file
diff --git a/tests/framework/base/windowmanager/src/android/server/wm/AlertWindowsTests.java b/tests/framework/base/windowmanager/src/android/server/wm/AlertWindowsTests.java
index 20f2f42..7c50ab2 100644
--- a/tests/framework/base/windowmanager/src/android/server/wm/AlertWindowsTests.java
+++ b/tests/framework/base/windowmanager/src/android/server/wm/AlertWindowsTests.java
@@ -133,7 +133,7 @@
 
     private boolean allWindowsHidden(List<WindowManagerState.WindowState> windows) {
         for (WindowManagerState.WindowState ws : windows) {
-            if (ws.isShown()) {
+            if (ws.isSurfaceShown()) {
                 return false;
             }
         }
diff --git a/tests/framework/base/windowmanager/src/android/server/wm/AnrTests.java b/tests/framework/base/windowmanager/src/android/server/wm/AnrTests.java
index 5045810..608a760 100644
--- a/tests/framework/base/windowmanager/src/android/server/wm/AnrTests.java
+++ b/tests/framework/base/windowmanager/src/android/server/wm/AnrTests.java
@@ -16,6 +16,7 @@
 
 package android.server.wm;
 
+import static android.server.wm.app.Components.HOST_ACTIVITY;
 import static android.server.wm.app.Components.UNRESPONSIVE_ACTIVITY;
 import static android.server.wm.app.Components.UnresponsiveActivity;
 import static android.server.wm.app.Components.UnresponsiveActivity.EXTRA_DELAY_UI_THREAD_MS;
@@ -26,8 +27,10 @@
 
 import static org.junit.Assert.fail;
 
+import android.content.ComponentName;
 import android.os.SystemClock;
 import android.platform.test.annotations.Presubmit;
+import android.server.wm.app.Components.RenderService;
 import android.provider.Settings;
 import android.server.wm.settings.SettingsSession;
 import android.support.test.uiautomator.By;
@@ -75,11 +78,13 @@
     public void teardown() {
         mHideDialogSetting.close();
         stopTestPackage(UNRESPONSIVE_ACTIVITY.getPackageName());
+        stopTestPackage(HOST_ACTIVITY.getPackageName());
     }
 
     @Test
     public void slowOnCreateWithKeyEventTriggersAnr() {
-        startUnresponsiveActivity(EXTRA_ON_CREATE_DELAY_MS, false /* waitForCompletion */);
+        startUnresponsiveActivity(EXTRA_ON_CREATE_DELAY_MS, false /* waitForCompletion */,
+                UNRESPONSIVE_ACTIVITY);
         // wait for app to be focused
         mWmState.waitAndAssertAppFocus(UNRESPONSIVE_ACTIVITY.getPackageName(),
                 2000 /* waitTime_ms */);
@@ -93,7 +98,8 @@
 
     @Test
     public void slowUiThreadWithKeyEventTriggersAnr() {
-        startUnresponsiveActivity(EXTRA_DELAY_UI_THREAD_MS, true /* waitForCompletion */);
+        startUnresponsiveActivity(EXTRA_DELAY_UI_THREAD_MS, true /* waitForCompletion */,
+                UNRESPONSIVE_ACTIVITY);
         injectKey(KeyEvent.KEYCODE_BACK, false /* longpress */, false /* sync */);
         clickCloseAppOnAnrDialog();
         assertEventLogsContainsAnr(UnresponsiveActivity.PROCESS_NAME);
@@ -101,7 +107,8 @@
 
     @Test
     public void slowOnKeyEventHandleTriggersAnr() {
-        startUnresponsiveActivity(EXTRA_ON_KEYDOWN_DELAY_MS, true /* waitForCompletion */);
+        startUnresponsiveActivity(EXTRA_ON_KEYDOWN_DELAY_MS, true /* waitForCompletion */,
+                UNRESPONSIVE_ACTIVITY);
         injectKey(KeyEvent.KEYCODE_BACK, false /* longpress */, false /* sync */);
         clickCloseAppOnAnrDialog();
         assertEventLogsContainsAnr(UnresponsiveActivity.PROCESS_NAME);
@@ -109,7 +116,8 @@
 
     @Test
     public void slowOnTouchEventHandleTriggersAnr() {
-        startUnresponsiveActivity(EXTRA_ON_MOTIONEVENT_DELAY_MS, true /* waitForCompletion */);
+        startUnresponsiveActivity(EXTRA_ON_MOTIONEVENT_DELAY_MS, true /* waitForCompletion */,
+                UNRESPONSIVE_ACTIVITY);
 
         // TODO(b/143566069) investigate why we need multiple taps on display to trigger anr.
         mWmState.computeState();
@@ -121,6 +129,24 @@
         assertEventLogsContainsAnr(UnresponsiveActivity.PROCESS_NAME);
     }
 
+    /**
+     * Verify embedded windows can trigger ANR and the verify embedded app is blamed.
+     */
+    @Test
+    public void embeddedWindowTriggersAnr() {
+        startUnresponsiveActivity(EXTRA_ON_MOTIONEVENT_DELAY_MS, true  /* waitForCompletion */,
+                HOST_ACTIVITY);
+
+        // TODO(b/143566069) investigate why we need multiple taps on display to trigger anr.
+        mWmState.computeState();
+        tapOnDisplayCenterAsync(DEFAULT_DISPLAY);
+        SystemClock.sleep(1000);
+        tapOnDisplayCenterAsync(DEFAULT_DISPLAY);
+
+        clickCloseAppOnAnrDialog();
+        assertEventLogsContainsAnr(RenderService.PROCESS_NAME);
+    }
+
     private void assertEventLogsContainsAnr(String processName) {
         final List<EventLog.Event> events = getEventLogsForComponents(mLogSeparator,
                 android.util.EventLog.getTagCode("am_anr"));
@@ -147,9 +173,10 @@
         fail("Could not find anr dialog");
     }
 
-    private void startUnresponsiveActivity(String delayTypeExtra, boolean waitForCompletion) {
+    private void startUnresponsiveActivity(String delayTypeExtra, boolean waitForCompletion,
+            ComponentName activity) {
         String flags = waitForCompletion ? " -W -n " : " -n ";
-        String startCmd = "am start" + flags + UNRESPONSIVE_ACTIVITY.flattenToString() +
+        String startCmd = "am start" + flags + activity.flattenToString() +
                 " --ei " + delayTypeExtra + " 30000";
         executeShellCommand(startCmd);
     }
diff --git a/tests/framework/base/windowmanager/src/android/server/wm/KeyguardTests.java b/tests/framework/base/windowmanager/src/android/server/wm/KeyguardTests.java
index d3584b2..bc0c65d 100755
--- a/tests/framework/base/windowmanager/src/android/server/wm/KeyguardTests.java
+++ b/tests/framework/base/windowmanager/src/android/server/wm/KeyguardTests.java
@@ -137,11 +137,11 @@
         mWmState.computeState(SHOW_WHEN_LOCKED_WITH_DIALOG_ACTIVITY);
         mWmState.assertVisibility(SHOW_WHEN_LOCKED_WITH_DIALOG_ACTIVITY, true);
         lockScreenSession.gotoKeyguard(SHOW_WHEN_LOCKED_WITH_DIALOG_ACTIVITY);
-        mWmState.waitFor((wmState) -> wmState.allWindowsVisible(
+        mWmState.waitFor((wmState) -> wmState.allWindowSurfacesShown(
                 getWindowName(SHOW_WHEN_LOCKED_WITH_DIALOG_ACTIVITY)),
                 "Wait for all windows visible for " + SHOW_WHEN_LOCKED_WITH_DIALOG_ACTIVITY);
         mWmState.assertVisibility(SHOW_WHEN_LOCKED_WITH_DIALOG_ACTIVITY, true);
-        assertTrue(mWmState.allWindowsVisible(
+        assertTrue(mWmState.allWindowSurfacesShown(
                 getWindowName(SHOW_WHEN_LOCKED_WITH_DIALOG_ACTIVITY)));
         mWmState.assertKeyguardShowingAndOccluded();
     }
@@ -548,7 +548,7 @@
         WindowState wallpaper =
                 mWmState.findFirstWindowWithType(TYPE_WALLPAPER);
         assertNotNull(wallpaper);
-        assertTrue(wallpaper.isShown());
+        assertTrue(wallpaper.isSurfaceShown());
     }
 
     @Test
diff --git a/tests/framework/base/windowmanager/src/android/server/wm/MinimalPostProcessingTests.java b/tests/framework/base/windowmanager/src/android/server/wm/MinimalPostProcessingTests.java
index cc49cf4..1c9f174 100644
--- a/tests/framework/base/windowmanager/src/android/server/wm/MinimalPostProcessingTests.java
+++ b/tests/framework/base/windowmanager/src/android/server/wm/MinimalPostProcessingTests.java
@@ -35,7 +35,6 @@
 import org.junit.Test;
 
 @Presubmit
-@FlakyTest(detail = "Promote once confirmed non-flaky")
 public class MinimalPostProcessingTests extends ActivityManagerTestBase {
     private static final boolean PREFER_MPP = true;
     private static final boolean NOT_PREFER_MPP = false;
diff --git a/tests/framework/base/windowmanager/src/android/server/wm/MultiDisplayActivityLaunchTests.java b/tests/framework/base/windowmanager/src/android/server/wm/MultiDisplayActivityLaunchTests.java
index de0372f..f95b12a 100644
--- a/tests/framework/base/windowmanager/src/android/server/wm/MultiDisplayActivityLaunchTests.java
+++ b/tests/framework/base/windowmanager/src/android/server/wm/MultiDisplayActivityLaunchTests.java
@@ -848,7 +848,6 @@
         getPendingIntentActivity(TEST_ACTIVITY).send(mContext, resultCode, null /* intent */,
                 null /* onFinished */, null /* handler */, null /* requiredPermission */,
                 options.toBundle());
-        waitAndAssertActivityState(TOP_ACTIVITY, STATE_STOPPED, "Activity should be stopped");
         waitAndAssertTopResumedActivity(TEST_ACTIVITY, displayContent.mId,
                 "Activity launched on secondary display and on top");
     }
diff --git a/tests/framework/base/windowmanager/src/android/server/wm/MultiDisplayLockedKeyguardTests.java b/tests/framework/base/windowmanager/src/android/server/wm/MultiDisplayLockedKeyguardTests.java
index 7f5f871..cf1b454 100644
--- a/tests/framework/base/windowmanager/src/android/server/wm/MultiDisplayLockedKeyguardTests.java
+++ b/tests/framework/base/windowmanager/src/android/server/wm/MultiDisplayLockedKeyguardTests.java
@@ -135,7 +135,6 @@
         mWmState.assertVisibility(DISMISS_KEYGUARD_ACTIVITY, true);
     }
 
-    @FlakyTest(bugId = 141674516)
     @Test
     public void testDismissKeyguard_whileOccluded_secondaryDisplay() {
         final LockScreenSession lockScreenSession =
diff --git a/tests/framework/base/windowmanager/src/android/server/wm/MultiDisplayPolicyTests.java b/tests/framework/base/windowmanager/src/android/server/wm/MultiDisplayPolicyTests.java
index da874ab..f1d5651 100644
--- a/tests/framework/base/windowmanager/src/android/server/wm/MultiDisplayPolicyTests.java
+++ b/tests/framework/base/windowmanager/src/android/server/wm/MultiDisplayPolicyTests.java
@@ -699,7 +699,7 @@
         assertTrue("Toast window must be shown", mWmState.waitForWithAmState(
                 state -> state.containsWindow(TOAST_NAME), "toast window to show"));
         assertTrue("Toast window must be visible",
-                mWmState.isWindowVisible(TOAST_NAME));
+                mWmState.isWindowSurfaceShown(TOAST_NAME));
     }
 
     /**
diff --git a/tests/framework/base/windowmanager/src/android/server/wm/MultiDisplaySystemDecorationTests.java b/tests/framework/base/windowmanager/src/android/server/wm/MultiDisplaySystemDecorationTests.java
index 5121a39..5920334 100644
--- a/tests/framework/base/windowmanager/src/android/server/wm/MultiDisplaySystemDecorationTests.java
+++ b/tests/framework/base/windowmanager/src/android/server/wm/MultiDisplaySystemDecorationTests.java
@@ -66,13 +66,10 @@
 import android.widget.EditText;
 import android.widget.LinearLayout;
 
-import androidx.test.filters.FlakyTest;
-
 import com.android.compatibility.common.util.ImeAwareEditText;
 import com.android.compatibility.common.util.SystemUtil;
 import com.android.compatibility.common.util.TestUtils;
 import com.android.cts.mockime.ImeCommand;
-import com.android.cts.mockime.ImeEvent;
 import com.android.cts.mockime.ImeEventStream;
 import com.android.cts.mockime.MockImeSession;
 
@@ -296,19 +293,9 @@
     public void testLaunchSingleHomeActivityOnDisplayWithDecorations() {
         createManagedHomeActivitySession(SINGLE_HOME_ACTIVITY);
 
-        // Create new virtual display with system decoration support.
-        final DisplayContent newDisplay = createManagedExternalDisplaySession()
-                .setShowSystemDecorations(true)
-                .createVirtualDisplay();
-
         // If default home doesn't support multi-instance, default secondary home activity
         // should be automatically launched on the new display.
-        waitAndAssertActivityStateOnDisplay(getDefaultSecondaryHomeComponent(), STATE_RESUMED,
-                newDisplay.mId, "Activity launched on secondary display must be resumed");
-
-        tapOnDisplayCenter(newDisplay.mId);
-        assertEquals("Top activity must be home type", ACTIVITY_TYPE_HOME,
-                mWmState.getFrontStackActivityType(newDisplay.mId));
+        assertSecondaryHomeResumedOnNewDisplay(getDefaultSecondaryHomeComponent());
     }
 
     /**
@@ -319,19 +306,9 @@
     public void testLaunchSingleSecondaryHomeActivityOnDisplayWithDecorations() {
         createManagedHomeActivitySession(SINGLE_SECONDARY_HOME_ACTIVITY);
 
-        // Create new virtual display with system decoration support.
-        final DisplayContent newDisplay = createManagedExternalDisplaySession()
-                .setShowSystemDecorations(true)
-                .createVirtualDisplay();
-
         // If provided secondary home doesn't support multi-instance, default secondary home
         // activity should be automatically launched on the new display.
-        waitAndAssertActivityStateOnDisplay(getDefaultSecondaryHomeComponent(), STATE_RESUMED,
-                newDisplay.mId, "Activity launched on secondary display must be resumed");
-
-        tapOnDisplayCenter(newDisplay.mId);
-        assertEquals("Top activity must be home type", ACTIVITY_TYPE_HOME,
-                mWmState.getFrontStackActivityType(newDisplay.mId));
+        assertSecondaryHomeResumedOnNewDisplay(getDefaultSecondaryHomeComponent());
     }
 
     /**
@@ -341,21 +318,10 @@
     @Test
     public void testLaunchHomeActivityOnDisplayWithDecorations() {
         createManagedHomeActivitySession(HOME_ACTIVITY);
-        final VirtualDisplaySession virtualDisplaySession = createManagedVirtualDisplaySession();
-
-        // Create new virtual display with system decoration support.
-        final DisplayContent newDisplay = createManagedExternalDisplaySession()
-                .setShowSystemDecorations(true)
-                .createVirtualDisplay();
 
         // If default home doesn't have SECONDARY_HOME category, default secondary home
         // activity should be automatically launched on the new display.
-        waitAndAssertActivityStateOnDisplay(getDefaultSecondaryHomeComponent(), STATE_RESUMED,
-                newDisplay.mId, "Activity launched on secondary display must be resumed");
-
-        tapOnDisplayCenter(newDisplay.mId);
-        assertEquals("Top activity must be home type", ACTIVITY_TYPE_HOME,
-                mWmState.getFrontStackActivityType(newDisplay.mId));
+        assertSecondaryHomeResumedOnNewDisplay(getDefaultSecondaryHomeComponent());
     }
 
     /**
@@ -365,15 +331,18 @@
     @Test
     public void testLaunchSecondaryHomeActivityOnDisplayWithDecorations() {
         createManagedHomeActivitySession(SECONDARY_HOME_ACTIVITY);
-        final VirtualDisplaySession virtualDisplaySession = createManagedVirtualDisplaySession();
 
+        // Provided secondary home activity should be automatically launched on the new display.
+        assertSecondaryHomeResumedOnNewDisplay(SECONDARY_HOME_ACTIVITY);
+    }
+
+    private void assertSecondaryHomeResumedOnNewDisplay(ComponentName homeComponentName) {
         // Create new virtual display with system decoration support.
         final DisplayContent newDisplay = createManagedExternalDisplaySession()
                 .setShowSystemDecorations(true)
                 .createVirtualDisplay();
 
-        // Provided secondary home activity should be automatically launched on the new display.
-        waitAndAssertActivityStateOnDisplay(SECONDARY_HOME_ACTIVITY, STATE_RESUMED,
+        waitAndAssertActivityStateOnDisplay(homeComponentName, STATE_RESUMED,
                 newDisplay.mId, "Activity launched on secondary display must be resumed");
 
         tapOnDisplayCenter(newDisplay.mId);
diff --git a/tests/framework/base/windowmanager/src/android/server/wm/PinnedStackTests.java b/tests/framework/base/windowmanager/src/android/server/wm/PinnedStackTests.java
index 0b44b01..1f24b6b 100644
--- a/tests/framework/base/windowmanager/src/android/server/wm/PinnedStackTests.java
+++ b/tests/framework/base/windowmanager/src/android/server/wm/PinnedStackTests.java
@@ -36,6 +36,7 @@
 import static android.server.wm.app.Components.NON_RESIZEABLE_ACTIVITY;
 import static android.server.wm.app.Components.PIP_ACTIVITY;
 import static android.server.wm.app.Components.PIP_ACTIVITY2;
+import static android.server.wm.app.Components.PIP_ACTIVITY_WITH_MINIMAL_SIZE;
 import static android.server.wm.app.Components.PIP_ACTIVITY_WITH_SAME_AFFINITY;
 import static android.server.wm.app.Components.PIP_ON_STOP_ACTIVITY;
 import static android.server.wm.app.Components.PipActivity.ACTION_ENTER_PIP;
@@ -81,6 +82,8 @@
 
 import android.content.ComponentName;
 import android.content.Context;
+import android.content.pm.ActivityInfo;
+import android.content.pm.PackageManager;
 import android.content.res.Configuration;
 import android.database.ContentObserver;
 import android.graphics.Rect;
@@ -120,9 +123,7 @@
     private static final String TAG = PinnedStackTests.class.getSimpleName();
 
     private static final String APP_OPS_OP_ENTER_PICTURE_IN_PICTURE = "PICTURE_IN_PICTURE";
-    private static final int APP_OPS_MODE_ALLOWED = 0;
     private static final int APP_OPS_MODE_IGNORED = 1;
-    private static final int APP_OPS_MODE_ERRORED = 2;
 
     private static final int ROTATION_0 = 0;
     private static final int ROTATION_90 = 1;
@@ -247,6 +248,31 @@
         assertPinnedStackActivityIsInDisplayBounds(PIP_ACTIVITY);
     }
 
+    // TODO: launch/size pip to a size smaller than limitation and verify the minWidth/minHeight
+    // is respected after b/149338177.
+    @Test
+    public void testEnterPipWithMinimalSize() throws Exception {
+        // Launch a PiP activity with minimal size specified
+        launchActivity(PIP_ACTIVITY_WITH_MINIMAL_SIZE, EXTRA_ENTER_PIP, "true");
+        // Wait for animation complete since we are comparing size
+        waitForEnterPipAnimationComplete(PIP_ACTIVITY_WITH_MINIMAL_SIZE);
+        assertPinnedStackExists();
+
+        // query the minimal size
+        final PackageManager pm = getInstrumentation().getTargetContext().getPackageManager();
+        final ActivityInfo info = pm.getActivityInfo(
+                PIP_ACTIVITY_WITH_MINIMAL_SIZE, 0 /* flags */);
+        final Size minSize = new Size(info.windowLayout.minWidth, info.windowLayout.minHeight);
+
+        // compare the bounds with minimal size
+        final Rect pipBounds = getPinnedStackBounds();
+        assertTrue("Pinned stack bounds is no smaller than minimal",
+                (pipBounds.width() == minSize.getWidth()
+                        && pipBounds.height() >= minSize.getHeight())
+                        || (pipBounds.height() == minSize.getHeight()
+                        && pipBounds.width() >= minSize.getWidth()));
+    }
+
     @Test
     public void testEnterPipAspectRatioMin() throws Exception {
         testEnterPipAspectRatio(MIN_ASPECT_RATIO_NUMERATOR, MIN_ASPECT_RATIO_DENOMINATOR);
diff --git a/tests/framework/base/windowmanager/src/android/server/wm/SplashscreenTests.java b/tests/framework/base/windowmanager/src/android/server/wm/SplashscreenTests.java
index 7f13089..1863487 100644
--- a/tests/framework/base/windowmanager/src/android/server/wm/SplashscreenTests.java
+++ b/tests/framework/base/windowmanager/src/android/server/wm/SplashscreenTests.java
@@ -28,6 +28,8 @@
 import android.graphics.Rect;
 import android.platform.test.annotations.Presubmit;
 
+import org.junit.After;
+import org.junit.Before;
 import org.junit.Test;
 
 /**
@@ -37,6 +39,17 @@
 @Presubmit
 public class SplashscreenTests extends ActivityManagerTestBase {
 
+    @Before
+    public void setUp() throws Exception {
+        super.setUp();
+        mWmState.setSanityCheckWithFocusedWindow(false);
+    }
+
+    @After
+    public void tearDown() {
+        mWmState.setSanityCheckWithFocusedWindow(true);
+    }
+
     @Test
     public void testSplashscreenContent() {
         launchActivityNoWait(SPLASHSCREEN_ACTIVITY);
diff --git a/tests/framework/base/windowmanager/src/android/server/wm/StartActivityAsUserActivity.java b/tests/framework/base/windowmanager/src/android/server/wm/StartActivityAsUserActivity.java
index cb279219..a73521b 100644
--- a/tests/framework/base/windowmanager/src/android/server/wm/StartActivityAsUserActivity.java
+++ b/tests/framework/base/windowmanager/src/android/server/wm/StartActivityAsUserActivity.java
@@ -23,6 +23,7 @@
 import android.app.Activity;
 import android.os.Bundle;
 import android.os.RemoteCallback;
+import android.os.UserHandle;
 import android.util.Log;
 
 public class StartActivityAsUserActivity extends Activity {
@@ -35,10 +36,10 @@
         RemoteCallback cb = (RemoteCallback) extra.get(EXTRA_CALLBACK);
         if (cb != null) {
             Bundle result = new Bundle();
-            result.putInt(KEY_USER_ID, getUserId());
+            result.putInt(KEY_USER_ID, UserHandle.myUserId());
             cb.sendResult(result);
         }
-        Log.i(LOG_TAG, "Second activity started with user " + getUserId());
+        Log.i(LOG_TAG, "Second activity started with user " + UserHandle.myUserId());
         finish();
     }
 }
diff --git a/tests/framework/base/windowmanager/src/android/server/wm/StartActivityTests.java b/tests/framework/base/windowmanager/src/android/server/wm/StartActivityTests.java
index e9c3f63..1057a94 100644
--- a/tests/framework/base/windowmanager/src/android/server/wm/StartActivityTests.java
+++ b/tests/framework/base/windowmanager/src/android/server/wm/StartActivityTests.java
@@ -37,6 +37,8 @@
 import static org.junit.Assert.assertNotEquals;
 
 import android.app.Activity;
+import android.app.WindowConfiguration;
+import android.content.ComponentName;
 import android.content.Intent;
 import android.os.Bundle;
 import android.platform.test.annotations.Presubmit;
@@ -44,9 +46,7 @@
 import android.server.wm.app.Components;
 import android.server.wm.intent.Activities;
 
-import androidx.test.rule.ActivityTestRule;
 
-import org.junit.Rule;
 import org.junit.Test;
 
 import java.util.Arrays;
@@ -58,34 +58,50 @@
 @Presubmit
 public class StartActivityTests extends ActivityManagerTestBase {
 
-    @Rule
-    public final ActivityTestRule<TestActivity2> mTestActivity2Rule =
-            new ActivityTestRule<>(TestActivity2.class, false /* initialTouchMode */,
-                    false /* launchActivity */);
+    @Test
+    public void testStartHomeIfNoActivities() {
+        final ComponentName defaultHome = getDefaultHomeComponent();
+        final int[] allActivityTypes = Arrays.copyOf(ALL_ACTIVITY_TYPE_BUT_HOME,
+                ALL_ACTIVITY_TYPE_BUT_HOME.length + 1);
+        allActivityTypes[allActivityTypes.length - 1] = WindowConfiguration.ACTIVITY_TYPE_HOME;
+        removeStacksWithActivityTypes(allActivityTypes);
+
+        waitAndAssertTopResumedActivity(defaultHome, DEFAULT_DISPLAY,
+                "Home activity should be restarted after force-finish");
+
+        stopTestPackage(defaultHome.getPackageName());
+
+        waitAndAssertTopResumedActivity(defaultHome, DEFAULT_DISPLAY,
+                "Home activity should be restarted after force-stop");
+    }
 
     /**
-     * Ensures {@link Activity} can only be launched from an {@link Activity}
-     * {@link android.content.Context}.
+     * Ensures {@link Activity} without {@link Intent#FLAG_ACTIVITY_NEW_TASK} can only be launched
+     * from an {@link Activity} {@link android.content.Context}.
      */
     @Test
     public void testStartActivityContexts() {
-        // Launch Activity from application context.
+        // Note by default LaunchActivityBuilder will use LAUNCHING_ACTIVITY to launch the target.
+
+        // Launch Activity from application context without FLAG_ACTIVITY_NEW_TASK.
         getLaunchActivityBuilder()
                 .setTargetActivity(TEST_ACTIVITY)
                 .setUseApplicationContext(true)
                 .setSuppressExceptions(true)
+                .setWaitForLaunched(false)
                 .execute();
 
-        // Launch second Activity from Activity Context to ensure previous Activity has launched.
-        final Activity testActivity2 = mTestActivity2Rule.launchActivity(null);
+        // Launch another activity from activity to ensure previous one has done.
+        getLaunchActivityBuilder()
+                .setTargetActivity(NO_RELAUNCH_ACTIVITY)
+                .execute();
 
-        mWmState.computeState(testActivity2.getComponentName());
+        mWmState.computeState(NO_RELAUNCH_ACTIVITY);
 
         // Verify Activity was not started.
         assertFalse(mWmState.containsActivity(TEST_ACTIVITY));
         mWmState.assertResumedActivity(
-                "Activity launched from activity context should be present",
-                testActivity2.getComponentName());
+                "Activity launched from activity context should be present", NO_RELAUNCH_ACTIVITY);
     }
 
     /**
@@ -273,7 +289,4 @@
         }
         return taskIds;
     }
-
-    public static class TestActivity2 extends Activity {
-    }
 }
diff --git a/tests/framework/base/windowmanager/src/android/server/wm/SurfaceControlViewHostTests.java b/tests/framework/base/windowmanager/src/android/server/wm/SurfaceControlViewHostTests.java
index 7f8aa01..5506e85 100644
--- a/tests/framework/base/windowmanager/src/android/server/wm/SurfaceControlViewHostTests.java
+++ b/tests/framework/base/windowmanager/src/android/server/wm/SurfaceControlViewHostTests.java
@@ -61,7 +61,6 @@
  *     atest CtsWindowManagerDeviceTestCases:SurfaceControlViewHostTests
  */
 @Presubmit
-@FlakyTest
 public class SurfaceControlViewHostTests implements SurfaceHolder.Callback {
     private final ActivityTestRule<Activity> mActivityRule = new ActivityTestRule<>(Activity.class);
 
@@ -117,7 +116,7 @@
 
         mEmbeddedLayoutParams = new WindowManager.LayoutParams(width, height,
                 WindowManager.LayoutParams.TYPE_APPLICATION, 0, PixelFormat.OPAQUE);
-        mVr.addView(v, mEmbeddedLayoutParams);
+        mVr.setView(v, mEmbeddedLayoutParams);
     }
 
     @Override
diff --git a/tests/framework/base/windowmanager/src/android/server/wm/WindowInsetsAnimationTests.java b/tests/framework/base/windowmanager/src/android/server/wm/WindowInsetsAnimationTests.java
index 089b556..2ff0d87 100644
--- a/tests/framework/base/windowmanager/src/android/server/wm/WindowInsetsAnimationTests.java
+++ b/tests/framework/base/windowmanager/src/android/server/wm/WindowInsetsAnimationTests.java
@@ -24,6 +24,7 @@
 import static android.view.WindowManager.LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_MODE_ALWAYS;
 import static androidx.test.InstrumentationRegistry.getInstrumentation;
 import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
 import static org.junit.Assert.assertNotNull;
 import static org.junit.Assert.assertTrue;
 import static org.mockito.ArgumentMatchers.any;
@@ -184,6 +185,7 @@
 
         getWmState().waitFor(state -> !state.isWindowVisible("StatusBar"),
                 "Waiting for status bar to be hidden");
+        assertFalse(getWmState().isWindowVisible("StatusBar"));
 
         verifyZeroInteractions(mActivity.mCallback);
     }
diff --git a/tests/framework/base/windowmanager/src/android/server/wm/WindowInsetsTest.java b/tests/framework/base/windowmanager/src/android/server/wm/WindowInsetsTest.java
index b817d2f..d931e25 100644
--- a/tests/framework/base/windowmanager/src/android/server/wm/WindowInsetsTest.java
+++ b/tests/framework/base/windowmanager/src/android/server/wm/WindowInsetsTest.java
@@ -29,6 +29,7 @@
 import android.platform.test.annotations.Presubmit;
 import android.view.DisplayCutout;
 import android.view.WindowInsets;
+import android.view.WindowInsets.Type;
 
 import androidx.test.filters.SmallTest;
 import androidx.test.runner.AndroidJUnit4;
@@ -72,6 +73,7 @@
         assertEquals(Insets.of(13, 14, 15, 16), insets.getMandatorySystemGestureInsets());
         assertEquals(Insets.of(17, 18, 19, 20), insets.getTappableElementInsets());
         assertSame(CUTOUT, insets.getDisplayCutout());
+        assertEquals(getCutoutSafeInsets(insets), insets.getInsets(Type.displayCutout()));
     }
 
     @Test
@@ -114,6 +116,7 @@
         assertNull(insets.getDisplayCutout());
         assertFalse(insets.isConsumed());
         assertTrue(insets.consumeDisplayCutout().isConsumed());
+        assertEquals(Insets.NONE, insets.getInsets(Type.displayCutout()));
     }
 
     @Test
@@ -137,6 +140,7 @@
         assertEquals(Insets.of(1, 2, 3, 4), insets.getSystemWindowInsets());
         assertEquals(Insets.of(5, 6, 7, 8), insets.getStableInsets());
         assertSame(CUTOUT, insets.getDisplayCutout());
+        assertEquals(getCutoutSafeInsets(insets), insets.getInsets(Type.displayCutout()));
     }
 
     @Test
@@ -197,6 +201,7 @@
         assertEquals(Insets.NONE, consumed.getSystemGestureInsets());
         assertEquals(Insets.NONE, consumed.getMandatorySystemGestureInsets());
         assertEquals(Insets.NONE, consumed.getTappableElementInsets());
+        assertEquals(Insets.NONE, consumed.getInsets(Type.displayCutout()));
     }
 
     @Test
@@ -217,6 +222,7 @@
         assertEquals(Insets.NONE, consumed.getSystemGestureInsets());
         assertEquals(Insets.NONE, consumed.getMandatorySystemGestureInsets());
         assertEquals(Insets.NONE, consumed.getTappableElementInsets());
+        assertEquals(Insets.NONE, consumed.getInsets(Type.displayCutout()));
     }
 
     @Test
@@ -237,6 +243,8 @@
         assertEquals(insets.getSystemGestureInsets(), consumed.getSystemGestureInsets());
         assertEquals(insets.getMandatorySystemGestureInsets(), consumed.getMandatorySystemGestureInsets());
         assertEquals(insets.getTappableElementInsets(), consumed.getTappableElementInsets());
+        assertEquals(
+                insets.getInsets(Type.displayCutout()), consumed.getInsets(Type.displayCutout()));
     }
 
     @Test
@@ -395,6 +403,8 @@
         assertEquals(applyInset(insets.getTappableElementInsets()),
                 insetInsets.getTappableElementInsets());
         assertEquals(applyInset(getCutoutSafeInsets(insets)), getCutoutSafeInsets(insetInsets));
+        assertEquals(applyInset(getCutoutSafeInsets(insets)),
+                insetInsets.getInsets(Type.displayCutout()));
     }
 
     @Test
@@ -415,6 +425,7 @@
         assertEquals(Insets.NONE, insetInsets.getMandatorySystemGestureInsets());
         assertEquals(Insets.NONE, insetInsets.getTappableElementInsets());
         assertNull(insetInsets.getDisplayCutout());
+        assertEquals(Insets.NONE, insetInsets.getInsets(Type.displayCutout()));
     }
 
     @Test
diff --git a/tests/framework/base/windowmanager/src/android/server/wm/WindowMetricsTests.java b/tests/framework/base/windowmanager/src/android/server/wm/WindowMetricsTests.java
index 1b04e13..684d10e 100644
--- a/tests/framework/base/windowmanager/src/android/server/wm/WindowMetricsTests.java
+++ b/tests/framework/base/windowmanager/src/android/server/wm/WindowMetricsTests.java
@@ -16,6 +16,9 @@
 
 package android.server.wm;
 
+import static android.view.WindowInsets.Type.displayCutout;
+import static android.view.WindowInsets.Type.navigationBars;
+
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertTrue;
 import static org.junit.Assume.assumeFalse;
@@ -27,7 +30,6 @@
 import android.platform.test.annotations.Presubmit;
 import android.util.Size;
 import android.view.Display;
-import android.view.DisplayCutout;
 import android.view.View;
 import android.view.WindowInsets;
 import android.view.WindowMetrics;
@@ -103,26 +105,14 @@
 
     private static Size getLegacySize(WindowMetrics windowMetrics) {
         WindowInsets windowInsets = windowMetrics.getWindowInsets();
-        final Insets insetsWithCutout = getProperInsetsWithCutout(windowInsets.getStableInsets(),
-                windowInsets.getDisplayCutout());
-        final int insetsInWidth = insetsWithCutout.left + insetsWithCutout.right;
-        final int insetsInHeight = insetsWithCutout.top + insetsWithCutout.bottom;
+        final Insets insetsWithCutout =
+                windowInsets.getInsetsIgnoringVisibility(navigationBars() | displayCutout());
+
+        final int insetsWidth = insetsWithCutout.left + insetsWithCutout.right;
+        final int insetsHeight = insetsWithCutout.top + insetsWithCutout.bottom;
 
         Size size = windowMetrics.getSize();
-        return new Size(size.getWidth() - insetsInWidth, size.getHeight() - insetsInHeight);
-    }
-
-    private static Insets getProperInsetsWithCutout(Insets stableInsets, DisplayCutout cutout) {
-        final Insets excludingStatusBar = Insets.of(stableInsets.left, 0,
-                stableInsets.right, stableInsets.bottom);
-        if (cutout == null) {
-            return excludingStatusBar;
-        } else {
-            final Insets unionInsetsWithCutout = Insets.max(excludingStatusBar,
-                    Insets.of(cutout.getSafeInsetLeft(), cutout.getSafeInsetTop(),
-                            cutout.getSafeInsetRight(), cutout.getSafeInsetBottom()));
-            return unionInsetsWithCutout;
-        }
+        return new Size(size.getWidth() - insetsWidth, size.getHeight() - insetsHeight);
     }
 
     public static class MetricsActivity extends Activity implements View.OnLayoutChangeListener {
diff --git a/tests/framework/base/windowmanager/src/android/server/wm/intent/LaunchRunner.java b/tests/framework/base/windowmanager/src/android/server/wm/intent/LaunchRunner.java
index 9e1d67a..f35ca66 100644
--- a/tests/framework/base/windowmanager/src/android/server/wm/intent/LaunchRunner.java
+++ b/tests/framework/base/windowmanager/src/android/server/wm/intent/LaunchRunner.java
@@ -71,11 +71,11 @@
      * The activities that were already present in the system when the test started.
      * So they can be removed form the outputs, otherwise our tests would be system dependent.
      */
-    private List<WindowManagerState.ActivityTask> mBaseStacks;
+    private List<WindowManagerState.ActivityTask> mBaseTasks;
 
     public LaunchRunner(IntentTestBase testBase) {
         mTestBase = testBase;
-        mBaseStacks = getBaseStacks();
+        mBaseTasks = getBaseTasks();
     }
 
     /**
@@ -106,7 +106,7 @@
 
         // assert that the state after setup is the same this time as the recorded state.
         StateDump setupStateDump = waitDumpAndTrimForVerification(getLast(activityLog),
-                testCase.getEndState());
+                testCase.getInitialState());
         assertInitialStateEqual(testCase.getInitialState(), setupStateDump);
 
         // apply all the intents in the act stage
@@ -281,8 +281,8 @@
 
     /**
      * After the last activity has been launched we wait for a valid state + an extra three seconds
-     * so have a stable state of the system. Also all previously known stacks in
-     * {@link LaunchRunner#mBaseStacks} is excluded from the output.
+     * so have a stable state of the system. Also all previously known tasks in
+     * {@link LaunchRunner#mBaseTasks} is excluded from the output.
      *
      * @param activity The last activity to be launched before dumping the state.
      * @return A stable {@link StateDump}, meaning no more {@link android.app.Activity} is in a
@@ -294,9 +294,9 @@
         // lifecycle state. wait an extra 3 seconds for it to settle
         SystemClock.sleep(BEFORE_DUMP_TIMEOUT);
         mTestBase.getWmState().computeState(activity.getComponentName());
-        List<WindowManagerState.ActivityTask> endStateStacks =
+        List<WindowManagerState.ActivityTask> endStateTasks =
                 mTestBase.getWmState().getRootTasks();
-        return StateDump.fromStacks(endStateStacks, mBaseStacks);
+        return StateDump.fromTasks(endStateTasks, mBaseTasks);
     }
 
     /**
@@ -316,17 +316,17 @@
         // lifecycle state. wait an extra 3 seconds for it to settle
         SystemClock.sleep(BEFORE_DUMP_TIMEOUT);
         mTestBase.getWmState().waitForWithAmState(
-                am -> StateDump.fromStacks(am.getRootTasks(), mBaseStacks).equals(expected),
+                am -> StateDump.fromTasks(am.getRootTasks(), mBaseTasks).equals(expected),
                 "the activity states match up with what we recorded");
         mTestBase.getWmState().computeState(activity.getComponentName());
 
-        List<WindowManagerState.ActivityTask> endStateStacks =
+        List<WindowManagerState.ActivityTask> endStateTasks =
                 mTestBase.getWmState().getRootTasks();
 
-        return StateDump.fromStacks(endStateStacks, mBaseStacks);
+        return StateDump.fromTasks(endStateTasks, mBaseTasks);
     }
 
-    private List<WindowManagerState.ActivityTask> getBaseStacks() {
+    private List<WindowManagerState.ActivityTask> getBaseTasks() {
         WindowManagerStateHelper amWmState = mTestBase.getWmState();
         amWmState.computeState(new ComponentName[]{});
         return amWmState.getRootTasks();
diff --git a/tests/framework/base/windowmanager/src/android/server/wm/intent/Persistence.java b/tests/framework/base/windowmanager/src/android/server/wm/intent/Persistence.java
index f3ab41a..92e8dfd 100644
--- a/tests/framework/base/windowmanager/src/android/server/wm/intent/Persistence.java
+++ b/tests/framework/base/windowmanager/src/android/server/wm/intent/Persistence.java
@@ -440,54 +440,68 @@
     }
 
     public static class StateDump {
-        final List<StackState> mStacks;
+        private static final String TASKS_KEY = "tasks";
+        private static final String RESUMED_ACTIVITY_KEY = "resumedActivity";
 
-        public static StateDump fromStacks(List<WindowManagerState.ActivityTask> activityTasks,
+        /**
+         * The component name of the resumedActivity in this state, empty string if there is none.
+         */
+        private String mResumedActivity;
+
+        /**
+         * The Tasks in this stack ordered from most recent to least recent.
+         */
+        private List<TaskState> mTasks;
+
+        public static StateDump fromTasks(List<WindowManagerState.ActivityTask> activityTasks,
                 List<WindowManagerState.ActivityTask> baseStacks) {
-            List<StackState> stacks = new ArrayList<>();
-            for (WindowManagerState.ActivityTask stack : trimStacks(activityTasks,
-                    baseStacks)) {
-                stacks.add(new StackState(stack));
+            List<TaskState> tasks = new ArrayList<>();
+            for (WindowManagerState.ActivityTask task : trimTasks(activityTasks, baseStacks)) {
+                tasks.add(new TaskState(task));
             }
-
-            return new StateDump(stacks);
+            return new StateDump(tasks);
         }
 
-        public StateDump(List<StackState> stacks) {
-            mStacks = stacks;
+        private StateDump(String resumedActivity, List<TaskState> tasks) {
+            mResumedActivity = resumedActivity;
+            mTasks = tasks;
+        }
+
+        public StateDump(List<TaskState> tasks) {
+            mTasks = tasks;
         }
 
         JSONObject toJson() throws JSONException {
-            JSONArray stacks = new JSONArray();
-            for (StackState stack : mStacks) {
-                stacks.put(stack.toJson());
+            JSONArray tasks = new JSONArray();
+            for (TaskState task : mTasks) {
+                tasks.put(task.toJson());
             }
 
-            return new JSONObject().put("stacks", stacks);
+            return new JSONObject().put("tasks", tasks);
         }
 
         static StateDump fromJson(JSONObject object) throws JSONException {
-            JSONArray jsonTasks = object.getJSONArray("stacks");
-            List<StackState> stacks = new ArrayList<>();
+            JSONArray jsonTasks = object.getJSONArray(TASKS_KEY);
+            List<TaskState> tasks = new ArrayList<>();
 
             for (int i = 0; i < jsonTasks.length(); i++) {
-                stacks.add(StackState.fromJson((JSONObject) jsonTasks.get(i)));
+                tasks.add(TaskState.fromJson((JSONObject) jsonTasks.get(i)));
             }
 
-            return new StateDump(stacks);
+            return new StateDump(object.optString(RESUMED_ACTIVITY_KEY, ""), tasks);
         }
 
         /**
-         * To make the state dump non device specific we remove every stack that was present
-         * in the system before recording, by their ID. For example a stack containing the launcher
+         * To make the state dump non device specific we remove every task that was present
+         * in the system before recording, by their ID. For example a task containing the launcher
          * activity.
          */
-        public static List<WindowManagerState.ActivityTask> trimStacks(
+        public static List<WindowManagerState.ActivityTask> trimTasks(
                 List<WindowManagerState.ActivityTask> toTrim,
                 List<WindowManagerState.ActivityTask> trimFrom) {
 
-            for (WindowManagerState.ActivityTask stack : trimFrom) {
-                toTrim.removeIf(t -> t.getRootTaskId() == stack.getRootTaskId());
+            for (WindowManagerState.ActivityTask task : trimFrom) {
+                toTrim.removeIf(t -> t.getRootTaskId() == task.getRootTaskId());
             }
 
             return toTrim;
@@ -498,86 +512,12 @@
             if (this == o) return true;
             if (o == null || getClass() != o.getClass()) return false;
             StateDump stateDump = (StateDump) o;
-            return Objects.equals(mStacks, stateDump.mStacks);
+            return Objects.equals(mTasks, stateDump.mTasks);
         }
 
         @Override
         public int hashCode() {
-            return Objects.hash(mStacks);
-        }
-    }
-
-    /**
-     * A simplified JSON version of the information in {@link WindowManagerState.ActivityTask}
-     */
-    public static class StackState {
-        private static final String TASKS_KEY = "tasks";
-        private static final String RESUMED_ACTIVITY_KEY = "resumedActivity";
-
-        /**
-         * The component name of the resumedActivity in this Stack, empty string if there is none.
-         */
-        private final String mResumedActivity;
-        /**
-         * The Tasks in this stack ordered from most recent to least recent.
-         */
-        private final List<TaskState> mTasks;
-
-        public StackState(String resumedActivity, List<TaskState> tasks) {
-            mResumedActivity = resumedActivity;
-            mTasks = tasks;
-        }
-
-        public StackState(WindowManagerState.ActivityTask stack) {
-            this.mResumedActivity = stack.getResumedActivity();
-            mTasks = new ArrayList<>();
-            for (WindowManagerState.ActivityTask task : stack.getTasks()) {
-                this.mTasks.add(new TaskState(task));
-            }
-        }
-
-        JSONObject toJson() throws JSONException {
-            JSONArray jsonTasks = new JSONArray();
-
-            for (TaskState task : mTasks) {
-                jsonTasks.put(task.toJson());
-            }
-
-            return new JSONObject()
-                    .put(TASKS_KEY, jsonTasks)
-                    .put(RESUMED_ACTIVITY_KEY, mResumedActivity);
-        }
-
-        static StackState fromJson(JSONObject object) throws JSONException {
-            JSONArray jsonTasks = object.getJSONArray(TASKS_KEY);
-            List<TaskState> tasks = new ArrayList<>();
-
-            for (int i = 0; i < jsonTasks.length(); i++) {
-                tasks.add(TaskState.fromJson((JSONObject) jsonTasks.get(i)));
-            }
-
-            return new StackState(object.optString(RESUMED_ACTIVITY_KEY, ""), tasks);
-        }
-
-        public String getResumedActivity() {
-            return mResumedActivity;
-        }
-
-        public List<TaskState> getTasks() {
-            return mTasks;
-        }
-
-        @Override
-        public boolean equals(Object o) {
-            if (this == o) return true;
-            if (o == null || getClass() != o.getClass()) return false;
-            StackState stack = (StackState) o;
-            return Objects.equals(mTasks, stack.mTasks);
-        }
-
-        @Override
-        public int hashCode() {
-            return Objects.hash(mResumedActivity, mTasks);
+            return Objects.hash(mTasks);
         }
     }
 
diff --git a/tests/framework/base/windowmanager/util/src/android/server/wm/ActivityManagerTestBase.java b/tests/framework/base/windowmanager/util/src/android/server/wm/ActivityManagerTestBase.java
index 24033a2..e1ecc13 100644
--- a/tests/framework/base/windowmanager/util/src/android/server/wm/ActivityManagerTestBase.java
+++ b/tests/framework/base/windowmanager/util/src/android/server/wm/ActivityManagerTestBase.java
@@ -546,26 +546,25 @@
     }
 
     /**
-     * Move around center of the specific display to ensures the display to be focused without
-     * triggering potential clicked event to impact the test environment.
+     * Insert an input event (ACTION_DOWN -> ACTION_CANCEL) to ensures the display to be focused
+     * without triggering potential clicked to impact the test environment.
      * (e.g: Keyguard credential activated unexpectedly.)
      *
      * @param displayId the display ID to gain focused by inject swipe action
      */
-    protected void moveAroundCenterSync(int displayId) {
+    protected void touchAndCancelOnDisplayCenterSync(int displayId) {
         final Rect bounds = mWmState.getDisplay(displayId).getDisplayRect();
+        final int x = bounds.left + bounds.width() / 2;
+        final int y = bounds.top + bounds.height() / 2;
         final long downTime = SystemClock.uptimeMillis();
+        injectMotion(downTime, downTime, MotionEvent.ACTION_DOWN, x, y, displayId, true /* sync */);
+
+        final long eventTime = SystemClock.uptimeMillis();
         final int touchSlop = ViewConfiguration.get(mContext).getScaledTouchSlop();
-        final int downX = bounds.left + bounds.width() / 2;
-        final int downY = bounds.top + bounds.height() / 2;
-        injectMotion(downTime, downTime, MotionEvent.ACTION_DOWN, downX, downY, displayId, true);
-
-        final int moveX = downX + Float.floatToIntBits(touchSlop / 2.0f);
-        final int moveY = downY + Float.floatToIntBits(touchSlop / 2.0f);
-        injectMotion(downTime, downTime, MotionEvent.ACTION_MOVE, moveX, moveY, displayId, true);
-
-        final long upTime = SystemClock.uptimeMillis();
-        injectMotion(downTime, upTime, MotionEvent.ACTION_UP, moveX, moveY, displayId, true);
+        final int tapX = x + Math.round(touchSlop / 2.0f);
+        final int tapY = y + Math.round(touchSlop / 2.0f);
+        injectMotion(downTime, eventTime, MotionEvent.ACTION_CANCEL, tapX, tapY, displayId,
+                true /* sync */);
     }
 
     protected void tapOnDisplaySync(int x, int y, int displayId) {
@@ -1153,6 +1152,19 @@
         }
     }
 
+    ComponentName getDefaultHomeComponent() {
+        final Intent intent = new Intent(ACTION_MAIN);
+        intent.addCategory(CATEGORY_HOME);
+        intent.addFlags(FLAG_ACTIVITY_NEW_TASK);
+        final ResolveInfo resolveInfo =
+                mContext.getPackageManager().resolveActivity(intent, MATCH_DEFAULT_ONLY);
+        if (resolveInfo == null) {
+            throw new AssertionError("Home activity not found");
+        }
+        return new ComponentName(resolveInfo.activityInfo.packageName,
+                resolveInfo.activityInfo.name);
+    }
+
     /**
      * HomeActivitySession is used to replace the default home component, so that you can use
      * your preferred home for testing within the session. The original default home will be
@@ -1166,16 +1178,7 @@
         HomeActivitySession(ComponentName sessionHome) {
             mSessionHome = sessionHome;
             mPackageManager = mContext.getPackageManager();
-
-            final Intent intent = new Intent(ACTION_MAIN);
-            intent.addCategory(CATEGORY_HOME);
-            intent.addFlags(FLAG_ACTIVITY_NEW_TASK);
-            final ResolveInfo resolveInfo =
-                    mPackageManager.resolveActivity(intent, MATCH_DEFAULT_ONLY);
-            if (resolveInfo != null) {
-                mOrigHome = new ComponentName(resolveInfo.activityInfo.packageName,
-                        resolveInfo.activityInfo.name);
-            }
+            mOrigHome = getDefaultHomeComponent();
 
             SystemUtil.runWithShellPermissionIdentity(
                     () -> mPackageManager.setComponentEnabledSetting(mSessionHome,
@@ -1234,7 +1237,7 @@
         public LockScreenSession enterAndConfirmLockCredential() {
             // Ensure focus will switch to default display. Meanwhile we cannot tap on center area,
             // which may tap on input credential area.
-            moveAroundCenterSync(DEFAULT_DISPLAY);
+            touchAndCancelOnDisplayCenterSync(DEFAULT_DISPLAY);
 
             waitForDeviceIdle(3000);
             SystemUtil.runWithShellPermissionIdentity(() ->
@@ -1276,7 +1279,7 @@
 
         LockScreenSession unlockDevice() {
             // Make sure the unlock button event is send to the default display.
-            moveAroundCenterSync(DEFAULT_DISPLAY);
+            touchAndCancelOnDisplayCenterSync(DEFAULT_DISPLAY);
 
             pressUnlockButton();
             return this;
diff --git a/tests/framework/base/windowmanager/util/src/android/server/wm/WindowManagerState.java b/tests/framework/base/windowmanager/util/src/android/server/wm/WindowManagerState.java
index d747155..3f3ac8f 100644
--- a/tests/framework/base/windowmanager/util/src/android/server/wm/WindowManagerState.java
+++ b/tests/framework/base/windowmanager/util/src/android/server/wm/WindowManagerState.java
@@ -51,6 +51,7 @@
 import androidx.annotation.Nullable;
 
 import com.android.server.wm.nano.AppTransitionProto;
+import com.android.server.wm.nano.DisplayAreaProto;
 import com.android.server.wm.nano.DisplayFramesProto;
 import com.android.server.wm.nano.IdentifierProto;
 import com.android.server.wm.nano.KeyguardControllerProto;
@@ -60,9 +61,11 @@
 import com.android.server.wm.nano.PinnedStackControllerProto;
 import com.android.server.wm.nano.RootWindowContainerProto;
 import com.android.server.wm.nano.TaskProto;
+import com.android.server.wm.nano.WindowContainerChildProto;
 import com.android.server.wm.nano.WindowContainerProto;
 import com.android.server.wm.nano.WindowFramesProto;
 import com.android.server.wm.nano.WindowManagerServiceDumpProto;
+import com.android.server.wm.nano.WindowTokenProto;
 import com.android.server.wm.nano.WindowStateAnimatorProto;
 import com.android.server.wm.nano.WindowStateProto;
 import com.android.server.wm.nano.WindowSurfaceControllerProto;
@@ -119,6 +122,7 @@
     // Must be kept in sync with 'default_minimal_size_resizable_task' dimen from frameworks/base.
     private static final int DEFAULT_RESIZABLE_TASK_SIZE_DP = 220;
 
+    private RootWindowContainer mRoot = null;
     // Displays in z-order with the top most at the front of the list, starting with primary.
     private final List<DisplayContent> mDisplays = new ArrayList<>();
     // Stacks in z-order with the top most at the front of the list, starting with primary display.
@@ -141,6 +145,7 @@
     private int mRotation;
     private int mLastOrientation;
     private boolean mDisplayFrozen;
+    private boolean mSanityCheckFocusedWindow = true;
 
     static String appStateToString(int appState) {
         switch (appState) {
@@ -237,6 +242,52 @@
         return TYPE_NAVIGATION_BAR == navState.getType();
     }
 
+    /** Enable/disable the mFocusedWindow check during the computeState.*/
+    void setSanityCheckWithFocusedWindow(boolean sanityCheckFocusedWindow) {
+        mSanityCheckFocusedWindow = sanityCheckFocusedWindow;
+    }
+
+    /**
+     * For a given WindowContainer, traverse down the hierarchy and add all children of type
+     * {@code T} to {@code outChildren}.
+     */
+    private static <T extends WindowContainer> void collectDescendantsOfType(Class<T> clazz,
+            WindowContainer root, List<T> outChildren) {
+        collectDescendantsOfTypeIf(clazz, t -> true, root, outChildren);
+    }
+
+    /**
+     * For a given WindowContainer, traverse down the hierarchy and add all children of type
+     * {@code T} to {@code outChildren} if the child passes the test {@code predicate}.
+     */
+    private static <T extends WindowContainer> void collectDescendantsOfTypeIf(Class<T> clazz,
+            Predicate<T> predicate, WindowContainer root, List<T> outChildren) {
+        // Traverse top to bottom
+        for (int i = root.mChildren.size()-1; i >= 0; i--) {
+            final WindowContainer child = root.mChildren.get(i);
+            if (clazz.isInstance(child)) {
+                if(predicate.test(clazz.cast(child))) {
+                    outChildren.add(clazz.cast(child));
+                }
+            }
+            collectDescendantsOfTypeIf(clazz, predicate, child, outChildren);
+        }
+    }
+
+    /**
+     * For a given WindowContainer, traverse down the hierarchy and add all immediate children of
+     * type {@code T} to {@code outChildren}.
+     */
+    private static <T extends WindowContainer> void collectChildrenOfType(Class<T> clazz,
+            WindowContainer root, List<T> outChildren) {
+        for (int i = root.mChildren.size()-1; i >= 0; i--) {
+            final WindowContainer child = root.mChildren.get(i);
+            if (clazz.isInstance(child)) {
+                outChildren.add(clazz.cast(child));
+            }
+        }
+    }
+
     public void computeState() {
         // It is possible the system is in the middle of transition to the right state when we get
         // the dump. We try a few times to get the information we need before giving up.
@@ -264,7 +315,7 @@
             }
 
             retry = mRootTasks.isEmpty() || mTopFocusedTaskId == -1 || mWindowStates.isEmpty()
-                    || mFocusedApp == null
+                    || mFocusedApp == null || (mSanityCheckFocusedWindow && mFocusedWindow == null)
                     || (mTopResumedActivityRecord == null || mResumedActivitiesInStacks.isEmpty())
                     && !mKeyguardControllerState.keyguardShowing;
         } while (retry && retriesLeft-- > 0);
@@ -310,6 +361,26 @@
         }
     }
 
+    /** Update WindowManagerState state for a newly added DisplayContent. */
+    private void updateForDisplayContent(DisplayContent display) {
+        if (display.mResumedActivity != null) {
+            mResumedActivitiesInDisplays.add(display.mResumedActivity);
+        }
+
+        for (int i = 0; i < display.mRootTasks.size(); i++) {
+            ActivityTask task = display.mRootTasks.get(i);
+            mRootTasks.add(task);
+            if (task.mResumedActivity != null) {
+                mResumedActivitiesInStacks.add(task.mResumedActivity);
+            }
+        }
+
+        if (display.mDefaultPinnedStackBounds != null) {
+            mDefaultPinnedStackBounds = display.mDefaultPinnedStackBounds;
+            mPinnedStackMovementBounds = display.mPinnedStackMovementBounds;
+        }
+    }
+
     private void parseSysDumpProto(byte[] sysDump) throws InvalidProtocolBufferNanoException {
         reset();
 
@@ -318,10 +389,11 @@
         if (state.focusedWindow != null) {
             mFocusedWindow = state.focusedWindow.title;
         }
-
-        for (int i = 0; i < root.displays.length; i++) {
-            final DisplayContentProto display = root.displays[i];
-            mDisplays.add(new DisplayContent(display, this));
+        mRoot = new RootWindowContainer(root);
+        collectDescendantsOfType(DisplayContent.class, mRoot, mDisplays);
+        for (int i = 0; i < mDisplays.size(); i++) {
+            DisplayContent display = mDisplays.get(i);
+            updateForDisplayContent(display);
         }
         mKeyguardControllerState = new KeyguardControllerState(root.keyguardController);
         mFocusedApp = state.focusedApp;
@@ -337,9 +409,7 @@
             mPendingActivities.add(root.pendingActivities[i].title);
         }
 
-        for (int i = 0; i < root.windows.length; i++) {
-            mWindowStates.add(new WindowState(root.windows[i]));
-        }
+        collectDescendantsOfType(WindowState.class, mRoot, mWindowStates);
 
         if (state.inputMethodWindow != null) {
             mInputMethodWindowAppToken = Integer.toHexString(state.inputMethodWindow.hashCode);
@@ -350,6 +420,7 @@
     }
 
     private void reset() {
+        mRoot = null;
         mDisplays.clear();
         mRootTasks.clear();
         mWindowStates.clear();
@@ -762,7 +833,7 @@
     }
 
     public List<WindowState> getMatchingVisibleWindowState(final String windowName) {
-        return getMatchingWindows(ws -> ws.isShown() && windowName.equals(ws.getName()))
+        return getMatchingWindows(ws -> ws.isSurfaceShown() && windowName.equals(ws.getName()))
                 .collect(Collectors.toList());
     }
 
@@ -834,11 +905,11 @@
         return false;
     }
 
-    /** Check if at least one window which matches provided window name is visible. */
-    boolean isWindowVisible(String windowName) {
+    /** Check if at least one window which matches the specified name has shown it's surface. */
+    boolean isWindowSurfaceShown(String windowName) {
         for (WindowState window : mWindowStates) {
             if (window.getName().equals(windowName)) {
-                if (window.isShown()) {
+                if (window.isSurfaceShown()) {
                     return true;
                 }
             }
@@ -846,19 +917,31 @@
         return false;
     }
 
-    boolean allWindowsVisible(String windowName) {
-        boolean allVisible = false;
+    /** Check if at least one window which matches provided window name is visible. */
+    boolean isWindowVisible(String windowName) {
         for (WindowState window : mWindowStates) {
             if (window.getName().equals(windowName)) {
-                if (!window.isShown()) {
+                if (window.isVisible()) {
+                    return true;
+                }
+            }
+        }
+        return false;
+    }
+
+    boolean allWindowSurfacesShown(String windowName) {
+        boolean allShown = false;
+        for (WindowState window : mWindowStates) {
+            if (window.getName().equals(windowName)) {
+                if (!window.isSurfaceShown()) {
                     log("[VISIBLE] not visible" + windowName);
                     return false;
                 }
                 log("[VISIBLE] visible" + windowName);
-                allVisible = true;
+                allShown = true;
             }
         }
-        return allVisible;
+        return allShown;
     }
 
     WindowState findFirstWindowWithType(int type) {
@@ -911,12 +994,16 @@
     }
 
     public static class DisplayContent extends ActivityContainer {
+        static Predicate<ActivityTask> isRootAndNotTaskOrganized
+                = t -> !t.mCreatedByOrganizer && t.isRootTask();
 
         public int mId;
         ArrayList<ActivityTask> mRootTasks = new ArrayList<>();
         int mFocusedRootTaskId;
         String mResumedActivity;
         boolean mSingleTaskInstance;
+        Rect mDefaultPinnedStackBounds = null;
+        Rect mPinnedStackMovementBounds = null;
 
         private Rect mDisplayRect = new Rect();
         private Rect mAppRect = new Rect();
@@ -929,30 +1016,19 @@
         private String mLastTransition;
         private String mAppTransitionState;
 
-        DisplayContent(DisplayContentProto proto, WindowManagerState amState) {
+        DisplayContent(DisplayContentProto proto) {
             super(proto.windowContainer);
             mId = proto.id;
             mFocusedRootTaskId = proto.focusedRootTaskId;
             mSingleTaskInstance = proto.singleTaskInstance;
             if (proto.resumedActivity != null) {
                 mResumedActivity = proto.resumedActivity.title;
-                amState.mResumedActivitiesInDisplays.add(mResumedActivity);
             }
-            for (int i = 0; i < proto.tasks.length; i++) {
-                ActivityTask task = new ActivityTask(proto.tasks[i]);
-                if (task.mCreatedByOrganizer) {
-                    // TODO(b/149338177): figure out how CTS tests deal with organizer. For now,
-                    //                    don't treat them as regular stacks
-                    // Skip tasks created by an organizer
-                    continue;
-                }
-                mRootTasks.add(task);
-                // Also update activity manager state
-                amState.mRootTasks.add(task);
-                if (task.mResumedActivity != null) {
-                    amState.mResumedActivitiesInStacks.add(task.mResumedActivity);
-                }
-            }
+            // TODO(b/149338177): figure out how CTS tests deal with organizer. For now,
+            //                    don't treat them as regular stacks
+            // Skip tasks created by an organizer
+            collectDescendantsOfTypeIf(ActivityTask.class, isRootAndNotTaskOrganized, this,
+                                       mRootTasks);
 
             mDpi = proto.dpi;
             DisplayInfoProto infoProto = proto.displayInfo;
@@ -981,8 +1057,8 @@
 
             PinnedStackControllerProto pinnedStackProto = proto.pinnedStackController;
             if (pinnedStackProto != null) {
-                amState.mDefaultPinnedStackBounds = extract(pinnedStackProto.defaultBounds);
-                amState.mPinnedStackMovementBounds = extract(pinnedStackProto.movementBounds);
+                mDefaultPinnedStackBounds = extract(pinnedStackProto.defaultBounds);
+                mPinnedStackMovementBounds = extract(pinnedStackProto.movementBounds);
             }
 
         }
@@ -1078,12 +1154,8 @@
                 mResumedActivity = proto.resumedActivity.title;
             }
 
-            for (int i = 0;  i < proto.tasks.length; i++) {
-                mTasks.add(new ActivityTask(proto.tasks[i]));
-            }
-            for (int i = 0;  i < proto.activities.length; i++) {
-                mActivities.add(new Activity(proto.activities[i], this));
-            }
+            collectChildrenOfType(ActivityTask.class, this, mTasks);
+            collectChildrenOfType(Activity.class, this, mActivities);
         }
 
         public int getResizeMode() {
@@ -1093,6 +1165,9 @@
         public int getTaskId() {
             return mTaskId;
         }
+        boolean isRootTask() {
+            return mTaskId == mRootTaskId;
+        }
 
         public int getRootTaskId() {
             return mRootTaskId;
@@ -1174,9 +1249,9 @@
         public boolean translucent;
         ActivityTask task;
 
-        Activity(ActivityRecordProto proto, ActivityTask parent) {
+        Activity(ActivityRecordProto proto, WindowContainer parent) {
             super(proto.windowToken.windowContainer);
-            task = parent;
+            task = (ActivityTask) parent;
             name = proto.name;
             state = proto.state;
             visible = proto.visible;
@@ -1289,16 +1364,84 @@
         }
     }
 
+    public static class RootWindowContainer extends WindowContainer {
+        RootWindowContainer(RootWindowContainerProto proto) {
+            super(proto.windowContainer);
+        }
+    }
+    public static class DisplayArea extends WindowContainer {
+        DisplayArea(DisplayAreaProto proto) {
+            super(proto.windowContainer);
+        }
+    }
+    public static class WindowToken extends WindowContainer {
+        WindowToken(WindowTokenProto proto) {
+            super(proto.windowContainer);
+        }
+    }
+
+    /**
+     * Represents WindowContainer classes such as DisplayContent.WindowContainers and
+     * DisplayContent.NonAppWindowContainers. This can be expanded into a specific class
+     * if we need track and assert some state in the future.
+     */
+    public static class GenericWindowContainer extends WindowContainer {
+        GenericWindowContainer(WindowContainerProto proto) {
+            super(proto);
+        }
+    }
+
+    static WindowContainer getWindowContainer(WindowContainerChildProto proto,
+            WindowContainer parent) {
+        if (proto.displayContent != null) {
+           return new DisplayContent(proto.displayContent);
+        }
+
+        if (proto.displayArea != null) {
+           return new DisplayArea(proto.displayArea);
+        }
+
+        if (proto.task != null) {
+           return new ActivityTask(proto.task);
+        }
+
+        if (proto.activity != null) {
+           return new Activity(proto.activity, parent);
+        }
+
+        if (proto.windowToken != null) {
+           return new WindowToken(proto.windowToken);
+        }
+
+        if (proto.window != null) {
+           return new WindowState(proto.window);
+        }
+
+        if (proto.windowContainer != null) {
+           return new GenericWindowContainer(proto.windowContainer);
+        }
+        return null;
+    }
+
     static abstract class WindowContainer extends ConfigurationContainer {
 
         protected boolean mFullscreen;
         protected Rect mBounds;
         protected int mOrientation;
+        protected boolean mVisible;
         protected List<WindowState> mSubWindows = new ArrayList<>();
+        protected List<WindowContainer> mChildren = new ArrayList<>();
 
         WindowContainer(WindowContainerProto proto) {
             super(proto.configurationContainer);
             mOrientation = proto.orientation;
+            for (int i = 0; i < proto.children.length; i++) {
+                final WindowContainer child = getWindowContainer(proto.children[i], this);
+                if (child != null) {
+                    mChildren.add(child);
+                }
+            }
+            mVisible = proto.visible;
         }
 
         Rect getBounds() {
@@ -1309,6 +1452,10 @@
             return mFullscreen;
         }
 
+        boolean isVisible() {
+            return mVisible;
+        }
+
         List<WindowState> getWindows() {
             return mSubWindows;
         }
@@ -1379,12 +1526,7 @@
             } else {
                 mWindowType = 0;
             }
-            for (int i = 0; i < proto.childWindows.length; i++) {
-                WindowStateProto childProto = proto.childWindows[i];
-                WindowState childWindow = new WindowState(childProto);
-                mSubWindows.add(childWindow);
-                mSubWindows.addAll(childWindow.getWindows());
-            }
+            collectDescendantsOfType(WindowState.class, this, mSubWindows);
         }
 
         @NonNull
@@ -1448,7 +1590,7 @@
             return mCrop;
         }
 
-        public boolean isShown() {
+        public boolean isSurfaceShown() {
             return mShown;
         }
 
diff --git a/tests/framework/base/windowmanager/util/src/android/server/wm/WindowManagerStateHelper.java b/tests/framework/base/windowmanager/util/src/android/server/wm/WindowManagerStateHelper.java
index fc31bd6..31d65de 100644
--- a/tests/framework/base/windowmanager/util/src/android/server/wm/WindowManagerStateHelper.java
+++ b/tests/framework/base/windowmanager/util/src/android/server/wm/WindowManagerStateHelper.java
@@ -18,11 +18,8 @@
 
 import static android.app.ActivityTaskManager.INVALID_STACK_ID;
 import static android.app.WindowConfiguration.ACTIVITY_TYPE_UNDEFINED;
-import static android.app.WindowConfiguration.WINDOWING_MODE_FREEFORM;
-import static android.app.WindowConfiguration.WINDOWING_MODE_PINNED;
 import static android.app.WindowConfiguration.WINDOWING_MODE_SPLIT_SCREEN_PRIMARY;
 import static android.app.WindowConfiguration.WINDOWING_MODE_UNDEFINED;
-import static android.content.pm.ActivityInfo.RESIZE_MODE_RESIZEABLE;
 import static android.server.wm.ComponentNameUtils.getActivityName;
 import static android.server.wm.ComponentNameUtils.getWindowName;
 import static android.server.wm.StateLogger.logAlways;
@@ -538,8 +535,9 @@
         // Check visibility of activity and window.
         assertEquals("Activity=" + getActivityName(activityName) + " must" + (visible ? "" : " NOT")
                 + " be visible.", visible, isActivityVisible(activityName));
-        assertEquals("Window=" + windowName + " must" + (visible ? "" : " NOT") + " be visible.",
-                visible, isWindowVisible(windowName));
+        assertEquals("Window=" + windowName + " must" + (visible ? "" : " NOT")
+                        + " have shown surface.",
+                visible, isWindowSurfaceShown(windowName));
     }
 
     void assertHomeActivityVisible(boolean visible) {
@@ -609,7 +607,7 @@
 
     public void assertWindowDisplayed(final String windowName) {
         waitForValidState(WaitForValidActivityState.forWindow(windowName));
-        assertTrue(windowName + "is visible", isWindowVisible(windowName));
+        assertTrue(windowName + "is visible", isWindowSurfaceShown(windowName));
     }
 
     void waitAndAssertImeWindowShownOnDisplay(int displayId) {
@@ -617,10 +615,11 @@
                 condition -> condition
                         .setResultSupplier(this::getImeWindowState)
                         .setResultValidator(
-                                w -> w != null && w.isShown() && w.getDisplayId() == displayId));
+                                w -> w != null && w.isSurfaceShown()
+                                        && w.getDisplayId() == displayId));
 
         assertNotNull("IME window must exist", imeWinState);
-        assertTrue("IME window must be shown", imeWinState.isShown());
+        assertTrue("IME window must be shown", imeWinState.isSurfaceShown());
         assertEquals("IME window must be on the given display", displayId,
                 imeWinState.getDisplayId());
     }
diff --git a/tests/inputmethod/AndroidManifest.xml b/tests/inputmethod/AndroidManifest.xml
index 2626d5a..3c754de 100644
--- a/tests/inputmethod/AndroidManifest.xml
+++ b/tests/inputmethod/AndroidManifest.xml
@@ -19,6 +19,7 @@
     package="android.view.inputmethod.cts"
     android:targetSandboxVersion="2">
 
+    <uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW" />
     <application
         android:label="CtsInputMethodTestCases"
         android:multiArch="true"
@@ -61,6 +62,10 @@
             android:exported="false">
         </service>
 
+        <service android:name="android.view.inputmethod.cts.util.WindowFocusHandleService"
+                 android:exported="false">
+        </service>
+
     </application>
 
     <instrumentation
diff --git a/tests/inputmethod/mockime/src/com/android/cts/mockime/MockIme.java b/tests/inputmethod/mockime/src/com/android/cts/mockime/MockIme.java
index 6142b9e..9a73722 100644
--- a/tests/inputmethod/mockime/src/com/android/cts/mockime/MockIme.java
+++ b/tests/inputmethod/mockime/src/com/android/cts/mockime/MockIme.java
@@ -286,6 +286,8 @@
                     case "getDisplayId":
                         return getSystemService(WindowManager.class)
                                 .getDefaultDisplay().getDisplayId();
+                    case "verifyLayoutInflaterContext":
+                        return getLayoutInflater().getContext() == this;
                 }
             }
             return ImeEvent.RETURN_VALUE_UNAVAILABLE;
diff --git a/tests/inputmethod/mockime/src/com/android/cts/mockime/MockImeSession.java b/tests/inputmethod/mockime/src/com/android/cts/mockime/MockImeSession.java
index 5e653c6..a407a28 100644
--- a/tests/inputmethod/mockime/src/com/android/cts/mockime/MockImeSession.java
+++ b/tests/inputmethod/mockime/src/com/android/cts/mockime/MockImeSession.java
@@ -982,4 +982,18 @@
         final Bundle params = new Bundle();
         return callCommandInternal("getDisplayId", params);
     }
+
+    /**
+     * Verifies {@code InputMethodService.getLayoutInflater().getContext()} is equal to
+     * {@code InputMethodService.this}.
+     *
+     * @return {@link ImeCommand} object that can be passed to
+     *         {@link ImeEventStreamTestUtils#expectCommand(ImeEventStream, ImeCommand, long)} to
+     *         wait until this event is handled by {@link MockIme}
+     */
+    @NonNull
+    public ImeCommand verifyLayoutInflaterContext() {
+        final Bundle params = new Bundle();
+        return callCommandInternal("verifyLayoutInflaterContext", params);
+    }
 }
diff --git a/tests/inputmethod/src/android/view/inputmethod/cts/FocusHandlingTest.java b/tests/inputmethod/src/android/view/inputmethod/cts/FocusHandlingTest.java
index 674463e..5a2c8c2 100644
--- a/tests/inputmethod/src/android/view/inputmethod/cts/FocusHandlingTest.java
+++ b/tests/inputmethod/src/android/view/inputmethod/cts/FocusHandlingTest.java
@@ -16,6 +16,8 @@
 
 package android.view.inputmethod.cts;
 
+import static android.view.WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM;
+import static android.view.WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN;
 import static android.view.WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_VISIBLE;
 import static android.view.inputmethod.cts.util.TestUtils.runOnMainSync;
 import static android.widget.PopupWindow.INPUT_METHOD_NOT_NEEDED;
@@ -27,26 +29,35 @@
 import static com.android.cts.mockime.ImeEventStreamTestUtils.notExpectEvent;
 
 import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
 
 import android.app.Instrumentation;
+import android.content.ComponentName;
 import android.content.Context;
+import android.content.Intent;
+import android.content.ServiceConnection;
 import android.os.Build;
 import android.os.IBinder;
 import android.os.Process;
 import android.os.SystemClock;
 import android.text.TextUtils;
 import android.view.View;
+import android.view.ViewTreeObserver;
+import android.view.WindowManager;
 import android.view.inputmethod.EditorInfo;
 import android.view.inputmethod.InputMethodManager;
 import android.view.inputmethod.cts.util.EndToEndImeTestBase;
 import android.view.inputmethod.cts.util.TestActivity;
 import android.view.inputmethod.cts.util.TestUtils;
+import android.view.inputmethod.cts.util.WindowFocusHandleService;
 import android.view.inputmethod.cts.util.WindowFocusStealer;
 import android.widget.EditText;
 import android.widget.LinearLayout;
 import android.widget.PopupWindow;
 import android.widget.TextView;
 
+import androidx.annotation.NonNull;
 import androidx.test.InstrumentationRegistry;
 import androidx.test.filters.FlakyTest;
 import androidx.test.filters.MediumTest;
@@ -63,6 +74,8 @@
 import org.junit.runner.RunWith;
 
 import java.util.concurrent.TimeUnit;
+import java.util.concurrent.TimeoutException;
+import java.util.concurrent.atomic.AtomicBoolean;
 import java.util.concurrent.atomic.AtomicReference;
 
 @MediumTest
@@ -92,6 +105,18 @@
         return editTextRef.get();
     }
 
+    public EditText launchTestActivity(String marker,
+            @NonNull AtomicBoolean outEditHasWindowFocusRef) {
+        final EditText editText = launchTestActivity(marker);
+        editText.post(() -> {
+            final ViewTreeObserver observerForEditText = editText.getViewTreeObserver();
+            observerForEditText.addOnWindowFocusChangeListener((hasFocus) ->
+                outEditHasWindowFocusRef.set(editText.hasWindowFocus()));
+            outEditHasWindowFocusRef.set(editText.hasWindowFocus());
+        });
+        return editText;
+    }
+
     private static String getTestMarker() {
         return TEST_MARKER_PREFIX + "/"  + SystemClock.elapsedRealtimeNanos();
     }
@@ -417,4 +442,153 @@
                     NOT_EXPECT_TIMEOUT);
         }
     }
+
+    @Test
+    public void testMultiWindowFocusHandleOnDifferentUiThread() throws Exception {
+        final Instrumentation instrumentation = InstrumentationRegistry.getInstrumentation();
+        try (ServiceSession session = new ServiceSession(instrumentation.getContext());
+             MockImeSession imeSession = MockImeSession.create(
+                     instrumentation.getContext(), instrumentation.getUiAutomation(),
+                     new ImeSettings.Builder())) {
+            final ImeEventStream stream = imeSession.openEventStream();
+            final AtomicBoolean popupTextHasWindowFocus = new AtomicBoolean(false);
+            final AtomicBoolean popupTextHasViewFocus = new AtomicBoolean(false);
+            final AtomicBoolean editTextHasWindowFocus = new AtomicBoolean(false);
+
+            // Start a TestActivity and verify the edit text will receive focus and keyboard shown.
+            final String marker = getTestMarker();
+            final EditText editText = launchTestActivity(marker, editTextHasWindowFocus);
+
+            // Wait until the MockIme gets bound to the TestActivity.
+            expectBindInput(stream, Process.myPid(), TIMEOUT);
+
+            // Emulate tap event
+            CtsTouchUtils.emulateTapOnViewCenter(instrumentation, null, editText);
+            TestUtils.waitOnMainUntil(() -> editTextHasWindowFocus.get(), TIMEOUT);
+
+            expectEvent(stream, editorMatcher("onStartInput", marker), TIMEOUT);
+            expectEvent(stream, event -> "showSoftInput".equals(event.getEventName()), TIMEOUT);
+
+            // Create a popupTextView which from Service with different UI thread.
+            final TextView popupTextView = session.getService().getPopupTextView(
+                    popupTextHasWindowFocus);
+            assertTrue(popupTextView.getHandler().getLooper()
+                    != session.getService().getMainLooper());
+
+            // Verify popupTextView will also receive window focus change and soft keyboard shown
+            // after tapping the view.
+            final String marker1 = getTestMarker();
+            popupTextView.post(() -> {
+                popupTextView.setPrivateImeOptions(marker1);
+                popupTextHasViewFocus.set(popupTextView.requestFocus());
+            });
+            TestUtils.waitOnMainUntil(() -> popupTextHasViewFocus.get(), TIMEOUT);
+
+            CtsTouchUtils.emulateTapOnViewCenter(instrumentation, null, popupTextView);
+            TestUtils.waitOnMainUntil(() -> popupTextHasWindowFocus.get()
+                            && !editTextHasWindowFocus.get(), TIMEOUT);
+            expectEvent(stream, editorMatcher("onStartInput", marker1), TIMEOUT);
+            expectEvent(stream, event -> "showSoftInput".equals(event.getEventName()), TIMEOUT);
+
+            // Emulate tap event for editText again, verify soft keyboard and window focus will
+            // come back.
+            CtsTouchUtils.emulateTapOnViewCenter(instrumentation, null, editText);
+            TestUtils.waitOnMainUntil(() -> editTextHasWindowFocus.get()
+                    && !popupTextHasWindowFocus.get(), TIMEOUT);
+            expectEvent(stream, editorMatcher("onStartInput", marker), TIMEOUT);
+            expectEvent(stream, event -> "showSoftInput".equals(event.getEventName()), TIMEOUT);
+        }
+    }
+
+    @Test
+    public void testKeyboardStateAfterImeFocusableFlagChanged() throws Exception {
+        final Instrumentation instrumentation = InstrumentationRegistry.getInstrumentation();
+        try (MockImeSession imeSession = MockImeSession.create(
+                     instrumentation.getContext(), instrumentation.getUiAutomation(),
+                     new ImeSettings.Builder())) {
+            final ImeEventStream stream = imeSession.openEventStream();
+            final AtomicReference<EditText> editTextRef = new AtomicReference<>();
+            final String marker = getTestMarker();
+            final TestActivity testActivity = TestActivity.startSync(activity-> {
+                // Initially set activity window to not IME focusable.
+                activity.getWindow().addFlags(FLAG_ALT_FOCUSABLE_IM);
+
+                final LinearLayout layout = new LinearLayout(activity);
+                layout.setOrientation(LinearLayout.VERTICAL);
+
+                final EditText editText = new EditText(activity);
+                editText.setPrivateImeOptions(marker);
+                editText.setHint("editText");
+                editTextRef.set(editText);
+                editText.requestFocus();
+
+                layout.addView(editText);
+                return layout;
+            });
+            // Wait until the MockIme gets bound to the TestActivity.
+            expectBindInput(stream, Process.myPid(), TIMEOUT);
+
+            // Emulate tap event, expect there is no "onStartInput", and "showSoftInput" happened.
+            final EditText editText = editTextRef.get();
+            CtsTouchUtils.emulateTapOnViewCenter(instrumentation, null, editText);
+            notExpectEvent(stream, editorMatcher("onStartInput", marker), NOT_EXPECT_TIMEOUT);
+            notExpectEvent(stream, event -> "showSoftInput".equals(event.getEventName()),
+                    NOT_EXPECT_TIMEOUT);
+
+            // Set testActivity window to be IME focusable.
+            testActivity.getWindow().getDecorView().post(() -> {
+                final WindowManager.LayoutParams params = testActivity.getWindow().getAttributes();
+                testActivity.getWindow().clearFlags(FLAG_ALT_FOCUSABLE_IM);
+                editTextRef.get().requestFocus();
+            });
+
+            // Make sure test activity's window has changed to be IME focusable.
+            TestUtils.waitOnMainUntil(() -> WindowManager.LayoutParams.mayUseInputMethod(
+                    testActivity.getWindow().getAttributes().flags), TIMEOUT);
+
+            // Emulate tap event again.
+            CtsTouchUtils.emulateTapOnViewCenter(instrumentation, null, editText);
+            assertTrue(TestUtils.getOnMainSync(() -> editText.hasFocus()
+                    && editText.hasWindowFocus()));
+
+            // "onStartInput", and "showSoftInput" must happen when editText became IME focusable.
+            expectEvent(stream, editorMatcher("onStartInput", marker), TIMEOUT);
+            expectEvent(stream, event -> "showSoftInput".equals(event.getEventName()), TIMEOUT);
+        }
+    }
+
+    private static class ServiceSession implements ServiceConnection, AutoCloseable {
+        private final Context mContext;
+
+        ServiceSession(Context context) {
+            mContext = context;
+            Intent service = new Intent(mContext, WindowFocusHandleService.class);
+            mContext.bindService(service, this, Context.BIND_AUTO_CREATE);
+
+            // Wait for service bound.
+            try {
+                TestUtils.waitOnMainUntil(() -> WindowFocusHandleService.getInstance() != null, 5,
+                        "WindowFocusHandleService should be bound");
+            } catch (TimeoutException e) {
+                fail("WindowFocusHandleService should be bound");
+            }
+        }
+
+        @Override
+        public void close() throws Exception {
+            mContext.unbindService(this);
+        }
+
+        WindowFocusHandleService getService() {
+            return WindowFocusHandleService.getInstance();
+        }
+
+        @Override
+        public void onServiceConnected(ComponentName name, IBinder service) {
+        }
+
+        @Override
+        public void onServiceDisconnected(ComponentName name) {
+        }
+    }
 }
diff --git a/tests/inputmethod/src/android/view/inputmethod/cts/InlineSuggestionsRequestTest.java b/tests/inputmethod/src/android/view/inputmethod/cts/InlineSuggestionsRequestTest.java
index d8db007..429aee0 100644
--- a/tests/inputmethod/src/android/view/inputmethod/cts/InlineSuggestionsRequestTest.java
+++ b/tests/inputmethod/src/android/view/inputmethod/cts/InlineSuggestionsRequestTest.java
@@ -20,6 +20,7 @@
 
 import static org.testng.Assert.assertThrows;
 
+import android.os.LocaleList;
 import android.os.Parcel;
 import android.util.Size;
 import android.view.inline.InlinePresentationSpec;
@@ -32,7 +33,6 @@
 import org.junit.runner.RunWith;
 
 import java.util.ArrayList;
-import android.os.LocaleList;
 
 @SmallTest
 @RunWith(AndroidJUnit4.class)
@@ -58,6 +58,23 @@
     }
 
     @Test
+    public void testEmptyPresentationSpecsThrowsException() {
+        assertThrows(IllegalStateException.class,
+                () -> new InlineSuggestionsRequest.Builder(new ArrayList<>())
+                        .setMaxSuggestionCount(1).build());
+    }
+
+    @Test
+    public void testZeroMaxSuggestionCountThrowsException() {
+        ArrayList<InlinePresentationSpec> presentationSpecs = new ArrayList<>();
+        presentationSpecs.add(new InlinePresentationSpec.Builder(new Size(100, 100),
+                new Size(400, 100)).build());
+        assertThrows(IllegalStateException.class,
+                () -> new InlineSuggestionsRequest.Builder(presentationSpecs)
+                        .setMaxSuggestionCount(0).build());
+    }
+
+    @Test
     public void testInlineSuggestionsRequestValues() {
         final int suggestionCount = 3;
         ArrayList<InlinePresentationSpec> presentationSpecs = new ArrayList<>();
@@ -81,6 +98,8 @@
     @Test
     public void testInlineSuggestionsRequestParcelizeDeparcelize() {
         ArrayList<InlinePresentationSpec> presentationSpecs = new ArrayList<>();
+        presentationSpecs.add(
+                new InlinePresentationSpec.Builder(new Size(100, 100), new Size(400, 400)).build());
         InlineSuggestionsRequest request =
                 new InlineSuggestionsRequest.Builder(presentationSpecs).build();
         Parcel p = Parcel.obtain();
diff --git a/tests/inputmethod/src/android/view/inputmethod/cts/InputMethodServiceTest.java b/tests/inputmethod/src/android/view/inputmethod/cts/InputMethodServiceTest.java
index 0b20b85..1a2561a 100644
--- a/tests/inputmethod/src/android/view/inputmethod/cts/InputMethodServiceTest.java
+++ b/tests/inputmethod/src/android/view/inputmethod/cts/InputMethodServiceTest.java
@@ -116,6 +116,24 @@
         });
     }
 
+    @Test
+    public void verifyLayoutInflaterContext() throws Exception {
+        try (MockImeSession imeSession = MockImeSession.create(
+                InstrumentationRegistry.getContext(),
+                InstrumentationRegistry.getInstrumentation().getUiAutomation(),
+                new ImeSettings.Builder())) {
+            final ImeEventStream stream = imeSession.openEventStream();
+
+            createTestActivity(SOFT_INPUT_STATE_ALWAYS_VISIBLE);
+            expectEvent(stream, event -> "onStartInputView".equals(event.getEventName()), TIMEOUT);
+
+            final ImeCommand command = imeSession.verifyLayoutInflaterContext();
+            assertTrue("InputMethodService.getLayoutInflater().getContext() must be equal to"
+                    + " InputMethodService.this",
+                    expectCommand(stream, command, TIMEOUT).getReturnBooleanValue());
+        }
+    }
+
     private void verifyImeConsumesBackButton(int backDisposition) throws Exception {
         try (MockImeSession imeSession = MockImeSession.create(
                 InstrumentationRegistry.getContext(),
diff --git a/tests/inputmethod/src/android/view/inputmethod/cts/SearchViewTest.java b/tests/inputmethod/src/android/view/inputmethod/cts/SearchViewTest.java
index 5cf8fd0..2b327f5 100644
--- a/tests/inputmethod/src/android/view/inputmethod/cts/SearchViewTest.java
+++ b/tests/inputmethod/src/android/view/inputmethod/cts/SearchViewTest.java
@@ -19,15 +19,20 @@
 import static com.android.cts.mockime.ImeEventStreamTestUtils.EventFilterMode.CHECK_EXIT_EVENT_ONLY;
 import static com.android.cts.mockime.ImeEventStreamTestUtils.expectBindInput;
 import static com.android.cts.mockime.ImeEventStreamTestUtils.expectEvent;
+import static com.android.cts.mockime.ImeEventStreamTestUtils.notExpectEvent;
 
 import android.os.Process;
 import android.text.InputType;
+import android.view.View;
+import android.view.ViewGroup;
 import android.view.inputmethod.EditorInfo;
 import android.view.inputmethod.InputMethodManager;
 import android.view.inputmethod.cts.util.EndToEndImeTestBase;
 import android.view.inputmethod.cts.util.TestActivity;
+import android.widget.BaseAdapter;
 import android.widget.EditText;
 import android.widget.LinearLayout;
+import android.widget.ListView;
 import android.widget.SearchView;
 
 import androidx.test.InstrumentationRegistry;
@@ -49,6 +54,7 @@
 @RunWith(AndroidJUnit4.class)
 public class SearchViewTest extends EndToEndImeTestBase {
     static final long TIMEOUT = TimeUnit.SECONDS.toMillis(5);
+    static final long NOT_EXPECT_TIMEOUT = TimeUnit.SECONDS.toMillis(2);
 
     public SearchView launchTestActivity(boolean requestFocus) {
         final AtomicReference<SearchView> searchViewRef = new AtomicReference<>();
@@ -77,6 +83,32 @@
         return searchViewRef.get();
     }
 
+    private SearchView launchTestActivityWithListView(boolean requestFocus) {
+        final AtomicReference<SearchView> searchViewRef = new AtomicReference<>();
+        TestActivity.startSync(activity -> {
+            final LinearLayout layout = new LinearLayout(activity);
+            layout.setOrientation(LinearLayout.VERTICAL);
+
+            final ListView listView = new ListView(activity);
+            layout.addView(listView);
+
+            final SearchView searchView = new SearchView(activity);
+            searchViewRef.set(searchView);
+            listView.setAdapter(new SingleItemAdapter(searchView));
+
+            searchView.setQueryHint("hint");
+            searchView.setIconifiedByDefault(false);
+            searchView.setInputType(InputType.TYPE_TEXT_FLAG_CAP_SENTENCES);
+            searchView.setImeOptions(EditorInfo.IME_ACTION_DONE);
+            if (requestFocus) {
+                searchView.requestFocus();
+            }
+
+            return layout;
+        });
+        return searchViewRef.get();
+    }
+
     @Test
     public void testTapThenSetQuery() throws Exception {
         try (MockImeSession imeSession = MockImeSession.create(
@@ -132,4 +164,60 @@
                     CHECK_EXIT_EVENT_ONLY, TIMEOUT);
         }
     }
+
+    @Test
+    public void testShowImeWhenSearchViewFocusInListView() throws Exception {
+        try (MockImeSession imeSession = MockImeSession.create(
+                InstrumentationRegistry.getContext(),
+                InstrumentationRegistry.getInstrumentation().getUiAutomation(),
+                new ImeSettings.Builder())) {
+            final ImeEventStream stream = imeSession.openEventStream();
+
+            final SearchView searchView = launchTestActivityWithListView(true /* requestFocus */);
+
+            // Emulate tap event on SearchView
+            CtsTouchUtils.emulateTapOnViewCenter(
+                    InstrumentationRegistry.getInstrumentation(), null, searchView);
+
+            // Expect input to bind since EditText is focused.
+            expectBindInput(stream, Process.myPid(), TIMEOUT);
+
+            // Wait until "showSoftInput" gets called with a real InputConnection
+            expectEvent(stream, event ->
+                            "showSoftInput".equals(event.getEventName())
+                                    && !event.getExitState().hasDummyInputConnection(),
+                    CHECK_EXIT_EVENT_ONLY, TIMEOUT);
+
+            notExpectEvent(stream, event -> "hideSoftInput".equals(event.getEventName()),
+                    NOT_EXPECT_TIMEOUT);
+        }
+    }
+
+    static final class SingleItemAdapter extends BaseAdapter {
+        private final SearchView mSearchView;
+
+        SingleItemAdapter(SearchView searchView) {
+            mSearchView = searchView;
+        }
+
+        @Override
+        public int getCount() {
+            return 1;
+        }
+
+        @Override
+        public Object getItem(int i) {
+            return mSearchView;
+        }
+
+        @Override
+        public long getItemId(int i) {
+            return 0;
+        }
+
+        @Override
+        public View getView(int i, View view, ViewGroup viewGroup) {
+            return mSearchView;
+        }
+    }
 }
diff --git a/tests/inputmethod/src/android/view/inputmethod/cts/util/WindowFocusHandleService.java b/tests/inputmethod/src/android/view/inputmethod/cts/util/WindowFocusHandleService.java
new file mode 100644
index 0000000..427cf11
--- /dev/null
+++ b/tests/inputmethod/src/android/view/inputmethod/cts/util/WindowFocusHandleService.java
@@ -0,0 +1,173 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.view.inputmethod.cts.util;
+
+import static android.view.Display.DEFAULT_DISPLAY;
+import static android.view.WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN;
+import static android.view.WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE;
+import static android.view.WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL;
+import static android.view.WindowManager.LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH;
+import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY;
+
+import static androidx.test.platform.app.InstrumentationRegistry.getInstrumentation;
+
+import android.app.Service;
+import android.content.Context;
+import android.content.Intent;
+import android.graphics.Color;
+import android.graphics.PixelFormat;
+import android.graphics.Point;
+import android.graphics.drawable.ColorDrawable;
+import android.hardware.display.DisplayManager;
+import android.os.Binder;
+import android.os.Handler;
+import android.os.HandlerThread;
+import android.os.IBinder;
+import android.util.Log;
+import android.view.Display;
+import android.view.MotionEvent;
+import android.view.ViewTreeObserver;
+import android.view.WindowManager;
+import android.widget.EditText;
+
+import androidx.annotation.AnyThread;
+import androidx.annotation.MainThread;
+import androidx.annotation.Nullable;
+import androidx.annotation.UiThread;
+
+import java.util.concurrent.atomic.AtomicBoolean;
+
+/**
+ * A Service class to create popup window with edit text by handler thread.
+ * For verifying IME focus handle between windows on different UI thread.
+ */
+public class WindowFocusHandleService extends Service {
+    private @Nullable static WindowFocusHandleService sInstance = null;
+    private static final String TAG = WindowFocusHandleService.class.getSimpleName();
+
+    private EditText mPopupTextView;
+    private Handler mThreadHandler;
+
+    @Override
+    public void onCreate() {
+        super.onCreate();
+        // Create a popup text view with different UI thread.
+        final HandlerThread localThread = new HandlerThread("TestThreadHandler");
+        localThread.start();
+        mThreadHandler = new Handler(localThread.getLooper());
+        mThreadHandler.post(() -> mPopupTextView = createPopupTextView(new Point(150, 150)));
+    }
+
+    public @Nullable static WindowFocusHandleService getInstance() {
+        return sInstance;
+    }
+
+    @Override
+    public IBinder onBind(Intent intent) {
+        sInstance = this;
+        return new Binder();
+    }
+
+    @Override
+    public boolean onUnbind(Intent intent) {
+        sInstance = null;
+        return true;
+    }
+
+    @UiThread
+    private EditText createPopupTextView(Point pos) {
+        final Context windowContext = createWindowContext(DEFAULT_DISPLAY);
+        final WindowManager wm = windowContext.getSystemService(WindowManager.class);
+        final EditText editText = new EditText(windowContext) {
+            @Override
+            public void onWindowFocusChanged(boolean hasWindowFocus) {
+                if (Log.isLoggable(TAG, Log.VERBOSE)) {
+                    Log.v(TAG,"onWindowFocusChanged for view=" + this
+                            + ", hasWindowfocus: " + hasWindowFocus);
+                }
+            }
+        };
+        editText.setOnFocusChangeListener((v, hasFocus) -> {
+            if (v == editText) {
+                WindowManager.LayoutParams params =
+                        (WindowManager.LayoutParams) editText.getLayoutParams();
+                if (hasFocus) {
+                    params.flags &= ~FLAG_NOT_FOCUSABLE;
+                    params.flags |= FLAG_LAYOUT_IN_SCREEN
+                                    | FLAG_WATCH_OUTSIDE_TOUCH
+                                    | FLAG_NOT_TOUCH_MODAL;
+                    wm.updateViewLayout(editText, params);
+                }
+            }
+        });
+        editText.setOnTouchListener((v, event) -> {
+            if (event.getAction() == MotionEvent.ACTION_OUTSIDE) {
+                WindowManager.LayoutParams params =
+                        (WindowManager.LayoutParams) editText.getLayoutParams();
+                if ((params.flags & FLAG_NOT_FOCUSABLE) == 0) {
+                    params.flags |= FLAG_NOT_FOCUSABLE;
+                    wm.updateViewLayout(editText, params);
+                }
+            }
+            return false;
+        });
+        editText.setText("Popup");
+        editText.setBackground(new ColorDrawable(Color.CYAN));
+
+        WindowManager.LayoutParams params = new WindowManager.LayoutParams(
+                150, 150, pos.x, pos.y,
+                TYPE_APPLICATION_OVERLAY, FLAG_NOT_FOCUSABLE,
+                PixelFormat.OPAQUE);
+        wm.addView(editText, params);
+        return editText;
+    }
+
+    private Context createWindowContext(int displayId) {
+        final Display display = getSystemService(DisplayManager.class).getDisplay(displayId);
+        return createDisplayContext(display).createWindowContext(TYPE_APPLICATION_OVERLAY,
+                null /* options */);
+    }
+
+    @AnyThread
+    public EditText getPopupTextView(@Nullable AtomicBoolean outPopupTextHasWindowFocusRef) {
+        if (outPopupTextHasWindowFocusRef != null) {
+            mPopupTextView.post(() -> {
+                final ViewTreeObserver observerForPopupTextView =
+                        mPopupTextView.getViewTreeObserver();
+                observerForPopupTextView.addOnWindowFocusChangeListener((hasFocus) ->
+                        outPopupTextHasWindowFocusRef.set(hasFocus));
+            });
+        }
+        return mPopupTextView;
+    }
+
+    @MainThread
+    public void handleReset() {
+        if (mPopupTextView != null) {
+            final WindowManager wm = mPopupTextView.getContext().getSystemService(
+                    WindowManager.class);
+            wm.removeView(mPopupTextView);
+            mPopupTextView = null;
+        }
+    }
+
+    @MainThread
+    public void onDestroy() {
+        super.onDestroy();
+        handleReset();
+    }
+}
diff --git a/tests/libcore/okhttp/Android.bp b/tests/libcore/okhttp/Android.bp
index 511e28a..00360f1 100644
--- a/tests/libcore/okhttp/Android.bp
+++ b/tests/libcore/okhttp/Android.bp
@@ -16,6 +16,7 @@
     name: "CtsLibcoreOkHttpTestCases",
     defaults: ["cts_support_defaults"],
     platform_apis: true,
+    min_sdk_version: "29",
     static_libs: [
         "bouncycastle-unbundled",
         "cts-core-test-runner-axt",
diff --git a/tests/libcore/okhttp/AndroidManifest.xml b/tests/libcore/okhttp/AndroidManifest.xml
index 5396d8e..1e6718c 100644
--- a/tests/libcore/okhttp/AndroidManifest.xml
+++ b/tests/libcore/okhttp/AndroidManifest.xml
@@ -17,6 +17,7 @@
 
 <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="android.libcore.cts.okhttp">
     <uses-permission android:name="android.permission.INTERNET" />
+    <uses-sdk android:minSdkVersion="29" android:targetSdkVersion="29" />
     <application android:usesCleartextTraffic="true">
         <uses-library android:name="android.test.runner" />
     </application>
diff --git a/tests/media/src/android/mediav2/cts/MuxerUnitTest.java b/tests/media/src/android/mediav2/cts/MuxerUnitTest.java
index 6942393..b648ca2 100644
--- a/tests/media/src/android/mediav2/cts/MuxerUnitTest.java
+++ b/tests/media/src/android/mediav2/cts/MuxerUnitTest.java
@@ -259,7 +259,6 @@
         }
 
         @Test
-        @Ignore("TODO(b/146423844)")
         public void testIfAddTrackSucceedsAfterStart() throws IOException {
             MediaMuxer muxer = new MediaMuxer(mOutLoc, MediaMuxer.OutputFormat.MUXER_OUTPUT_MPEG_4);
             try {
@@ -356,7 +355,6 @@
         }
 
         @Test
-        @Ignore("TODO(b/146423844)")
         public void testIdempotentStart() throws IOException {
             MediaMuxer muxer = new MediaMuxer(mOutLoc, MediaMuxer.OutputFormat.MUXER_OUTPUT_MPEG_4);
             MediaFormat format = new MediaFormat();
@@ -491,7 +489,6 @@
         }
 
         @Test
-        @Ignore("TODO(b/146423844)")
         public void testSimpleStartStopMuxer() throws IOException {
             MediaMuxer muxer = new MediaMuxer(mOutLoc, MediaMuxer.OutputFormat.MUXER_OUTPUT_MPEG_4);
             MediaFormat format = new MediaFormat();
@@ -877,7 +874,6 @@
         }
 
         @Test
-        @Ignore("TODO(b/146423844)")
         public void testSimpleStartStopMuxer() {
             assertTrue(nativeTestSimpleStartStop(mOutLoc));
         }
diff --git a/tests/tests/app.usage/src/android/app/usage/cts/UsageStatsTest.java b/tests/tests/app.usage/src/android/app/usage/cts/UsageStatsTest.java
index 0ca1fc9..0d834cd 100644
--- a/tests/tests/app.usage/src/android/app/usage/cts/UsageStatsTest.java
+++ b/tests/tests/app.usage/src/android/app/usage/cts/UsageStatsTest.java
@@ -687,6 +687,8 @@
                 mUsageStatsManager.getAppStandbyBucket(mTargetPackage));
     }
 
+    // TODO(148887416): get this test to work for instant apps
+    @AppModeFull(reason = "Test APK Activity not found when installed as an instant app")
     @Test
     public void testIsAppInactive_Charging() throws Exception {
         setStandByBucket(TEST_APP_PKG, "rare");
diff --git a/tests/tests/appenumeration/AndroidTest.xml b/tests/tests/appenumeration/AndroidTest.xml
index d5ad14c..8db021f 100644
--- a/tests/tests/appenumeration/AndroidTest.xml
+++ b/tests/tests/appenumeration/AndroidTest.xml
@@ -32,6 +32,7 @@
         <option name="test-file-name" value="CtsAppEnumerationSharedUidSource.apk" />
         <option name="test-file-name" value="CtsAppEnumerationSharedUidTarget.apk" />
         <option name="test-file-name" value="CtsAppEnumerationQueriesNothing.apk" />
+        <option name="test-file-name" value="CtsAppEnumerationWildcardActionSource.apk" />
         <option name="test-file-name" value="CtsAppEnumerationQueriesActivityViaAction.apk" />
         <option name="test-file-name" value="CtsAppEnumerationQueriesServiceViaAction.apk" />
         <option name="test-file-name" value="CtsAppEnumerationQueriesProviderViaAuthority.apk" />
diff --git a/tests/tests/appenumeration/app/source/Android.bp b/tests/tests/appenumeration/app/source/Android.bp
index 01d26fa..f215e77 100644
--- a/tests/tests/appenumeration/app/source/Android.bp
+++ b/tests/tests/appenumeration/app/source/Android.bp
@@ -149,4 +149,16 @@
         "vts",
         "general-tests",
     ],
+}
+
+android_test_helper_app {
+    name: "CtsAppEnumerationWildcardActionSource",
+    manifest: "AndroidManifest-queriesWildcardAction.xml",
+    defaults: ["CtsAppEnumerationQueriesDefaults"],
+    // Tag this module as a cts test artifact
+    test_suites: [
+        "cts",
+        "vts",
+        "general-tests",
+    ],
 }
\ No newline at end of file
diff --git a/tests/tests/appop/AppWithLongFeatureId/AndroidManifest.xml b/tests/tests/appenumeration/app/source/AndroidManifest-queriesWildcardAction.xml
similarity index 65%
copy from tests/tests/appop/AppWithLongFeatureId/AndroidManifest.xml
copy to tests/tests/appenumeration/app/source/AndroidManifest-queriesWildcardAction.xml
index 17d10e9..ffd8848 100644
--- a/tests/tests/appop/AppWithLongFeatureId/AndroidManifest.xml
+++ b/tests/tests/appenumeration/app/source/AndroidManifest-queriesWildcardAction.xml
@@ -1,5 +1,4 @@
 <?xml version="1.0" encoding="utf-8"?>
-
 <!--
   ~ Copyright (C) 2020 The Android Open Source Project
   ~
@@ -17,9 +16,15 @@
   -->
 
 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
-    package="android.app.appops.cts.appwithlongfeatureId">
-  <feature android:featureId="1xxxx_xxxx2xxxx_xxxx3xxxx_xxxx4xxxx_xxxx5xxxx_xxxxB" android:label="@string/dummyLabel" />
-
-  <application />
-
+    package="android.appenumeration.queries.wildcard.action">
+    <queries>
+        <intent>
+            <action android:name="*" />
+        </intent>
+    </queries>
+    <application>
+        <uses-library android:name="android.test.runner" />
+        <activity android:name="android.appenumeration.cts.query.TestActivity"
+                  android:exported="true" />
+    </application>
 </manifest>
diff --git a/tests/tests/appenumeration/app/source/src/android/appenumeration/cts/query/TestActivity.java b/tests/tests/appenumeration/app/source/src/android/appenumeration/cts/query/TestActivity.java
index 01aef3c..7a680f3 100644
--- a/tests/tests/appenumeration/app/source/src/android/appenumeration/cts/query/TestActivity.java
+++ b/tests/tests/appenumeration/app/source/src/android/appenumeration/cts/query/TestActivity.java
@@ -24,15 +24,18 @@
 import static android.appenumeration.cts.Constants.ACTION_SEND_RESULT;
 import static android.appenumeration.cts.Constants.ACTION_START_DIRECTLY;
 import static android.appenumeration.cts.Constants.ACTION_START_FOR_RESULT;
+import static android.appenumeration.cts.Constants.ACTION_START_SENDER_FOR_RESULT;
 import static android.appenumeration.cts.Constants.EXTRA_ERROR;
 import static android.appenumeration.cts.Constants.EXTRA_FLAGS;
 import static android.appenumeration.cts.Constants.EXTRA_REMOTE_CALLBACK;
 import static android.content.Intent.EXTRA_RETURN_RESULT;
 
 import android.app.Activity;
+import android.app.PendingIntent;
 import android.content.ActivityNotFoundException;
 import android.content.ComponentName;
 import android.content.Intent;
+import android.content.IntentSender;
 import android.content.pm.PackageInfo;
 import android.content.pm.PackageManager;
 import android.os.Bundle;
@@ -92,6 +95,16 @@
                 finish();
             } else if (ACTION_GET_INSTALLED_PACKAGES.equals(action)) {
                 sendGetInstalledPackages(remoteCallback, queryIntent.getIntExtra(EXTRA_FLAGS, 0));
+            } else if (ACTION_START_SENDER_FOR_RESULT.equals(action)) {
+                PendingIntent pendingIntent = intent.getParcelableExtra("pendingIntent");
+                int requestCode = RESULT_FIRST_USER + callbacks.size();
+                callbacks.put(requestCode, remoteCallback);
+                try {
+                    startIntentSenderForResult(pendingIntent.getIntentSender(), requestCode, null,
+                            0, 0, 0);
+                } catch (IntentSender.SendIntentException e) {
+                    sendError(remoteCallback, e);
+                }
             } else {
                 sendError(remoteCallback, new Exception("unknown action " + action));
             }
diff --git a/tests/tests/appenumeration/lib/src/android/appenumeration/cts/Constants.java b/tests/tests/appenumeration/lib/src/android/appenumeration/cts/Constants.java
index 3c80da6..1afcc65 100644
--- a/tests/tests/appenumeration/lib/src/android/appenumeration/cts/Constants.java
+++ b/tests/tests/appenumeration/lib/src/android/appenumeration/cts/Constants.java
@@ -44,7 +44,9 @@
     public static final String QUERIES_NOTHING = PKG_BASE + "queries.nothing";
     /** A package that queries nothing, but is part of a shared user */
     public static final String QUERIES_NOTHING_SHARED_USER = PKG_BASE + "queries.nothing.shareduid";
-    /** A package that exposes nothing, but is part of a shared user */
+    /** A package that queries via wildcard action. */
+    public static final String QUERIES_WILDCARD_ACTION = PKG_BASE + "queries.wildcard.action";
+    /** A package that queries for {@link #TARGET_NO_API} package */
     public static final String TARGET_SHARED_USER = PKG_BASE + "noapi.shareduid";
     /** A package that exposes itself via various intent filters (activities, services, etc.) */
     public static final String TARGET_FILTERS = PKG_BASE + "filters";
@@ -63,7 +65,8 @@
             QUERIES_UNEXPORTED_SERVICE_ACTION,
             QUERIES_UNEXPORTED_PROVIDER_AUTH,
             QUERIES_PACKAGE,
-            QUERIES_NOTHING_SHARED_USER
+            QUERIES_NOTHING_SHARED_USER,
+            QUERIES_WILDCARD_ACTION
     };
 
     public static final String ACTIVITY_CLASS_TEST = PKG_BASE + "cts.query.TestActivity";
@@ -84,8 +87,11 @@
             PKG_BASE + "cts.action.QUERY_INTENT_PROVIDERS";
     public static final String ACTION_GET_INSTALLED_PACKAGES =
             PKG_BASE + "cts.action.GET_INSTALLED_PACKAGES";
+    public static final String ACTION_START_SENDER_FOR_RESULT =
+            PKG_BASE + "cts.action.START_SENDER_FOR_RESULT";
 
     public static final String EXTRA_REMOTE_CALLBACK = "remoteCallback";
     public static final String EXTRA_ERROR = "error";
     public static final String EXTRA_FLAGS = "flags";
+
 }
diff --git a/tests/tests/appenumeration/src/android/appenumeration/cts/AppEnumerationTests.java b/tests/tests/appenumeration/src/android/appenumeration/cts/AppEnumerationTests.java
index 9beffff..3f624ee 100644
--- a/tests/tests/appenumeration/src/android/appenumeration/cts/AppEnumerationTests.java
+++ b/tests/tests/appenumeration/src/android/appenumeration/cts/AppEnumerationTests.java
@@ -43,6 +43,7 @@
 import static android.appenumeration.cts.Constants.QUERIES_UNEXPORTED_ACTIVITY_ACTION;
 import static android.appenumeration.cts.Constants.QUERIES_UNEXPORTED_PROVIDER_AUTH;
 import static android.appenumeration.cts.Constants.QUERIES_UNEXPORTED_SERVICE_ACTION;
+import static android.appenumeration.cts.Constants.QUERIES_WILDCARD_ACTION;
 import static android.appenumeration.cts.Constants.TARGET_FILTERS;
 import static android.appenumeration.cts.Constants.TARGET_FORCEQUERYABLE;
 import static android.appenumeration.cts.Constants.TARGET_NO_API;
@@ -55,6 +56,7 @@
 import static org.junit.Assert.assertThat;
 import static org.junit.Assert.fail;
 
+import android.app.PendingIntent;
 import android.content.ActivityNotFoundException;
 import android.content.ComponentName;
 import android.content.Intent;
@@ -66,6 +68,7 @@
 import android.os.ConditionVariable;
 import android.os.Handler;
 import android.os.HandlerThread;
+import android.os.Parcelable;
 import android.os.RemoteCallback;
 
 import androidx.annotation.Nullable;
@@ -92,7 +95,6 @@
 
 @RunWith(AndroidJUnit4.class)
 public class AppEnumerationTests {
-
     private static Handler sResponseHandler;
     private static HandlerThread sResponseThread;
 
@@ -254,6 +256,11 @@
     }
 
     @Test
+    public void queriesWildcardAction_canSeeTargets() throws Exception {
+        assertVisible(QUERIES_WILDCARD_ACTION, TARGET_FILTERS);
+    }
+
+    @Test
     public void queriesProviderAuthority_canSeeTarget() throws Exception {
         assertVisible(QUERIES_PROVIDER_AUTH, TARGET_FILTERS);
     }
@@ -292,6 +299,21 @@
     }
 
     @Test
+    public void whenStartedViaIntentSender_canSeeCaller() throws Exception {
+        // let's first make sure that the target cannot see the caller.
+        assertNotVisible(QUERIES_NOTHING, QUERIES_NOTHING_Q);
+        // now let's start the target via pending intent and make sure that it can see the caller
+        // as part of that call
+        PackageInfo packageInfo = startSenderForResult(QUERIES_NOTHING_Q, QUERIES_NOTHING);
+        assertThat(packageInfo, IsNull.notNullValue());
+        assertThat(packageInfo.packageName, is(QUERIES_NOTHING_Q));
+        // and finally let's re-run the last check to make sure that the target can still see the
+        // caller
+        assertVisible(QUERIES_NOTHING, QUERIES_NOTHING_Q);
+    }
+
+
+    @Test
     public void sharedUserMember_canSeeOtherMember() throws Exception {
         assertVisible(QUERIES_NOTHING_SHARED_USER, TARGET_SHARED_USER);
     }
@@ -335,7 +357,7 @@
         }
     }
 
-    interface ThrowingBiFunction<T,U,R> {
+    interface ThrowingBiFunction<T, U, R> {
         R apply(T arg1, U arg2) throws Exception;
     }
 
@@ -352,6 +374,7 @@
             }
         }
     }
+
     private void assertQueryable(String sourcePackageName, String targetPackageName,
             String intentAction, ThrowingBiFunction<String, Intent, String[]> commandMethod)
             throws Exception {
@@ -381,9 +404,25 @@
         return response.getParcelable(Intent.EXTRA_RETURN_RESULT);
     }
 
+    private PackageInfo startSenderForResult(String sourcePackageName, String targetPackageName)
+            throws Exception {
+        PendingIntent pendingIntent = PendingIntent.getActivity(
+                InstrumentationRegistry.getInstrumentation().getContext(), 100,
+                new Intent("android.appenumeration.cts.action.SEND_RESULT").setComponent(
+                        new ComponentName(targetPackageName,
+                                "android.appenumeration.cts.query.TestActivity")),
+                PendingIntent.FLAG_ONE_SHOT);
+
+        Bundle response = sendCommand(sourcePackageName, targetPackageName,
+                pendingIntent /*queryIntent*/, Constants.ACTION_START_SENDER_FOR_RESULT);
+        return response.getParcelable(Intent.EXTRA_RETURN_RESULT);
+    }
+
+
     private String[] queryIntentActivities(String sourcePackageName, Intent queryIntent)
             throws Exception {
-        Bundle response = sendCommand(sourcePackageName, null, queryIntent, ACTION_QUERY_ACTIVITIES);
+        Bundle response =
+                sendCommand(sourcePackageName, null, queryIntent, ACTION_QUERY_ACTIVITIES);
         return response.getStringArray(Intent.EXTRA_RETURN_RESULT);
     }
 
@@ -418,21 +457,23 @@
     }
 
     private Bundle sendCommand(String sourcePackageName, @Nullable String targetPackageName,
-            @Nullable Intent queryIntent, String action)
+            @Nullable Parcelable intentExtra, String action)
             throws Exception {
         final Intent intent = new Intent(action)
                 .setComponent(new ComponentName(sourcePackageName, ACTIVITY_CLASS_TEST))
                 // data uri unique to each activity start to ensure actual launch and not just
                 // redisplay
-                .setData(Uri.parse("test://" + name.getMethodName()
-                      + (targetPackageName != null
-                      ? targetPackageName : UUID.randomUUID().toString())))
+                .setData(Uri.parse("test://" + UUID.randomUUID().toString()))
                 .addFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_NEW_DOCUMENT);
         if (targetPackageName != null) {
             intent.putExtra(Intent.EXTRA_PACKAGE_NAME, targetPackageName);
         }
-        if (queryIntent != null) {
-            intent.putExtra(Intent.EXTRA_INTENT, queryIntent);
+        if (intentExtra != null) {
+            if (intentExtra instanceof Intent) {
+                intent.putExtra(Intent.EXTRA_INTENT, intentExtra);
+            } else if (intentExtra instanceof PendingIntent) {
+                intent.putExtra("pendingIntent", intentExtra);
+            }
         }
 
         final ConditionVariable latch = new ConditionVariable();
diff --git a/tests/tests/appop/AndroidManifest.xml b/tests/tests/appop/AndroidManifest.xml
index ab36586..0c89b6e 100644
--- a/tests/tests/appop/AndroidManifest.xml
+++ b/tests/tests/appop/AndroidManifest.xml
@@ -19,11 +19,11 @@
 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
     package="android.app.appops.cts"
     android:targetSandboxVersion="2">
-  <feature android:featureId="testFeature" android:label="@string/dummyLabel" />
-  <feature android:featureId="firstFeature" android:label="@string/dummyLabel" />
-  <feature android:featureId="secondFeature" android:label="@string/dummyLabel" />
-  <feature android:featureId="firstProxyFeature" android:label="@string/dummyLabel" />
-  <feature android:featureId="secondProxyFeature" android:label="@string/dummyLabel" />
+  <attribution android:tag="testAttribution" android:label="@string/dummyLabel" />
+  <attribution android:tag="firstAttribution" android:label="@string/dummyLabel" />
+  <attribution android:tag="secondAttribution" android:label="@string/dummyLabel" />
+  <attribution android:tag="firstProxyAttribution" android:label="@string/dummyLabel" />
+  <attribution android:tag="secondProxyAttribution" android:label="@string/dummyLabel" />
 
   <uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
   <uses-permission android:name="android.permission.BLUETOOTH_ADMIN" />
diff --git a/tests/tests/appop/AndroidTest.xml b/tests/tests/appop/AndroidTest.xml
index a911b20..386feb4 100644
--- a/tests/tests/appop/AndroidTest.xml
+++ b/tests/tests/appop/AndroidTest.xml
@@ -37,12 +37,12 @@
         <option name="push-file" key="CtsAppToBlame1.apk" value="/data/local/tmp/cts/appops/CtsAppToBlame1.apk" />
         <option name="push-file" key="CtsAppToBlame2.apk" value="/data/local/tmp/cts/appops/CtsAppToBlame2.apk" />
         <option name="push-file" key="CtsAppToCollect.apk" value="/data/local/tmp/cts/appops/CtsAppToCollect.apk" />
-        <option name="push-file" key="AppWithDuplicateFeature.apk" value="/data/local/tmp/cts/appops/AppWithDuplicateFeature.apk" />
-        <option name="push-file" key="AppWithFeatureInheritingFromExisting.apk" value="/data/local/tmp/cts/appops/AppWithFeatureInheritingFromExisting.apk" />
-        <option name="push-file" key="AppWithFeatureInheritingFromSameAsOther.apk" value="/data/local/tmp/cts/appops/AppWithFeatureInheritingFromSameAsOther.apk" />
-        <option name="push-file" key="AppWithFeatureInheritingFromSelf.apk" value="/data/local/tmp/cts/appops/AppWithFeatureInheritingFromSelf.apk" />
-        <option name="push-file" key="AppWithLongFeatureIdFeature.apk" value="/data/local/tmp/cts/appops/AppWithLongFeatureIdFeature.apk" />
-        <option name="push-file" key="AppWithTooManyFeatures.apk" value="/data/local/tmp/cts/appops/AppWithTooManyFeatures.apk" />
+        <option name="push-file" key="AppWithDuplicateAttribution.apk" value="/data/local/tmp/cts/appops/AppWithDuplicateAttribution.apk" />
+        <option name="push-file" key="AppWithAttributionInheritingFromExisting.apk" value="/data/local/tmp/cts/appops/AppWithAttributionInheritingFromExisting.apk" />
+        <option name="push-file" key="AppWithAttributionInheritingFromSameAsOther.apk" value="/data/local/tmp/cts/appops/AppWithAttributionInheritingFromSameAsOther.apk" />
+        <option name="push-file" key="AppWithAttributionInheritingFromSelf.apk" value="/data/local/tmp/cts/appops/AppWithAttributionInheritingFromSelf.apk" />
+        <option name="push-file" key="AppWithLongAttributionTag.apk" value="/data/local/tmp/cts/appops/AppWithLongAttributionTag.apk" />
+        <option name="push-file" key="AppWithTooManyAttributions.apk" value="/data/local/tmp/cts/appops/AppWithTooManyAttributions.apk" />
     </target_preparer>
 
     <!-- Remove additional apps if installed -->
diff --git a/tests/tests/appop/AppThatUsesAppOps/AndroidManifest.xml b/tests/tests/appop/AppThatUsesAppOps/AndroidManifest.xml
index e3e4937..df614d8 100644
--- a/tests/tests/appop/AppThatUsesAppOps/AndroidManifest.xml
+++ b/tests/tests/appop/AppThatUsesAppOps/AndroidManifest.xml
@@ -18,7 +18,7 @@
 
 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
     package="android.app.appops.cts.appthatusesappops">
-  <feature android:featureId="testFeature" android:label="@string/dummyLabel" />
+  <attribution android:tag="testAttribution" android:label="@string/dummyLabel" />
 
   <application>
       <service android:name=".AppOpsUserService" android:exported="true" />
diff --git a/tests/tests/appop/AppThatUsesAppOps/res/values/strings.xml b/tests/tests/appop/AppThatUsesAppOps/res/values/strings.xml
index 2d02f14..37d548d 100644
--- a/tests/tests/appop/AppThatUsesAppOps/res/values/strings.xml
+++ b/tests/tests/appop/AppThatUsesAppOps/res/values/strings.xml
@@ -16,5 +16,5 @@
   -->
 
 <resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="dummyLabel">A feature</string>
+    <string name="dummyLabel">An attribution</string>
 </resources>
diff --git a/tests/tests/appop/AppThatUsesAppOps/src/android/app/appops/cts/appthatusesappops/AppOpsUserService.kt b/tests/tests/appop/AppThatUsesAppOps/src/android/app/appops/cts/appthatusesappops/AppOpsUserService.kt
index 3f55742..ba98da1 100644
--- a/tests/tests/appop/AppThatUsesAppOps/src/android/app/appops/cts/appthatusesappops/AppOpsUserService.kt
+++ b/tests/tests/appop/AppThatUsesAppOps/src/android/app/appops/cts/appthatusesappops/AppOpsUserService.kt
@@ -25,7 +25,7 @@
 import android.app.SyncNotedAppOp
 import android.app.appops.cts.IAppOpsUserClient
 import android.app.appops.cts.IAppOpsUserService
-import android.app.appops.cts.TEST_FEATURE_ID
+import android.app.appops.cts.TEST_ATTRIBUTION_TAG
 import android.app.appops.cts.eventually
 import android.content.Intent
 import android.os.IBinder
@@ -56,8 +56,8 @@
             private val asyncNoted = mutableListOf<AsyncNotedAppOp>()
 
             private fun setNotedAppOpsCollector() {
-                appOpsManager.setNotedAppOpsCollector(
-                        object : AppOpsManager.AppOpsCollector() {
+                appOpsManager.setOnOpNotedCallback(mainExecutor,
+                        object : AppOpsManager.OnOpNotedCallback() {
                             override fun onNoted(op: SyncNotedAppOp) {
                                 noted.add(op to Throwable().stackTrace)
                             }
@@ -73,6 +73,10 @@
             }
 
             init {
+                try {
+                    appOpsManager.setOnOpNotedCallback(null, null)
+                } catch (ignored: IllegalStateException) {
+                }
                 setNotedAppOpsCollector()
             }
 
@@ -94,7 +98,7 @@
                 client: IAppOpsUserClient
             ) {
                 forwardThrowableFrom {
-                    appOpsManager.setNotedAppOpsCollector(null)
+                    appOpsManager.setOnOpNotedCallback(null, null)
 
                     client.noteSyncOp()
 
@@ -114,7 +118,7 @@
                 client: IAppOpsUserClient
             ) {
                 forwardThrowableFrom {
-                    appOpsManager.setNotedAppOpsCollector(null)
+                    appOpsManager.setOnOpNotedCallback(null, null)
 
                     client.noteAsyncOp()
 
@@ -132,7 +136,7 @@
                 forwardThrowableFrom {
                     client.noteSyncOp()
 
-                    assertThat(noted.map { it.first.featureId to it.first.op })
+                    assertThat(noted.map { it.first.attributionTag to it.first.op })
                         .containsExactly(null to OPSTR_COARSE_LOCATION)
                     assertThat(noted[0].second.map { it.methodName })
                         .contains("callApiThatNotesSyncOpAndCheckLog")
@@ -155,11 +159,14 @@
                 }
             }
 
-            override fun callApiThatNotesSyncOpWithFeatureAndCheckLog(client: IAppOpsUserClient) {
+            override fun callApiThatNotesSyncOpWithAttributionAndCheckLog(
+                client: IAppOpsUserClient
+            ) {
                 forwardThrowableFrom {
-                    client.noteSyncOpWithFeature(TEST_FEATURE_ID)
+                    client.noteSyncOpWithAttribution(TEST_ATTRIBUTION_TAG)
 
-                    assertThat(noted.map { it.first.featureId }).containsExactly(TEST_FEATURE_ID)
+                    assertThat(noted.map { it.first.attributionTag })
+                            .containsExactly(TEST_ATTRIBUTION_TAG)
                 }
             }
 
@@ -336,7 +343,7 @@
                     client.noteAsyncOp()
 
                     eventually {
-                        assertThat(asyncNoted.map { it.featureId to it.op })
+                        assertThat(asyncNoted.map { it.attributionTag to it.op })
                             .containsExactly(null to OPSTR_COARSE_LOCATION)
                     }
                     assertThat(noted).isEmpty()
@@ -344,15 +351,15 @@
                 }
             }
 
-            override fun callApiThatNotesAsyncOpWithFeatureAndCheckLog(
+            override fun callApiThatNotesAsyncOpWithAttributionAndCheckLog(
                 client: IAppOpsUserClient
             ) {
                 forwardThrowableFrom {
-                    client.noteAsyncOpWithFeature(TEST_FEATURE_ID)
+                    client.noteAsyncOpWithAttribution(TEST_ATTRIBUTION_TAG)
 
                     eventually {
-                        assertThat(asyncNoted.map { it.featureId })
-                            .containsExactly(TEST_FEATURE_ID)
+                        assertThat(asyncNoted.map { it.attributionTag })
+                            .containsExactly(TEST_ATTRIBUTION_TAG)
                     }
                 }
             }
diff --git a/tests/tests/appop/AppToBlame1/AndroidManifest.xml b/tests/tests/appop/AppToBlame1/AndroidManifest.xml
index 55db16b..a8d3638 100644
--- a/tests/tests/appop/AppToBlame1/AndroidManifest.xml
+++ b/tests/tests/appop/AppToBlame1/AndroidManifest.xml
@@ -19,11 +19,11 @@
 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
     package="android.app.appops.cts.apptoblame"
     android:version="1">
-  <feature android:featureId="feature1" android:label="@string/dummyLabel" />
-  <feature android:featureId="feature2" android:label="@string/dummyLabel" />
-  <feature android:featureId="feature3" android:label="@string/dummyLabel" />
-  <feature android:featureId="feature4" android:label="@string/dummyLabel" />
-  <feature android:featureId="feature5" android:label="@string/dummyLabel" />
+  <attribution android:tag="attribution1" android:label="@string/dummyLabel" />
+  <attribution android:tag="attribution2" android:label="@string/dummyLabel" />
+  <attribution android:tag="attribution3" android:label="@string/dummyLabel" />
+  <attribution android:tag="attribution4" android:label="@string/dummyLabel" />
+  <attribution android:tag="attribution5" android:label="@string/dummyLabel" />
 
   <application />
 
diff --git a/tests/tests/appop/AppToBlame2/AndroidManifest.xml b/tests/tests/appop/AppToBlame2/AndroidManifest.xml
index 96a490c..ba13fd6 100644
--- a/tests/tests/appop/AppToBlame2/AndroidManifest.xml
+++ b/tests/tests/appop/AppToBlame2/AndroidManifest.xml
@@ -19,14 +19,14 @@
 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
     package="android.app.appops.cts.apptoblame"
     android:version="2">
-  <feature android:featureId="feature1" android:label="@string/dummyLabel" />
-  <feature android:featureId="feature6" android:label="@string/dummyLabel">
-    <inherit-from android:featureId="feature2" />
-  </feature>
-  <feature android:featureId="feature7" android:label="@string/dummyLabel">
-    <inherit-from android:featureId="feature4" />
-    <inherit-from android:featureId="feature5" />
-  </feature>
+  <attribution android:tag="attribution1" android:label="@string/dummyLabel" />
+  <attribution android:tag="attribution6" android:label="@string/dummyLabel">
+    <inherit-from android:tag="attribution2" />
+  </attribution>
+  <attribution android:tag="attribution7" android:label="@string/dummyLabel">
+    <inherit-from android:tag="attribution4" />
+    <inherit-from android:tag="attribution5" />
+  </attribution>
 
   <application />
 
diff --git a/tests/tests/appop/AppToCollect/AndroidManifest.xml b/tests/tests/appop/AppToCollect/AndroidManifest.xml
index e67cb57..2a0d18d 100644
--- a/tests/tests/appop/AppToCollect/AndroidManifest.xml
+++ b/tests/tests/appop/AppToCollect/AndroidManifest.xml
@@ -19,7 +19,7 @@
 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
     package="android.app.appops.cts.apptocollect"
     android:version="1">
-  <feature android:featureId="testFeature" android:label="@string/dummyLabel" />
+  <attribution android:tag="testAttribution" android:label="@string/dummyLabel" />
 
   <uses-permission android:name="android.permission.READ_CONTACTS"></uses-permission>
 
diff --git a/tests/tests/appop/AppWithDuplicateFeature/Android.bp b/tests/tests/appop/AppWithAttributionInheritingFromExisting/Android.bp
similarity index 92%
copy from tests/tests/appop/AppWithDuplicateFeature/Android.bp
copy to tests/tests/appop/AppWithAttributionInheritingFromExisting/Android.bp
index a27dacb..2b07c3b 100644
--- a/tests/tests/appop/AppWithDuplicateFeature/Android.bp
+++ b/tests/tests/appop/AppWithAttributionInheritingFromExisting/Android.bp
@@ -13,7 +13,7 @@
 // limitations under the License.
 
 android_test_helper_app {
-    name: "AppWithDuplicateFeature",
+    name: "AppWithAttributionInheritingFromExisting",
 
     test_suites: [
         "cts",
diff --git a/tests/tests/appop/AppWithFeatureInheritingFromExisting/AndroidManifest.xml b/tests/tests/appop/AppWithAttributionInheritingFromExisting/AndroidManifest.xml
similarity index 72%
rename from tests/tests/appop/AppWithFeatureInheritingFromExisting/AndroidManifest.xml
rename to tests/tests/appop/AppWithAttributionInheritingFromExisting/AndroidManifest.xml
index eb097ef..6b1798b 100644
--- a/tests/tests/appop/AppWithFeatureInheritingFromExisting/AndroidManifest.xml
+++ b/tests/tests/appop/AppWithAttributionInheritingFromExisting/AndroidManifest.xml
@@ -17,11 +17,11 @@
   -->
 
 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
-    package="android.app.appops.cts.appwithfeatureinheritingfromexisting">
-  <feature android:featureId="feature1" android:label="@string/dummyLabel" />
-  <feature android:featureId="feature2" android:label="@string/dummyLabel">
-      <inherit-from android:featureId="feature1" />
-  </feature>
+    package="android.app.appops.cts.appwithattributioninheritingfromexisting">
+  <attribution android:tag="attribution" android:label="@string/dummyLabel" />
+  <attribution android:tag="attribution2" android:label="@string/dummyLabel">
+      <inherit-from android:tag="attribution" />
+  </attribution>
 
   <application />
 
diff --git a/tests/tests/appop/AppWithFeatureInheritingFromExisting/res/values/strings.xml b/tests/tests/appop/AppWithAttributionInheritingFromExisting/res/values/strings.xml
similarity index 100%
rename from tests/tests/appop/AppWithFeatureInheritingFromExisting/res/values/strings.xml
rename to tests/tests/appop/AppWithAttributionInheritingFromExisting/res/values/strings.xml
diff --git a/tests/tests/appop/AppWithDuplicateFeature/Android.bp b/tests/tests/appop/AppWithAttributionInheritingFromSameAsOther/Android.bp
similarity index 92%
copy from tests/tests/appop/AppWithDuplicateFeature/Android.bp
copy to tests/tests/appop/AppWithAttributionInheritingFromSameAsOther/Android.bp
index a27dacb..7de79e5 100644
--- a/tests/tests/appop/AppWithDuplicateFeature/Android.bp
+++ b/tests/tests/appop/AppWithAttributionInheritingFromSameAsOther/Android.bp
@@ -13,7 +13,7 @@
 // limitations under the License.
 
 android_test_helper_app {
-    name: "AppWithDuplicateFeature",
+    name: "AppWithAttributionInheritingFromSameAsOther",
 
     test_suites: [
         "cts",
diff --git a/tests/tests/appop/AppWithDuplicateFeature/AndroidManifest.xml b/tests/tests/appop/AppWithAttributionInheritingFromSameAsOther/AndroidManifest.xml
similarity index 67%
copy from tests/tests/appop/AppWithDuplicateFeature/AndroidManifest.xml
copy to tests/tests/appop/AppWithAttributionInheritingFromSameAsOther/AndroidManifest.xml
index b7b5297..fcf47a5 100644
--- a/tests/tests/appop/AppWithDuplicateFeature/AndroidManifest.xml
+++ b/tests/tests/appop/AppWithAttributionInheritingFromSameAsOther/AndroidManifest.xml
@@ -17,9 +17,13 @@
   -->
 
 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
-    package="android.app.appops.cts.appwithduplicatefeature">
-  <feature android:featureId="feature1" android:label="@string/dummyLabel" />
-  <feature android:featureId="feature1" android:label="@string/dummyLabel" />
+    package="android.app.appops.cts.appwithattributioninheritingfromsameasother">
+  <attribution android:tag="attribution1" android:label="@string/dummyLabel">
+      <inherit-from android:tag="attribution3" />
+  </attribution>
+  <attribution android:tag="attribution2" android:label="@string/dummyLabel">
+      <inherit-from android:tag="attribution3" />
+  </attribution>
 
   <application />
 
diff --git a/tests/tests/appop/AppWithFeatureInheritingFromSameAsOther/res/values/strings.xml b/tests/tests/appop/AppWithAttributionInheritingFromSameAsOther/res/values/strings.xml
similarity index 100%
rename from tests/tests/appop/AppWithFeatureInheritingFromSameAsOther/res/values/strings.xml
rename to tests/tests/appop/AppWithAttributionInheritingFromSameAsOther/res/values/strings.xml
diff --git a/tests/tests/appop/AppWithDuplicateFeature/Android.bp b/tests/tests/appop/AppWithAttributionInheritingFromSelf/Android.bp
similarity index 93%
copy from tests/tests/appop/AppWithDuplicateFeature/Android.bp
copy to tests/tests/appop/AppWithAttributionInheritingFromSelf/Android.bp
index a27dacb..4a6e524 100644
--- a/tests/tests/appop/AppWithDuplicateFeature/Android.bp
+++ b/tests/tests/appop/AppWithAttributionInheritingFromSelf/Android.bp
@@ -13,7 +13,7 @@
 // limitations under the License.
 
 android_test_helper_app {
-    name: "AppWithDuplicateFeature",
+    name: "AppWithAttributionInheritingFromSelf",
 
     test_suites: [
         "cts",
diff --git a/tests/tests/appop/AppWithDuplicateFeature/AndroidManifest.xml b/tests/tests/appop/AppWithAttributionInheritingFromSelf/AndroidManifest.xml
similarity index 77%
copy from tests/tests/appop/AppWithDuplicateFeature/AndroidManifest.xml
copy to tests/tests/appop/AppWithAttributionInheritingFromSelf/AndroidManifest.xml
index b7b5297..3cb4712 100644
--- a/tests/tests/appop/AppWithDuplicateFeature/AndroidManifest.xml
+++ b/tests/tests/appop/AppWithAttributionInheritingFromSelf/AndroidManifest.xml
@@ -17,9 +17,10 @@
   -->
 
 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
-    package="android.app.appops.cts.appwithduplicatefeature">
-  <feature android:featureId="feature1" android:label="@string/dummyLabel" />
-  <feature android:featureId="feature1" android:label="@string/dummyLabel" />
+    package="android.app.appops.cts.appwithattributioninheritingfromself">
+  <attribution android:tag="attribution1" android:label="@string/dummyLabel">
+      <inherit-from android:tag="attribution1" />
+  </attribution>
 
   <application />
 
diff --git a/tests/tests/appop/AppWithFeatureInheritingFromSelf/res/values/strings.xml b/tests/tests/appop/AppWithAttributionInheritingFromSelf/res/values/strings.xml
similarity index 100%
rename from tests/tests/appop/AppWithFeatureInheritingFromSelf/res/values/strings.xml
rename to tests/tests/appop/AppWithAttributionInheritingFromSelf/res/values/strings.xml
diff --git a/tests/tests/appop/AppWithDuplicateFeature/Android.bp b/tests/tests/appop/AppWithDuplicateAttribution/Android.bp
similarity index 94%
rename from tests/tests/appop/AppWithDuplicateFeature/Android.bp
rename to tests/tests/appop/AppWithDuplicateAttribution/Android.bp
index a27dacb..a4b1272 100644
--- a/tests/tests/appop/AppWithDuplicateFeature/Android.bp
+++ b/tests/tests/appop/AppWithDuplicateAttribution/Android.bp
@@ -13,7 +13,7 @@
 // limitations under the License.
 
 android_test_helper_app {
-    name: "AppWithDuplicateFeature",
+    name: "AppWithDuplicateAttribution",
 
     test_suites: [
         "cts",
diff --git a/tests/tests/appop/AppWithDuplicateFeature/AndroidManifest.xml b/tests/tests/appop/AppWithDuplicateAttribution/AndroidManifest.xml
similarity index 77%
rename from tests/tests/appop/AppWithDuplicateFeature/AndroidManifest.xml
rename to tests/tests/appop/AppWithDuplicateAttribution/AndroidManifest.xml
index b7b5297..55b0ddb 100644
--- a/tests/tests/appop/AppWithDuplicateFeature/AndroidManifest.xml
+++ b/tests/tests/appop/AppWithDuplicateAttribution/AndroidManifest.xml
@@ -17,9 +17,9 @@
   -->
 
 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
-    package="android.app.appops.cts.appwithduplicatefeature">
-  <feature android:featureId="feature1" android:label="@string/dummyLabel" />
-  <feature android:featureId="feature1" android:label="@string/dummyLabel" />
+    package="android.app.appops.cts.appwithduplicateattribution">
+  <attribution android:tag="attribution1" android:label="@string/dummyLabel" />
+  <attribution android:tag="attribution1" android:label="@string/dummyLabel" />
 
   <application />
 
diff --git a/tests/tests/appop/AppWithDuplicateFeature/res/values/strings.xml b/tests/tests/appop/AppWithDuplicateAttribution/res/values/strings.xml
similarity index 100%
rename from tests/tests/appop/AppWithDuplicateFeature/res/values/strings.xml
rename to tests/tests/appop/AppWithDuplicateAttribution/res/values/strings.xml
diff --git a/tests/tests/appop/AppWithFeatureInheritingFromExisting/Android.bp b/tests/tests/appop/AppWithFeatureInheritingFromExisting/Android.bp
deleted file mode 100644
index fd498d7..0000000
--- a/tests/tests/appop/AppWithFeatureInheritingFromExisting/Android.bp
+++ /dev/null
@@ -1,23 +0,0 @@
-// Copyright (C) 2019 The Android Open Source Project
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-android_test_helper_app {
-    name: "AppWithFeatureInheritingFromExisting",
-
-    test_suites: [
-        "cts",
-        "vts",
-        "general-tests",
-    ]
-}
\ No newline at end of file
diff --git a/tests/tests/appop/AppWithFeatureInheritingFromSameAsOther/Android.bp b/tests/tests/appop/AppWithFeatureInheritingFromSameAsOther/Android.bp
deleted file mode 100644
index d358ae34..0000000
--- a/tests/tests/appop/AppWithFeatureInheritingFromSameAsOther/Android.bp
+++ /dev/null
@@ -1,23 +0,0 @@
-// Copyright (C) 2019 The Android Open Source Project
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-android_test_helper_app {
-    name: "AppWithFeatureInheritingFromSameAsOther",
-
-    test_suites: [
-        "cts",
-        "vts",
-        "general-tests",
-    ]
-}
\ No newline at end of file
diff --git a/tests/tests/appop/AppWithFeatureInheritingFromSameAsOther/AndroidManifest.xml b/tests/tests/appop/AppWithFeatureInheritingFromSameAsOther/AndroidManifest.xml
deleted file mode 100644
index 5af9edc..0000000
--- a/tests/tests/appop/AppWithFeatureInheritingFromSameAsOther/AndroidManifest.xml
+++ /dev/null
@@ -1,30 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-
-<!--
-  ~ Copyright (C) 2019 The Android Open Source Project
-  ~
-  ~ Licensed under the Apache License, Version 2.0 (the "License");
-  ~ you may not use this file except in compliance with the License.
-  ~ You may obtain a copy of the License at
-  ~
-  ~      http://www.apache.org/licenses/LICENSE-2.0
-  ~
-  ~ Unless required by applicable law or agreed to in writing, software
-  ~ distributed under the License is distributed on an "AS IS" BASIS,
-  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-  ~ See the License for the specific language governing permissions and
-  ~ limitations under the License.
-  -->
-
-<manifest xmlns:android="http://schemas.android.com/apk/res/android"
-    package="android.app.appops.cts.appwithfeatureinheritingfromsameasother">
-  <feature android:featureId="feature1" android:label="@string/dummyLabel">
-      <inherit-from android:featureId="feature3" />
-  </feature>
-  <feature android:featureId="feature2" android:label="@string/dummyLabel">
-      <inherit-from android:featureId="feature3" />
-  </feature>
-
-  <application />
-
-</manifest>
diff --git a/tests/tests/appop/AppWithFeatureInheritingFromSelf/Android.bp b/tests/tests/appop/AppWithFeatureInheritingFromSelf/Android.bp
deleted file mode 100644
index 4c47869..0000000
--- a/tests/tests/appop/AppWithFeatureInheritingFromSelf/Android.bp
+++ /dev/null
@@ -1,23 +0,0 @@
-// Copyright (C) 2019 The Android Open Source Project
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-android_test_helper_app {
-    name: "AppWithFeatureInheritingFromSelf",
-
-    test_suites: [
-        "cts",
-        "vts",
-        "general-tests",
-    ]
-}
\ No newline at end of file
diff --git a/tests/tests/appop/AppWithFeatureInheritingFromSelf/AndroidManifest.xml b/tests/tests/appop/AppWithFeatureInheritingFromSelf/AndroidManifest.xml
deleted file mode 100644
index ff7e198..0000000
--- a/tests/tests/appop/AppWithFeatureInheritingFromSelf/AndroidManifest.xml
+++ /dev/null
@@ -1,27 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-
-<!--
-  ~ Copyright (C) 2019 The Android Open Source Project
-  ~
-  ~ Licensed under the Apache License, Version 2.0 (the "License");
-  ~ you may not use this file except in compliance with the License.
-  ~ You may obtain a copy of the License at
-  ~
-  ~      http://www.apache.org/licenses/LICENSE-2.0
-  ~
-  ~ Unless required by applicable law or agreed to in writing, software
-  ~ distributed under the License is distributed on an "AS IS" BASIS,
-  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-  ~ See the License for the specific language governing permissions and
-  ~ limitations under the License.
-  -->
-
-<manifest xmlns:android="http://schemas.android.com/apk/res/android"
-    package="android.app.appops.cts.appwithfeatureinheritingfromself">
-  <feature android:featureId="feature1" android:label="@string/dummyLabel">
-      <inherit-from android:featureId="feature1" />
-  </feature>
-
-  <application />
-
-</manifest>
diff --git a/tests/tests/appop/AppWithLongFeatureId/Android.bp b/tests/tests/appop/AppWithLongAttributionTag/Android.bp
similarity index 94%
copy from tests/tests/appop/AppWithLongFeatureId/Android.bp
copy to tests/tests/appop/AppWithLongAttributionTag/Android.bp
index e0034f0..5ee3f02 100644
--- a/tests/tests/appop/AppWithLongFeatureId/Android.bp
+++ b/tests/tests/appop/AppWithLongAttributionTag/Android.bp
@@ -13,7 +13,7 @@
 // limitations under the License.
 
 android_test_helper_app {
-    name: "AppWithLongFeatureIdFeature",
+    name: "AppWithLongAttributionTag",
 
     test_suites: [
         "cts",
diff --git a/tests/tests/appop/AppWithLongFeatureId/AndroidManifest.xml b/tests/tests/appop/AppWithLongAttributionTag/AndroidManifest.xml
similarity index 80%
rename from tests/tests/appop/AppWithLongFeatureId/AndroidManifest.xml
rename to tests/tests/appop/AppWithLongAttributionTag/AndroidManifest.xml
index 17d10e9..e08a32d 100644
--- a/tests/tests/appop/AppWithLongFeatureId/AndroidManifest.xml
+++ b/tests/tests/appop/AppWithLongAttributionTag/AndroidManifest.xml
@@ -17,8 +17,8 @@
   -->
 
 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
-    package="android.app.appops.cts.appwithlongfeatureId">
-  <feature android:featureId="1xxxx_xxxx2xxxx_xxxx3xxxx_xxxx4xxxx_xxxx5xxxx_xxxxB" android:label="@string/dummyLabel" />
+    package="android.app.appops.cts.appwithlongattributiontag">
+  <attribution android:tag="1xxxx_xxxx2xxxx_xxxx3xxxx_xxxx4xxxx_xxxx5xxxx_xxxxB" android:label="@string/dummyLabel" />
 
   <application />
 
diff --git a/tests/tests/appop/AppWithLongFeatureId/res/values/strings.xml b/tests/tests/appop/AppWithLongAttributionTag/res/values/strings.xml
similarity index 100%
rename from tests/tests/appop/AppWithLongFeatureId/res/values/strings.xml
rename to tests/tests/appop/AppWithLongAttributionTag/res/values/strings.xml
diff --git a/tests/tests/appop/AppWithLongFeatureId/Android.bp b/tests/tests/appop/AppWithTooManyAttributions/Android.bp
similarity index 94%
rename from tests/tests/appop/AppWithLongFeatureId/Android.bp
rename to tests/tests/appop/AppWithTooManyAttributions/Android.bp
index e0034f0..80b1bd3 100644
--- a/tests/tests/appop/AppWithLongFeatureId/Android.bp
+++ b/tests/tests/appop/AppWithTooManyAttributions/Android.bp
@@ -13,7 +13,7 @@
 // limitations under the License.
 
 android_test_helper_app {
-    name: "AppWithLongFeatureIdFeature",
+    name: "AppWithTooManyAttributions",
 
     test_suites: [
         "cts",
diff --git a/tests/tests/appop/AppWithTooManyAttributions/AndroidManifest.xml b/tests/tests/appop/AppWithTooManyAttributions/AndroidManifest.xml
new file mode 100644
index 0000000..debdb8e
--- /dev/null
+++ b/tests/tests/appop/AppWithTooManyAttributions/AndroidManifest.xml
@@ -0,0 +1,1028 @@
+<?xml version="1.0" encoding="utf-8"?>
+
+<!--
+  ~ Copyright (C) 2020 The Android Open Source Project
+  ~
+  ~ Licensed under the Apache License, Version 2.0 (the "License");
+  ~ you may not use this file except in compliance with the License.
+  ~ You may obtain a copy of the License at
+  ~
+  ~      http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing, software
+  ~ distributed under the License is distributed on an "AS IS" BASIS,
+  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  ~ See the License for the specific language governing permissions and
+  ~ limitations under the License.
+  -->
+
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+    package="android.app.appops.cts.appwithtoomanyattributions">
+
+  <!-- 1000 attributions are allowed -->
+  <attribution android:tag="f0" android:label="@string/dummyLabel" />
+  <attribution android:tag="f1" android:label="@string/dummyLabel" />
+  <attribution android:tag="f2" android:label="@string/dummyLabel" />
+  <attribution android:tag="f3" android:label="@string/dummyLabel" />
+  <attribution android:tag="f4" android:label="@string/dummyLabel" />
+  <attribution android:tag="f5" android:label="@string/dummyLabel" />
+  <attribution android:tag="f6" android:label="@string/dummyLabel" />
+  <attribution android:tag="f7" android:label="@string/dummyLabel" />
+  <attribution android:tag="f8" android:label="@string/dummyLabel" />
+  <attribution android:tag="f9" android:label="@string/dummyLabel" />
+  <attribution android:tag="f10" android:label="@string/dummyLabel" />
+  <attribution android:tag="f11" android:label="@string/dummyLabel" />
+  <attribution android:tag="f12" android:label="@string/dummyLabel" />
+  <attribution android:tag="f13" android:label="@string/dummyLabel" />
+  <attribution android:tag="f14" android:label="@string/dummyLabel" />
+  <attribution android:tag="f15" android:label="@string/dummyLabel" />
+  <attribution android:tag="f16" android:label="@string/dummyLabel" />
+  <attribution android:tag="f17" android:label="@string/dummyLabel" />
+  <attribution android:tag="f18" android:label="@string/dummyLabel" />
+  <attribution android:tag="f19" android:label="@string/dummyLabel" />
+  <attribution android:tag="f20" android:label="@string/dummyLabel" />
+  <attribution android:tag="f21" android:label="@string/dummyLabel" />
+  <attribution android:tag="f22" android:label="@string/dummyLabel" />
+  <attribution android:tag="f23" android:label="@string/dummyLabel" />
+  <attribution android:tag="f24" android:label="@string/dummyLabel" />
+  <attribution android:tag="f25" android:label="@string/dummyLabel" />
+  <attribution android:tag="f26" android:label="@string/dummyLabel" />
+  <attribution android:tag="f27" android:label="@string/dummyLabel" />
+  <attribution android:tag="f28" android:label="@string/dummyLabel" />
+  <attribution android:tag="f29" android:label="@string/dummyLabel" />
+  <attribution android:tag="f30" android:label="@string/dummyLabel" />
+  <attribution android:tag="f31" android:label="@string/dummyLabel" />
+  <attribution android:tag="f32" android:label="@string/dummyLabel" />
+  <attribution android:tag="f33" android:label="@string/dummyLabel" />
+  <attribution android:tag="f34" android:label="@string/dummyLabel" />
+  <attribution android:tag="f35" android:label="@string/dummyLabel" />
+  <attribution android:tag="f36" android:label="@string/dummyLabel" />
+  <attribution android:tag="f37" android:label="@string/dummyLabel" />
+  <attribution android:tag="f38" android:label="@string/dummyLabel" />
+  <attribution android:tag="f39" android:label="@string/dummyLabel" />
+  <attribution android:tag="f40" android:label="@string/dummyLabel" />
+  <attribution android:tag="f41" android:label="@string/dummyLabel" />
+  <attribution android:tag="f42" android:label="@string/dummyLabel" />
+  <attribution android:tag="f43" android:label="@string/dummyLabel" />
+  <attribution android:tag="f44" android:label="@string/dummyLabel" />
+  <attribution android:tag="f45" android:label="@string/dummyLabel" />
+  <attribution android:tag="f46" android:label="@string/dummyLabel" />
+  <attribution android:tag="f47" android:label="@string/dummyLabel" />
+  <attribution android:tag="f48" android:label="@string/dummyLabel" />
+  <attribution android:tag="f49" android:label="@string/dummyLabel" />
+  <attribution android:tag="f50" android:label="@string/dummyLabel" />
+  <attribution android:tag="f51" android:label="@string/dummyLabel" />
+  <attribution android:tag="f52" android:label="@string/dummyLabel" />
+  <attribution android:tag="f53" android:label="@string/dummyLabel" />
+  <attribution android:tag="f54" android:label="@string/dummyLabel" />
+  <attribution android:tag="f55" android:label="@string/dummyLabel" />
+  <attribution android:tag="f56" android:label="@string/dummyLabel" />
+  <attribution android:tag="f57" android:label="@string/dummyLabel" />
+  <attribution android:tag="f58" android:label="@string/dummyLabel" />
+  <attribution android:tag="f59" android:label="@string/dummyLabel" />
+  <attribution android:tag="f60" android:label="@string/dummyLabel" />
+  <attribution android:tag="f61" android:label="@string/dummyLabel" />
+  <attribution android:tag="f62" android:label="@string/dummyLabel" />
+  <attribution android:tag="f63" android:label="@string/dummyLabel" />
+  <attribution android:tag="f64" android:label="@string/dummyLabel" />
+  <attribution android:tag="f65" android:label="@string/dummyLabel" />
+  <attribution android:tag="f66" android:label="@string/dummyLabel" />
+  <attribution android:tag="f67" android:label="@string/dummyLabel" />
+  <attribution android:tag="f68" android:label="@string/dummyLabel" />
+  <attribution android:tag="f69" android:label="@string/dummyLabel" />
+  <attribution android:tag="f70" android:label="@string/dummyLabel" />
+  <attribution android:tag="f71" android:label="@string/dummyLabel" />
+  <attribution android:tag="f72" android:label="@string/dummyLabel" />
+  <attribution android:tag="f73" android:label="@string/dummyLabel" />
+  <attribution android:tag="f74" android:label="@string/dummyLabel" />
+  <attribution android:tag="f75" android:label="@string/dummyLabel" />
+  <attribution android:tag="f76" android:label="@string/dummyLabel" />
+  <attribution android:tag="f77" android:label="@string/dummyLabel" />
+  <attribution android:tag="f78" android:label="@string/dummyLabel" />
+  <attribution android:tag="f79" android:label="@string/dummyLabel" />
+  <attribution android:tag="f80" android:label="@string/dummyLabel" />
+  <attribution android:tag="f81" android:label="@string/dummyLabel" />
+  <attribution android:tag="f82" android:label="@string/dummyLabel" />
+  <attribution android:tag="f83" android:label="@string/dummyLabel" />
+  <attribution android:tag="f84" android:label="@string/dummyLabel" />
+  <attribution android:tag="f85" android:label="@string/dummyLabel" />
+  <attribution android:tag="f86" android:label="@string/dummyLabel" />
+  <attribution android:tag="f87" android:label="@string/dummyLabel" />
+  <attribution android:tag="f88" android:label="@string/dummyLabel" />
+  <attribution android:tag="f89" android:label="@string/dummyLabel" />
+  <attribution android:tag="f90" android:label="@string/dummyLabel" />
+  <attribution android:tag="f91" android:label="@string/dummyLabel" />
+  <attribution android:tag="f92" android:label="@string/dummyLabel" />
+  <attribution android:tag="f93" android:label="@string/dummyLabel" />
+  <attribution android:tag="f94" android:label="@string/dummyLabel" />
+  <attribution android:tag="f95" android:label="@string/dummyLabel" />
+  <attribution android:tag="f96" android:label="@string/dummyLabel" />
+  <attribution android:tag="f97" android:label="@string/dummyLabel" />
+  <attribution android:tag="f98" android:label="@string/dummyLabel" />
+  <attribution android:tag="f99" android:label="@string/dummyLabel" />
+  <attribution android:tag="f100" android:label="@string/dummyLabel" />
+  <attribution android:tag="f101" android:label="@string/dummyLabel" />
+  <attribution android:tag="f102" android:label="@string/dummyLabel" />
+  <attribution android:tag="f103" android:label="@string/dummyLabel" />
+  <attribution android:tag="f104" android:label="@string/dummyLabel" />
+  <attribution android:tag="f105" android:label="@string/dummyLabel" />
+  <attribution android:tag="f106" android:label="@string/dummyLabel" />
+  <attribution android:tag="f107" android:label="@string/dummyLabel" />
+  <attribution android:tag="f108" android:label="@string/dummyLabel" />
+  <attribution android:tag="f109" android:label="@string/dummyLabel" />
+  <attribution android:tag="f110" android:label="@string/dummyLabel" />
+  <attribution android:tag="f111" android:label="@string/dummyLabel" />
+  <attribution android:tag="f112" android:label="@string/dummyLabel" />
+  <attribution android:tag="f113" android:label="@string/dummyLabel" />
+  <attribution android:tag="f114" android:label="@string/dummyLabel" />
+  <attribution android:tag="f115" android:label="@string/dummyLabel" />
+  <attribution android:tag="f116" android:label="@string/dummyLabel" />
+  <attribution android:tag="f117" android:label="@string/dummyLabel" />
+  <attribution android:tag="f118" android:label="@string/dummyLabel" />
+  <attribution android:tag="f119" android:label="@string/dummyLabel" />
+  <attribution android:tag="f120" android:label="@string/dummyLabel" />
+  <attribution android:tag="f121" android:label="@string/dummyLabel" />
+  <attribution android:tag="f122" android:label="@string/dummyLabel" />
+  <attribution android:tag="f123" android:label="@string/dummyLabel" />
+  <attribution android:tag="f124" android:label="@string/dummyLabel" />
+  <attribution android:tag="f125" android:label="@string/dummyLabel" />
+  <attribution android:tag="f126" android:label="@string/dummyLabel" />
+  <attribution android:tag="f127" android:label="@string/dummyLabel" />
+  <attribution android:tag="f128" android:label="@string/dummyLabel" />
+  <attribution android:tag="f129" android:label="@string/dummyLabel" />
+  <attribution android:tag="f130" android:label="@string/dummyLabel" />
+  <attribution android:tag="f131" android:label="@string/dummyLabel" />
+  <attribution android:tag="f132" android:label="@string/dummyLabel" />
+  <attribution android:tag="f133" android:label="@string/dummyLabel" />
+  <attribution android:tag="f134" android:label="@string/dummyLabel" />
+  <attribution android:tag="f135" android:label="@string/dummyLabel" />
+  <attribution android:tag="f136" android:label="@string/dummyLabel" />
+  <attribution android:tag="f137" android:label="@string/dummyLabel" />
+  <attribution android:tag="f138" android:label="@string/dummyLabel" />
+  <attribution android:tag="f139" android:label="@string/dummyLabel" />
+  <attribution android:tag="f140" android:label="@string/dummyLabel" />
+  <attribution android:tag="f141" android:label="@string/dummyLabel" />
+  <attribution android:tag="f142" android:label="@string/dummyLabel" />
+  <attribution android:tag="f143" android:label="@string/dummyLabel" />
+  <attribution android:tag="f144" android:label="@string/dummyLabel" />
+  <attribution android:tag="f145" android:label="@string/dummyLabel" />
+  <attribution android:tag="f146" android:label="@string/dummyLabel" />
+  <attribution android:tag="f147" android:label="@string/dummyLabel" />
+  <attribution android:tag="f148" android:label="@string/dummyLabel" />
+  <attribution android:tag="f149" android:label="@string/dummyLabel" />
+  <attribution android:tag="f150" android:label="@string/dummyLabel" />
+  <attribution android:tag="f151" android:label="@string/dummyLabel" />
+  <attribution android:tag="f152" android:label="@string/dummyLabel" />
+  <attribution android:tag="f153" android:label="@string/dummyLabel" />
+  <attribution android:tag="f154" android:label="@string/dummyLabel" />
+  <attribution android:tag="f155" android:label="@string/dummyLabel" />
+  <attribution android:tag="f156" android:label="@string/dummyLabel" />
+  <attribution android:tag="f157" android:label="@string/dummyLabel" />
+  <attribution android:tag="f158" android:label="@string/dummyLabel" />
+  <attribution android:tag="f159" android:label="@string/dummyLabel" />
+  <attribution android:tag="f160" android:label="@string/dummyLabel" />
+  <attribution android:tag="f161" android:label="@string/dummyLabel" />
+  <attribution android:tag="f162" android:label="@string/dummyLabel" />
+  <attribution android:tag="f163" android:label="@string/dummyLabel" />
+  <attribution android:tag="f164" android:label="@string/dummyLabel" />
+  <attribution android:tag="f165" android:label="@string/dummyLabel" />
+  <attribution android:tag="f166" android:label="@string/dummyLabel" />
+  <attribution android:tag="f167" android:label="@string/dummyLabel" />
+  <attribution android:tag="f168" android:label="@string/dummyLabel" />
+  <attribution android:tag="f169" android:label="@string/dummyLabel" />
+  <attribution android:tag="f170" android:label="@string/dummyLabel" />
+  <attribution android:tag="f171" android:label="@string/dummyLabel" />
+  <attribution android:tag="f172" android:label="@string/dummyLabel" />
+  <attribution android:tag="f173" android:label="@string/dummyLabel" />
+  <attribution android:tag="f174" android:label="@string/dummyLabel" />
+  <attribution android:tag="f175" android:label="@string/dummyLabel" />
+  <attribution android:tag="f176" android:label="@string/dummyLabel" />
+  <attribution android:tag="f177" android:label="@string/dummyLabel" />
+  <attribution android:tag="f178" android:label="@string/dummyLabel" />
+  <attribution android:tag="f179" android:label="@string/dummyLabel" />
+  <attribution android:tag="f180" android:label="@string/dummyLabel" />
+  <attribution android:tag="f181" android:label="@string/dummyLabel" />
+  <attribution android:tag="f182" android:label="@string/dummyLabel" />
+  <attribution android:tag="f183" android:label="@string/dummyLabel" />
+  <attribution android:tag="f184" android:label="@string/dummyLabel" />
+  <attribution android:tag="f185" android:label="@string/dummyLabel" />
+  <attribution android:tag="f186" android:label="@string/dummyLabel" />
+  <attribution android:tag="f187" android:label="@string/dummyLabel" />
+  <attribution android:tag="f188" android:label="@string/dummyLabel" />
+  <attribution android:tag="f189" android:label="@string/dummyLabel" />
+  <attribution android:tag="f190" android:label="@string/dummyLabel" />
+  <attribution android:tag="f191" android:label="@string/dummyLabel" />
+  <attribution android:tag="f192" android:label="@string/dummyLabel" />
+  <attribution android:tag="f193" android:label="@string/dummyLabel" />
+  <attribution android:tag="f194" android:label="@string/dummyLabel" />
+  <attribution android:tag="f195" android:label="@string/dummyLabel" />
+  <attribution android:tag="f196" android:label="@string/dummyLabel" />
+  <attribution android:tag="f197" android:label="@string/dummyLabel" />
+  <attribution android:tag="f198" android:label="@string/dummyLabel" />
+  <attribution android:tag="f199" android:label="@string/dummyLabel" />
+  <attribution android:tag="f200" android:label="@string/dummyLabel" />
+  <attribution android:tag="f201" android:label="@string/dummyLabel" />
+  <attribution android:tag="f202" android:label="@string/dummyLabel" />
+  <attribution android:tag="f203" android:label="@string/dummyLabel" />
+  <attribution android:tag="f204" android:label="@string/dummyLabel" />
+  <attribution android:tag="f205" android:label="@string/dummyLabel" />
+  <attribution android:tag="f206" android:label="@string/dummyLabel" />
+  <attribution android:tag="f207" android:label="@string/dummyLabel" />
+  <attribution android:tag="f208" android:label="@string/dummyLabel" />
+  <attribution android:tag="f209" android:label="@string/dummyLabel" />
+  <attribution android:tag="f210" android:label="@string/dummyLabel" />
+  <attribution android:tag="f211" android:label="@string/dummyLabel" />
+  <attribution android:tag="f212" android:label="@string/dummyLabel" />
+  <attribution android:tag="f213" android:label="@string/dummyLabel" />
+  <attribution android:tag="f214" android:label="@string/dummyLabel" />
+  <attribution android:tag="f215" android:label="@string/dummyLabel" />
+  <attribution android:tag="f216" android:label="@string/dummyLabel" />
+  <attribution android:tag="f217" android:label="@string/dummyLabel" />
+  <attribution android:tag="f218" android:label="@string/dummyLabel" />
+  <attribution android:tag="f219" android:label="@string/dummyLabel" />
+  <attribution android:tag="f220" android:label="@string/dummyLabel" />
+  <attribution android:tag="f221" android:label="@string/dummyLabel" />
+  <attribution android:tag="f222" android:label="@string/dummyLabel" />
+  <attribution android:tag="f223" android:label="@string/dummyLabel" />
+  <attribution android:tag="f224" android:label="@string/dummyLabel" />
+  <attribution android:tag="f225" android:label="@string/dummyLabel" />
+  <attribution android:tag="f226" android:label="@string/dummyLabel" />
+  <attribution android:tag="f227" android:label="@string/dummyLabel" />
+  <attribution android:tag="f228" android:label="@string/dummyLabel" />
+  <attribution android:tag="f229" android:label="@string/dummyLabel" />
+  <attribution android:tag="f230" android:label="@string/dummyLabel" />
+  <attribution android:tag="f231" android:label="@string/dummyLabel" />
+  <attribution android:tag="f232" android:label="@string/dummyLabel" />
+  <attribution android:tag="f233" android:label="@string/dummyLabel" />
+  <attribution android:tag="f234" android:label="@string/dummyLabel" />
+  <attribution android:tag="f235" android:label="@string/dummyLabel" />
+  <attribution android:tag="f236" android:label="@string/dummyLabel" />
+  <attribution android:tag="f237" android:label="@string/dummyLabel" />
+  <attribution android:tag="f238" android:label="@string/dummyLabel" />
+  <attribution android:tag="f239" android:label="@string/dummyLabel" />
+  <attribution android:tag="f240" android:label="@string/dummyLabel" />
+  <attribution android:tag="f241" android:label="@string/dummyLabel" />
+  <attribution android:tag="f242" android:label="@string/dummyLabel" />
+  <attribution android:tag="f243" android:label="@string/dummyLabel" />
+  <attribution android:tag="f244" android:label="@string/dummyLabel" />
+  <attribution android:tag="f245" android:label="@string/dummyLabel" />
+  <attribution android:tag="f246" android:label="@string/dummyLabel" />
+  <attribution android:tag="f247" android:label="@string/dummyLabel" />
+  <attribution android:tag="f248" android:label="@string/dummyLabel" />
+  <attribution android:tag="f249" android:label="@string/dummyLabel" />
+  <attribution android:tag="f250" android:label="@string/dummyLabel" />
+  <attribution android:tag="f251" android:label="@string/dummyLabel" />
+  <attribution android:tag="f252" android:label="@string/dummyLabel" />
+  <attribution android:tag="f253" android:label="@string/dummyLabel" />
+  <attribution android:tag="f254" android:label="@string/dummyLabel" />
+  <attribution android:tag="f255" android:label="@string/dummyLabel" />
+  <attribution android:tag="f256" android:label="@string/dummyLabel" />
+  <attribution android:tag="f257" android:label="@string/dummyLabel" />
+  <attribution android:tag="f258" android:label="@string/dummyLabel" />
+  <attribution android:tag="f259" android:label="@string/dummyLabel" />
+  <attribution android:tag="f260" android:label="@string/dummyLabel" />
+  <attribution android:tag="f261" android:label="@string/dummyLabel" />
+  <attribution android:tag="f262" android:label="@string/dummyLabel" />
+  <attribution android:tag="f263" android:label="@string/dummyLabel" />
+  <attribution android:tag="f264" android:label="@string/dummyLabel" />
+  <attribution android:tag="f265" android:label="@string/dummyLabel" />
+  <attribution android:tag="f266" android:label="@string/dummyLabel" />
+  <attribution android:tag="f267" android:label="@string/dummyLabel" />
+  <attribution android:tag="f268" android:label="@string/dummyLabel" />
+  <attribution android:tag="f269" android:label="@string/dummyLabel" />
+  <attribution android:tag="f270" android:label="@string/dummyLabel" />
+  <attribution android:tag="f271" android:label="@string/dummyLabel" />
+  <attribution android:tag="f272" android:label="@string/dummyLabel" />
+  <attribution android:tag="f273" android:label="@string/dummyLabel" />
+  <attribution android:tag="f274" android:label="@string/dummyLabel" />
+  <attribution android:tag="f275" android:label="@string/dummyLabel" />
+  <attribution android:tag="f276" android:label="@string/dummyLabel" />
+  <attribution android:tag="f277" android:label="@string/dummyLabel" />
+  <attribution android:tag="f278" android:label="@string/dummyLabel" />
+  <attribution android:tag="f279" android:label="@string/dummyLabel" />
+  <attribution android:tag="f280" android:label="@string/dummyLabel" />
+  <attribution android:tag="f281" android:label="@string/dummyLabel" />
+  <attribution android:tag="f282" android:label="@string/dummyLabel" />
+  <attribution android:tag="f283" android:label="@string/dummyLabel" />
+  <attribution android:tag="f284" android:label="@string/dummyLabel" />
+  <attribution android:tag="f285" android:label="@string/dummyLabel" />
+  <attribution android:tag="f286" android:label="@string/dummyLabel" />
+  <attribution android:tag="f287" android:label="@string/dummyLabel" />
+  <attribution android:tag="f288" android:label="@string/dummyLabel" />
+  <attribution android:tag="f289" android:label="@string/dummyLabel" />
+  <attribution android:tag="f290" android:label="@string/dummyLabel" />
+  <attribution android:tag="f291" android:label="@string/dummyLabel" />
+  <attribution android:tag="f292" android:label="@string/dummyLabel" />
+  <attribution android:tag="f293" android:label="@string/dummyLabel" />
+  <attribution android:tag="f294" android:label="@string/dummyLabel" />
+  <attribution android:tag="f295" android:label="@string/dummyLabel" />
+  <attribution android:tag="f296" android:label="@string/dummyLabel" />
+  <attribution android:tag="f297" android:label="@string/dummyLabel" />
+  <attribution android:tag="f298" android:label="@string/dummyLabel" />
+  <attribution android:tag="f299" android:label="@string/dummyLabel" />
+  <attribution android:tag="f300" android:label="@string/dummyLabel" />
+  <attribution android:tag="f301" android:label="@string/dummyLabel" />
+  <attribution android:tag="f302" android:label="@string/dummyLabel" />
+  <attribution android:tag="f303" android:label="@string/dummyLabel" />
+  <attribution android:tag="f304" android:label="@string/dummyLabel" />
+  <attribution android:tag="f305" android:label="@string/dummyLabel" />
+  <attribution android:tag="f306" android:label="@string/dummyLabel" />
+  <attribution android:tag="f307" android:label="@string/dummyLabel" />
+  <attribution android:tag="f308" android:label="@string/dummyLabel" />
+  <attribution android:tag="f309" android:label="@string/dummyLabel" />
+  <attribution android:tag="f310" android:label="@string/dummyLabel" />
+  <attribution android:tag="f311" android:label="@string/dummyLabel" />
+  <attribution android:tag="f312" android:label="@string/dummyLabel" />
+  <attribution android:tag="f313" android:label="@string/dummyLabel" />
+  <attribution android:tag="f314" android:label="@string/dummyLabel" />
+  <attribution android:tag="f315" android:label="@string/dummyLabel" />
+  <attribution android:tag="f316" android:label="@string/dummyLabel" />
+  <attribution android:tag="f317" android:label="@string/dummyLabel" />
+  <attribution android:tag="f318" android:label="@string/dummyLabel" />
+  <attribution android:tag="f319" android:label="@string/dummyLabel" />
+  <attribution android:tag="f320" android:label="@string/dummyLabel" />
+  <attribution android:tag="f321" android:label="@string/dummyLabel" />
+  <attribution android:tag="f322" android:label="@string/dummyLabel" />
+  <attribution android:tag="f323" android:label="@string/dummyLabel" />
+  <attribution android:tag="f324" android:label="@string/dummyLabel" />
+  <attribution android:tag="f325" android:label="@string/dummyLabel" />
+  <attribution android:tag="f326" android:label="@string/dummyLabel" />
+  <attribution android:tag="f327" android:label="@string/dummyLabel" />
+  <attribution android:tag="f328" android:label="@string/dummyLabel" />
+  <attribution android:tag="f329" android:label="@string/dummyLabel" />
+  <attribution android:tag="f330" android:label="@string/dummyLabel" />
+  <attribution android:tag="f331" android:label="@string/dummyLabel" />
+  <attribution android:tag="f332" android:label="@string/dummyLabel" />
+  <attribution android:tag="f333" android:label="@string/dummyLabel" />
+  <attribution android:tag="f334" android:label="@string/dummyLabel" />
+  <attribution android:tag="f335" android:label="@string/dummyLabel" />
+  <attribution android:tag="f336" android:label="@string/dummyLabel" />
+  <attribution android:tag="f337" android:label="@string/dummyLabel" />
+  <attribution android:tag="f338" android:label="@string/dummyLabel" />
+  <attribution android:tag="f339" android:label="@string/dummyLabel" />
+  <attribution android:tag="f340" android:label="@string/dummyLabel" />
+  <attribution android:tag="f341" android:label="@string/dummyLabel" />
+  <attribution android:tag="f342" android:label="@string/dummyLabel" />
+  <attribution android:tag="f343" android:label="@string/dummyLabel" />
+  <attribution android:tag="f344" android:label="@string/dummyLabel" />
+  <attribution android:tag="f345" android:label="@string/dummyLabel" />
+  <attribution android:tag="f346" android:label="@string/dummyLabel" />
+  <attribution android:tag="f347" android:label="@string/dummyLabel" />
+  <attribution android:tag="f348" android:label="@string/dummyLabel" />
+  <attribution android:tag="f349" android:label="@string/dummyLabel" />
+  <attribution android:tag="f350" android:label="@string/dummyLabel" />
+  <attribution android:tag="f351" android:label="@string/dummyLabel" />
+  <attribution android:tag="f352" android:label="@string/dummyLabel" />
+  <attribution android:tag="f353" android:label="@string/dummyLabel" />
+  <attribution android:tag="f354" android:label="@string/dummyLabel" />
+  <attribution android:tag="f355" android:label="@string/dummyLabel" />
+  <attribution android:tag="f356" android:label="@string/dummyLabel" />
+  <attribution android:tag="f357" android:label="@string/dummyLabel" />
+  <attribution android:tag="f358" android:label="@string/dummyLabel" />
+  <attribution android:tag="f359" android:label="@string/dummyLabel" />
+  <attribution android:tag="f360" android:label="@string/dummyLabel" />
+  <attribution android:tag="f361" android:label="@string/dummyLabel" />
+  <attribution android:tag="f362" android:label="@string/dummyLabel" />
+  <attribution android:tag="f363" android:label="@string/dummyLabel" />
+  <attribution android:tag="f364" android:label="@string/dummyLabel" />
+  <attribution android:tag="f365" android:label="@string/dummyLabel" />
+  <attribution android:tag="f366" android:label="@string/dummyLabel" />
+  <attribution android:tag="f367" android:label="@string/dummyLabel" />
+  <attribution android:tag="f368" android:label="@string/dummyLabel" />
+  <attribution android:tag="f369" android:label="@string/dummyLabel" />
+  <attribution android:tag="f370" android:label="@string/dummyLabel" />
+  <attribution android:tag="f371" android:label="@string/dummyLabel" />
+  <attribution android:tag="f372" android:label="@string/dummyLabel" />
+  <attribution android:tag="f373" android:label="@string/dummyLabel" />
+  <attribution android:tag="f374" android:label="@string/dummyLabel" />
+  <attribution android:tag="f375" android:label="@string/dummyLabel" />
+  <attribution android:tag="f376" android:label="@string/dummyLabel" />
+  <attribution android:tag="f377" android:label="@string/dummyLabel" />
+  <attribution android:tag="f378" android:label="@string/dummyLabel" />
+  <attribution android:tag="f379" android:label="@string/dummyLabel" />
+  <attribution android:tag="f380" android:label="@string/dummyLabel" />
+  <attribution android:tag="f381" android:label="@string/dummyLabel" />
+  <attribution android:tag="f382" android:label="@string/dummyLabel" />
+  <attribution android:tag="f383" android:label="@string/dummyLabel" />
+  <attribution android:tag="f384" android:label="@string/dummyLabel" />
+  <attribution android:tag="f385" android:label="@string/dummyLabel" />
+  <attribution android:tag="f386" android:label="@string/dummyLabel" />
+  <attribution android:tag="f387" android:label="@string/dummyLabel" />
+  <attribution android:tag="f388" android:label="@string/dummyLabel" />
+  <attribution android:tag="f389" android:label="@string/dummyLabel" />
+  <attribution android:tag="f390" android:label="@string/dummyLabel" />
+  <attribution android:tag="f391" android:label="@string/dummyLabel" />
+  <attribution android:tag="f392" android:label="@string/dummyLabel" />
+  <attribution android:tag="f393" android:label="@string/dummyLabel" />
+  <attribution android:tag="f394" android:label="@string/dummyLabel" />
+  <attribution android:tag="f395" android:label="@string/dummyLabel" />
+  <attribution android:tag="f396" android:label="@string/dummyLabel" />
+  <attribution android:tag="f397" android:label="@string/dummyLabel" />
+  <attribution android:tag="f398" android:label="@string/dummyLabel" />
+  <attribution android:tag="f399" android:label="@string/dummyLabel" />
+  <attribution android:tag="f400" android:label="@string/dummyLabel" />
+  <attribution android:tag="f401" android:label="@string/dummyLabel" />
+  <attribution android:tag="f402" android:label="@string/dummyLabel" />
+  <attribution android:tag="f403" android:label="@string/dummyLabel" />
+  <attribution android:tag="f404" android:label="@string/dummyLabel" />
+  <attribution android:tag="f405" android:label="@string/dummyLabel" />
+  <attribution android:tag="f406" android:label="@string/dummyLabel" />
+  <attribution android:tag="f407" android:label="@string/dummyLabel" />
+  <attribution android:tag="f408" android:label="@string/dummyLabel" />
+  <attribution android:tag="f409" android:label="@string/dummyLabel" />
+  <attribution android:tag="f410" android:label="@string/dummyLabel" />
+  <attribution android:tag="f411" android:label="@string/dummyLabel" />
+  <attribution android:tag="f412" android:label="@string/dummyLabel" />
+  <attribution android:tag="f413" android:label="@string/dummyLabel" />
+  <attribution android:tag="f414" android:label="@string/dummyLabel" />
+  <attribution android:tag="f415" android:label="@string/dummyLabel" />
+  <attribution android:tag="f416" android:label="@string/dummyLabel" />
+  <attribution android:tag="f417" android:label="@string/dummyLabel" />
+  <attribution android:tag="f418" android:label="@string/dummyLabel" />
+  <attribution android:tag="f419" android:label="@string/dummyLabel" />
+  <attribution android:tag="f420" android:label="@string/dummyLabel" />
+  <attribution android:tag="f421" android:label="@string/dummyLabel" />
+  <attribution android:tag="f422" android:label="@string/dummyLabel" />
+  <attribution android:tag="f423" android:label="@string/dummyLabel" />
+  <attribution android:tag="f424" android:label="@string/dummyLabel" />
+  <attribution android:tag="f425" android:label="@string/dummyLabel" />
+  <attribution android:tag="f426" android:label="@string/dummyLabel" />
+  <attribution android:tag="f427" android:label="@string/dummyLabel" />
+  <attribution android:tag="f428" android:label="@string/dummyLabel" />
+  <attribution android:tag="f429" android:label="@string/dummyLabel" />
+  <attribution android:tag="f430" android:label="@string/dummyLabel" />
+  <attribution android:tag="f431" android:label="@string/dummyLabel" />
+  <attribution android:tag="f432" android:label="@string/dummyLabel" />
+  <attribution android:tag="f433" android:label="@string/dummyLabel" />
+  <attribution android:tag="f434" android:label="@string/dummyLabel" />
+  <attribution android:tag="f435" android:label="@string/dummyLabel" />
+  <attribution android:tag="f436" android:label="@string/dummyLabel" />
+  <attribution android:tag="f437" android:label="@string/dummyLabel" />
+  <attribution android:tag="f438" android:label="@string/dummyLabel" />
+  <attribution android:tag="f439" android:label="@string/dummyLabel" />
+  <attribution android:tag="f440" android:label="@string/dummyLabel" />
+  <attribution android:tag="f441" android:label="@string/dummyLabel" />
+  <attribution android:tag="f442" android:label="@string/dummyLabel" />
+  <attribution android:tag="f443" android:label="@string/dummyLabel" />
+  <attribution android:tag="f444" android:label="@string/dummyLabel" />
+  <attribution android:tag="f445" android:label="@string/dummyLabel" />
+  <attribution android:tag="f446" android:label="@string/dummyLabel" />
+  <attribution android:tag="f447" android:label="@string/dummyLabel" />
+  <attribution android:tag="f448" android:label="@string/dummyLabel" />
+  <attribution android:tag="f449" android:label="@string/dummyLabel" />
+  <attribution android:tag="f450" android:label="@string/dummyLabel" />
+  <attribution android:tag="f451" android:label="@string/dummyLabel" />
+  <attribution android:tag="f452" android:label="@string/dummyLabel" />
+  <attribution android:tag="f453" android:label="@string/dummyLabel" />
+  <attribution android:tag="f454" android:label="@string/dummyLabel" />
+  <attribution android:tag="f455" android:label="@string/dummyLabel" />
+  <attribution android:tag="f456" android:label="@string/dummyLabel" />
+  <attribution android:tag="f457" android:label="@string/dummyLabel" />
+  <attribution android:tag="f458" android:label="@string/dummyLabel" />
+  <attribution android:tag="f459" android:label="@string/dummyLabel" />
+  <attribution android:tag="f460" android:label="@string/dummyLabel" />
+  <attribution android:tag="f461" android:label="@string/dummyLabel" />
+  <attribution android:tag="f462" android:label="@string/dummyLabel" />
+  <attribution android:tag="f463" android:label="@string/dummyLabel" />
+  <attribution android:tag="f464" android:label="@string/dummyLabel" />
+  <attribution android:tag="f465" android:label="@string/dummyLabel" />
+  <attribution android:tag="f466" android:label="@string/dummyLabel" />
+  <attribution android:tag="f467" android:label="@string/dummyLabel" />
+  <attribution android:tag="f468" android:label="@string/dummyLabel" />
+  <attribution android:tag="f469" android:label="@string/dummyLabel" />
+  <attribution android:tag="f470" android:label="@string/dummyLabel" />
+  <attribution android:tag="f471" android:label="@string/dummyLabel" />
+  <attribution android:tag="f472" android:label="@string/dummyLabel" />
+  <attribution android:tag="f473" android:label="@string/dummyLabel" />
+  <attribution android:tag="f474" android:label="@string/dummyLabel" />
+  <attribution android:tag="f475" android:label="@string/dummyLabel" />
+  <attribution android:tag="f476" android:label="@string/dummyLabel" />
+  <attribution android:tag="f477" android:label="@string/dummyLabel" />
+  <attribution android:tag="f478" android:label="@string/dummyLabel" />
+  <attribution android:tag="f479" android:label="@string/dummyLabel" />
+  <attribution android:tag="f480" android:label="@string/dummyLabel" />
+  <attribution android:tag="f481" android:label="@string/dummyLabel" />
+  <attribution android:tag="f482" android:label="@string/dummyLabel" />
+  <attribution android:tag="f483" android:label="@string/dummyLabel" />
+  <attribution android:tag="f484" android:label="@string/dummyLabel" />
+  <attribution android:tag="f485" android:label="@string/dummyLabel" />
+  <attribution android:tag="f486" android:label="@string/dummyLabel" />
+  <attribution android:tag="f487" android:label="@string/dummyLabel" />
+  <attribution android:tag="f488" android:label="@string/dummyLabel" />
+  <attribution android:tag="f489" android:label="@string/dummyLabel" />
+  <attribution android:tag="f490" android:label="@string/dummyLabel" />
+  <attribution android:tag="f491" android:label="@string/dummyLabel" />
+  <attribution android:tag="f492" android:label="@string/dummyLabel" />
+  <attribution android:tag="f493" android:label="@string/dummyLabel" />
+  <attribution android:tag="f494" android:label="@string/dummyLabel" />
+  <attribution android:tag="f495" android:label="@string/dummyLabel" />
+  <attribution android:tag="f496" android:label="@string/dummyLabel" />
+  <attribution android:tag="f497" android:label="@string/dummyLabel" />
+  <attribution android:tag="f498" android:label="@string/dummyLabel" />
+  <attribution android:tag="f499" android:label="@string/dummyLabel" />
+  <attribution android:tag="f500" android:label="@string/dummyLabel" />
+  <attribution android:tag="f501" android:label="@string/dummyLabel" />
+  <attribution android:tag="f502" android:label="@string/dummyLabel" />
+  <attribution android:tag="f503" android:label="@string/dummyLabel" />
+  <attribution android:tag="f504" android:label="@string/dummyLabel" />
+  <attribution android:tag="f505" android:label="@string/dummyLabel" />
+  <attribution android:tag="f506" android:label="@string/dummyLabel" />
+  <attribution android:tag="f507" android:label="@string/dummyLabel" />
+  <attribution android:tag="f508" android:label="@string/dummyLabel" />
+  <attribution android:tag="f509" android:label="@string/dummyLabel" />
+  <attribution android:tag="f510" android:label="@string/dummyLabel" />
+  <attribution android:tag="f511" android:label="@string/dummyLabel" />
+  <attribution android:tag="f512" android:label="@string/dummyLabel" />
+  <attribution android:tag="f513" android:label="@string/dummyLabel" />
+  <attribution android:tag="f514" android:label="@string/dummyLabel" />
+  <attribution android:tag="f515" android:label="@string/dummyLabel" />
+  <attribution android:tag="f516" android:label="@string/dummyLabel" />
+  <attribution android:tag="f517" android:label="@string/dummyLabel" />
+  <attribution android:tag="f518" android:label="@string/dummyLabel" />
+  <attribution android:tag="f519" android:label="@string/dummyLabel" />
+  <attribution android:tag="f520" android:label="@string/dummyLabel" />
+  <attribution android:tag="f521" android:label="@string/dummyLabel" />
+  <attribution android:tag="f522" android:label="@string/dummyLabel" />
+  <attribution android:tag="f523" android:label="@string/dummyLabel" />
+  <attribution android:tag="f524" android:label="@string/dummyLabel" />
+  <attribution android:tag="f525" android:label="@string/dummyLabel" />
+  <attribution android:tag="f526" android:label="@string/dummyLabel" />
+  <attribution android:tag="f527" android:label="@string/dummyLabel" />
+  <attribution android:tag="f528" android:label="@string/dummyLabel" />
+  <attribution android:tag="f529" android:label="@string/dummyLabel" />
+  <attribution android:tag="f530" android:label="@string/dummyLabel" />
+  <attribution android:tag="f531" android:label="@string/dummyLabel" />
+  <attribution android:tag="f532" android:label="@string/dummyLabel" />
+  <attribution android:tag="f533" android:label="@string/dummyLabel" />
+  <attribution android:tag="f534" android:label="@string/dummyLabel" />
+  <attribution android:tag="f535" android:label="@string/dummyLabel" />
+  <attribution android:tag="f536" android:label="@string/dummyLabel" />
+  <attribution android:tag="f537" android:label="@string/dummyLabel" />
+  <attribution android:tag="f538" android:label="@string/dummyLabel" />
+  <attribution android:tag="f539" android:label="@string/dummyLabel" />
+  <attribution android:tag="f540" android:label="@string/dummyLabel" />
+  <attribution android:tag="f541" android:label="@string/dummyLabel" />
+  <attribution android:tag="f542" android:label="@string/dummyLabel" />
+  <attribution android:tag="f543" android:label="@string/dummyLabel" />
+  <attribution android:tag="f544" android:label="@string/dummyLabel" />
+  <attribution android:tag="f545" android:label="@string/dummyLabel" />
+  <attribution android:tag="f546" android:label="@string/dummyLabel" />
+  <attribution android:tag="f547" android:label="@string/dummyLabel" />
+  <attribution android:tag="f548" android:label="@string/dummyLabel" />
+  <attribution android:tag="f549" android:label="@string/dummyLabel" />
+  <attribution android:tag="f550" android:label="@string/dummyLabel" />
+  <attribution android:tag="f551" android:label="@string/dummyLabel" />
+  <attribution android:tag="f552" android:label="@string/dummyLabel" />
+  <attribution android:tag="f553" android:label="@string/dummyLabel" />
+  <attribution android:tag="f554" android:label="@string/dummyLabel" />
+  <attribution android:tag="f555" android:label="@string/dummyLabel" />
+  <attribution android:tag="f556" android:label="@string/dummyLabel" />
+  <attribution android:tag="f557" android:label="@string/dummyLabel" />
+  <attribution android:tag="f558" android:label="@string/dummyLabel" />
+  <attribution android:tag="f559" android:label="@string/dummyLabel" />
+  <attribution android:tag="f560" android:label="@string/dummyLabel" />
+  <attribution android:tag="f561" android:label="@string/dummyLabel" />
+  <attribution android:tag="f562" android:label="@string/dummyLabel" />
+  <attribution android:tag="f563" android:label="@string/dummyLabel" />
+  <attribution android:tag="f564" android:label="@string/dummyLabel" />
+  <attribution android:tag="f565" android:label="@string/dummyLabel" />
+  <attribution android:tag="f566" android:label="@string/dummyLabel" />
+  <attribution android:tag="f567" android:label="@string/dummyLabel" />
+  <attribution android:tag="f568" android:label="@string/dummyLabel" />
+  <attribution android:tag="f569" android:label="@string/dummyLabel" />
+  <attribution android:tag="f570" android:label="@string/dummyLabel" />
+  <attribution android:tag="f571" android:label="@string/dummyLabel" />
+  <attribution android:tag="f572" android:label="@string/dummyLabel" />
+  <attribution android:tag="f573" android:label="@string/dummyLabel" />
+  <attribution android:tag="f574" android:label="@string/dummyLabel" />
+  <attribution android:tag="f575" android:label="@string/dummyLabel" />
+  <attribution android:tag="f576" android:label="@string/dummyLabel" />
+  <attribution android:tag="f577" android:label="@string/dummyLabel" />
+  <attribution android:tag="f578" android:label="@string/dummyLabel" />
+  <attribution android:tag="f579" android:label="@string/dummyLabel" />
+  <attribution android:tag="f580" android:label="@string/dummyLabel" />
+  <attribution android:tag="f581" android:label="@string/dummyLabel" />
+  <attribution android:tag="f582" android:label="@string/dummyLabel" />
+  <attribution android:tag="f583" android:label="@string/dummyLabel" />
+  <attribution android:tag="f584" android:label="@string/dummyLabel" />
+  <attribution android:tag="f585" android:label="@string/dummyLabel" />
+  <attribution android:tag="f586" android:label="@string/dummyLabel" />
+  <attribution android:tag="f587" android:label="@string/dummyLabel" />
+  <attribution android:tag="f588" android:label="@string/dummyLabel" />
+  <attribution android:tag="f589" android:label="@string/dummyLabel" />
+  <attribution android:tag="f590" android:label="@string/dummyLabel" />
+  <attribution android:tag="f591" android:label="@string/dummyLabel" />
+  <attribution android:tag="f592" android:label="@string/dummyLabel" />
+  <attribution android:tag="f593" android:label="@string/dummyLabel" />
+  <attribution android:tag="f594" android:label="@string/dummyLabel" />
+  <attribution android:tag="f595" android:label="@string/dummyLabel" />
+  <attribution android:tag="f596" android:label="@string/dummyLabel" />
+  <attribution android:tag="f597" android:label="@string/dummyLabel" />
+  <attribution android:tag="f598" android:label="@string/dummyLabel" />
+  <attribution android:tag="f599" android:label="@string/dummyLabel" />
+  <attribution android:tag="f600" android:label="@string/dummyLabel" />
+  <attribution android:tag="f601" android:label="@string/dummyLabel" />
+  <attribution android:tag="f602" android:label="@string/dummyLabel" />
+  <attribution android:tag="f603" android:label="@string/dummyLabel" />
+  <attribution android:tag="f604" android:label="@string/dummyLabel" />
+  <attribution android:tag="f605" android:label="@string/dummyLabel" />
+  <attribution android:tag="f606" android:label="@string/dummyLabel" />
+  <attribution android:tag="f607" android:label="@string/dummyLabel" />
+  <attribution android:tag="f608" android:label="@string/dummyLabel" />
+  <attribution android:tag="f609" android:label="@string/dummyLabel" />
+  <attribution android:tag="f610" android:label="@string/dummyLabel" />
+  <attribution android:tag="f611" android:label="@string/dummyLabel" />
+  <attribution android:tag="f612" android:label="@string/dummyLabel" />
+  <attribution android:tag="f613" android:label="@string/dummyLabel" />
+  <attribution android:tag="f614" android:label="@string/dummyLabel" />
+  <attribution android:tag="f615" android:label="@string/dummyLabel" />
+  <attribution android:tag="f616" android:label="@string/dummyLabel" />
+  <attribution android:tag="f617" android:label="@string/dummyLabel" />
+  <attribution android:tag="f618" android:label="@string/dummyLabel" />
+  <attribution android:tag="f619" android:label="@string/dummyLabel" />
+  <attribution android:tag="f620" android:label="@string/dummyLabel" />
+  <attribution android:tag="f621" android:label="@string/dummyLabel" />
+  <attribution android:tag="f622" android:label="@string/dummyLabel" />
+  <attribution android:tag="f623" android:label="@string/dummyLabel" />
+  <attribution android:tag="f624" android:label="@string/dummyLabel" />
+  <attribution android:tag="f625" android:label="@string/dummyLabel" />
+  <attribution android:tag="f626" android:label="@string/dummyLabel" />
+  <attribution android:tag="f627" android:label="@string/dummyLabel" />
+  <attribution android:tag="f628" android:label="@string/dummyLabel" />
+  <attribution android:tag="f629" android:label="@string/dummyLabel" />
+  <attribution android:tag="f630" android:label="@string/dummyLabel" />
+  <attribution android:tag="f631" android:label="@string/dummyLabel" />
+  <attribution android:tag="f632" android:label="@string/dummyLabel" />
+  <attribution android:tag="f633" android:label="@string/dummyLabel" />
+  <attribution android:tag="f634" android:label="@string/dummyLabel" />
+  <attribution android:tag="f635" android:label="@string/dummyLabel" />
+  <attribution android:tag="f636" android:label="@string/dummyLabel" />
+  <attribution android:tag="f637" android:label="@string/dummyLabel" />
+  <attribution android:tag="f638" android:label="@string/dummyLabel" />
+  <attribution android:tag="f639" android:label="@string/dummyLabel" />
+  <attribution android:tag="f640" android:label="@string/dummyLabel" />
+  <attribution android:tag="f641" android:label="@string/dummyLabel" />
+  <attribution android:tag="f642" android:label="@string/dummyLabel" />
+  <attribution android:tag="f643" android:label="@string/dummyLabel" />
+  <attribution android:tag="f644" android:label="@string/dummyLabel" />
+  <attribution android:tag="f645" android:label="@string/dummyLabel" />
+  <attribution android:tag="f646" android:label="@string/dummyLabel" />
+  <attribution android:tag="f647" android:label="@string/dummyLabel" />
+  <attribution android:tag="f648" android:label="@string/dummyLabel" />
+  <attribution android:tag="f649" android:label="@string/dummyLabel" />
+  <attribution android:tag="f650" android:label="@string/dummyLabel" />
+  <attribution android:tag="f651" android:label="@string/dummyLabel" />
+  <attribution android:tag="f652" android:label="@string/dummyLabel" />
+  <attribution android:tag="f653" android:label="@string/dummyLabel" />
+  <attribution android:tag="f654" android:label="@string/dummyLabel" />
+  <attribution android:tag="f655" android:label="@string/dummyLabel" />
+  <attribution android:tag="f656" android:label="@string/dummyLabel" />
+  <attribution android:tag="f657" android:label="@string/dummyLabel" />
+  <attribution android:tag="f658" android:label="@string/dummyLabel" />
+  <attribution android:tag="f659" android:label="@string/dummyLabel" />
+  <attribution android:tag="f660" android:label="@string/dummyLabel" />
+  <attribution android:tag="f661" android:label="@string/dummyLabel" />
+  <attribution android:tag="f662" android:label="@string/dummyLabel" />
+  <attribution android:tag="f663" android:label="@string/dummyLabel" />
+  <attribution android:tag="f664" android:label="@string/dummyLabel" />
+  <attribution android:tag="f665" android:label="@string/dummyLabel" />
+  <attribution android:tag="f666" android:label="@string/dummyLabel" />
+  <attribution android:tag="f667" android:label="@string/dummyLabel" />
+  <attribution android:tag="f668" android:label="@string/dummyLabel" />
+  <attribution android:tag="f669" android:label="@string/dummyLabel" />
+  <attribution android:tag="f670" android:label="@string/dummyLabel" />
+  <attribution android:tag="f671" android:label="@string/dummyLabel" />
+  <attribution android:tag="f672" android:label="@string/dummyLabel" />
+  <attribution android:tag="f673" android:label="@string/dummyLabel" />
+  <attribution android:tag="f674" android:label="@string/dummyLabel" />
+  <attribution android:tag="f675" android:label="@string/dummyLabel" />
+  <attribution android:tag="f676" android:label="@string/dummyLabel" />
+  <attribution android:tag="f677" android:label="@string/dummyLabel" />
+  <attribution android:tag="f678" android:label="@string/dummyLabel" />
+  <attribution android:tag="f679" android:label="@string/dummyLabel" />
+  <attribution android:tag="f680" android:label="@string/dummyLabel" />
+  <attribution android:tag="f681" android:label="@string/dummyLabel" />
+  <attribution android:tag="f682" android:label="@string/dummyLabel" />
+  <attribution android:tag="f683" android:label="@string/dummyLabel" />
+  <attribution android:tag="f684" android:label="@string/dummyLabel" />
+  <attribution android:tag="f685" android:label="@string/dummyLabel" />
+  <attribution android:tag="f686" android:label="@string/dummyLabel" />
+  <attribution android:tag="f687" android:label="@string/dummyLabel" />
+  <attribution android:tag="f688" android:label="@string/dummyLabel" />
+  <attribution android:tag="f689" android:label="@string/dummyLabel" />
+  <attribution android:tag="f690" android:label="@string/dummyLabel" />
+  <attribution android:tag="f691" android:label="@string/dummyLabel" />
+  <attribution android:tag="f692" android:label="@string/dummyLabel" />
+  <attribution android:tag="f693" android:label="@string/dummyLabel" />
+  <attribution android:tag="f694" android:label="@string/dummyLabel" />
+  <attribution android:tag="f695" android:label="@string/dummyLabel" />
+  <attribution android:tag="f696" android:label="@string/dummyLabel" />
+  <attribution android:tag="f697" android:label="@string/dummyLabel" />
+  <attribution android:tag="f698" android:label="@string/dummyLabel" />
+  <attribution android:tag="f699" android:label="@string/dummyLabel" />
+  <attribution android:tag="f700" android:label="@string/dummyLabel" />
+  <attribution android:tag="f701" android:label="@string/dummyLabel" />
+  <attribution android:tag="f702" android:label="@string/dummyLabel" />
+  <attribution android:tag="f703" android:label="@string/dummyLabel" />
+  <attribution android:tag="f704" android:label="@string/dummyLabel" />
+  <attribution android:tag="f705" android:label="@string/dummyLabel" />
+  <attribution android:tag="f706" android:label="@string/dummyLabel" />
+  <attribution android:tag="f707" android:label="@string/dummyLabel" />
+  <attribution android:tag="f708" android:label="@string/dummyLabel" />
+  <attribution android:tag="f709" android:label="@string/dummyLabel" />
+  <attribution android:tag="f710" android:label="@string/dummyLabel" />
+  <attribution android:tag="f711" android:label="@string/dummyLabel" />
+  <attribution android:tag="f712" android:label="@string/dummyLabel" />
+  <attribution android:tag="f713" android:label="@string/dummyLabel" />
+  <attribution android:tag="f714" android:label="@string/dummyLabel" />
+  <attribution android:tag="f715" android:label="@string/dummyLabel" />
+  <attribution android:tag="f716" android:label="@string/dummyLabel" />
+  <attribution android:tag="f717" android:label="@string/dummyLabel" />
+  <attribution android:tag="f718" android:label="@string/dummyLabel" />
+  <attribution android:tag="f719" android:label="@string/dummyLabel" />
+  <attribution android:tag="f720" android:label="@string/dummyLabel" />
+  <attribution android:tag="f721" android:label="@string/dummyLabel" />
+  <attribution android:tag="f722" android:label="@string/dummyLabel" />
+  <attribution android:tag="f723" android:label="@string/dummyLabel" />
+  <attribution android:tag="f724" android:label="@string/dummyLabel" />
+  <attribution android:tag="f725" android:label="@string/dummyLabel" />
+  <attribution android:tag="f726" android:label="@string/dummyLabel" />
+  <attribution android:tag="f727" android:label="@string/dummyLabel" />
+  <attribution android:tag="f728" android:label="@string/dummyLabel" />
+  <attribution android:tag="f729" android:label="@string/dummyLabel" />
+  <attribution android:tag="f730" android:label="@string/dummyLabel" />
+  <attribution android:tag="f731" android:label="@string/dummyLabel" />
+  <attribution android:tag="f732" android:label="@string/dummyLabel" />
+  <attribution android:tag="f733" android:label="@string/dummyLabel" />
+  <attribution android:tag="f734" android:label="@string/dummyLabel" />
+  <attribution android:tag="f735" android:label="@string/dummyLabel" />
+  <attribution android:tag="f736" android:label="@string/dummyLabel" />
+  <attribution android:tag="f737" android:label="@string/dummyLabel" />
+  <attribution android:tag="f738" android:label="@string/dummyLabel" />
+  <attribution android:tag="f739" android:label="@string/dummyLabel" />
+  <attribution android:tag="f740" android:label="@string/dummyLabel" />
+  <attribution android:tag="f741" android:label="@string/dummyLabel" />
+  <attribution android:tag="f742" android:label="@string/dummyLabel" />
+  <attribution android:tag="f743" android:label="@string/dummyLabel" />
+  <attribution android:tag="f744" android:label="@string/dummyLabel" />
+  <attribution android:tag="f745" android:label="@string/dummyLabel" />
+  <attribution android:tag="f746" android:label="@string/dummyLabel" />
+  <attribution android:tag="f747" android:label="@string/dummyLabel" />
+  <attribution android:tag="f748" android:label="@string/dummyLabel" />
+  <attribution android:tag="f749" android:label="@string/dummyLabel" />
+  <attribution android:tag="f750" android:label="@string/dummyLabel" />
+  <attribution android:tag="f751" android:label="@string/dummyLabel" />
+  <attribution android:tag="f752" android:label="@string/dummyLabel" />
+  <attribution android:tag="f753" android:label="@string/dummyLabel" />
+  <attribution android:tag="f754" android:label="@string/dummyLabel" />
+  <attribution android:tag="f755" android:label="@string/dummyLabel" />
+  <attribution android:tag="f756" android:label="@string/dummyLabel" />
+  <attribution android:tag="f757" android:label="@string/dummyLabel" />
+  <attribution android:tag="f758" android:label="@string/dummyLabel" />
+  <attribution android:tag="f759" android:label="@string/dummyLabel" />
+  <attribution android:tag="f760" android:label="@string/dummyLabel" />
+  <attribution android:tag="f761" android:label="@string/dummyLabel" />
+  <attribution android:tag="f762" android:label="@string/dummyLabel" />
+  <attribution android:tag="f763" android:label="@string/dummyLabel" />
+  <attribution android:tag="f764" android:label="@string/dummyLabel" />
+  <attribution android:tag="f765" android:label="@string/dummyLabel" />
+  <attribution android:tag="f766" android:label="@string/dummyLabel" />
+  <attribution android:tag="f767" android:label="@string/dummyLabel" />
+  <attribution android:tag="f768" android:label="@string/dummyLabel" />
+  <attribution android:tag="f769" android:label="@string/dummyLabel" />
+  <attribution android:tag="f770" android:label="@string/dummyLabel" />
+  <attribution android:tag="f771" android:label="@string/dummyLabel" />
+  <attribution android:tag="f772" android:label="@string/dummyLabel" />
+  <attribution android:tag="f773" android:label="@string/dummyLabel" />
+  <attribution android:tag="f774" android:label="@string/dummyLabel" />
+  <attribution android:tag="f775" android:label="@string/dummyLabel" />
+  <attribution android:tag="f776" android:label="@string/dummyLabel" />
+  <attribution android:tag="f777" android:label="@string/dummyLabel" />
+  <attribution android:tag="f778" android:label="@string/dummyLabel" />
+  <attribution android:tag="f779" android:label="@string/dummyLabel" />
+  <attribution android:tag="f780" android:label="@string/dummyLabel" />
+  <attribution android:tag="f781" android:label="@string/dummyLabel" />
+  <attribution android:tag="f782" android:label="@string/dummyLabel" />
+  <attribution android:tag="f783" android:label="@string/dummyLabel" />
+  <attribution android:tag="f784" android:label="@string/dummyLabel" />
+  <attribution android:tag="f785" android:label="@string/dummyLabel" />
+  <attribution android:tag="f786" android:label="@string/dummyLabel" />
+  <attribution android:tag="f787" android:label="@string/dummyLabel" />
+  <attribution android:tag="f788" android:label="@string/dummyLabel" />
+  <attribution android:tag="f789" android:label="@string/dummyLabel" />
+  <attribution android:tag="f790" android:label="@string/dummyLabel" />
+  <attribution android:tag="f791" android:label="@string/dummyLabel" />
+  <attribution android:tag="f792" android:label="@string/dummyLabel" />
+  <attribution android:tag="f793" android:label="@string/dummyLabel" />
+  <attribution android:tag="f794" android:label="@string/dummyLabel" />
+  <attribution android:tag="f795" android:label="@string/dummyLabel" />
+  <attribution android:tag="f796" android:label="@string/dummyLabel" />
+  <attribution android:tag="f797" android:label="@string/dummyLabel" />
+  <attribution android:tag="f798" android:label="@string/dummyLabel" />
+  <attribution android:tag="f799" android:label="@string/dummyLabel" />
+  <attribution android:tag="f800" android:label="@string/dummyLabel" />
+  <attribution android:tag="f801" android:label="@string/dummyLabel" />
+  <attribution android:tag="f802" android:label="@string/dummyLabel" />
+  <attribution android:tag="f803" android:label="@string/dummyLabel" />
+  <attribution android:tag="f804" android:label="@string/dummyLabel" />
+  <attribution android:tag="f805" android:label="@string/dummyLabel" />
+  <attribution android:tag="f806" android:label="@string/dummyLabel" />
+  <attribution android:tag="f807" android:label="@string/dummyLabel" />
+  <attribution android:tag="f808" android:label="@string/dummyLabel" />
+  <attribution android:tag="f809" android:label="@string/dummyLabel" />
+  <attribution android:tag="f810" android:label="@string/dummyLabel" />
+  <attribution android:tag="f811" android:label="@string/dummyLabel" />
+  <attribution android:tag="f812" android:label="@string/dummyLabel" />
+  <attribution android:tag="f813" android:label="@string/dummyLabel" />
+  <attribution android:tag="f814" android:label="@string/dummyLabel" />
+  <attribution android:tag="f815" android:label="@string/dummyLabel" />
+  <attribution android:tag="f816" android:label="@string/dummyLabel" />
+  <attribution android:tag="f817" android:label="@string/dummyLabel" />
+  <attribution android:tag="f818" android:label="@string/dummyLabel" />
+  <attribution android:tag="f819" android:label="@string/dummyLabel" />
+  <attribution android:tag="f820" android:label="@string/dummyLabel" />
+  <attribution android:tag="f821" android:label="@string/dummyLabel" />
+  <attribution android:tag="f822" android:label="@string/dummyLabel" />
+  <attribution android:tag="f823" android:label="@string/dummyLabel" />
+  <attribution android:tag="f824" android:label="@string/dummyLabel" />
+  <attribution android:tag="f825" android:label="@string/dummyLabel" />
+  <attribution android:tag="f826" android:label="@string/dummyLabel" />
+  <attribution android:tag="f827" android:label="@string/dummyLabel" />
+  <attribution android:tag="f828" android:label="@string/dummyLabel" />
+  <attribution android:tag="f829" android:label="@string/dummyLabel" />
+  <attribution android:tag="f830" android:label="@string/dummyLabel" />
+  <attribution android:tag="f831" android:label="@string/dummyLabel" />
+  <attribution android:tag="f832" android:label="@string/dummyLabel" />
+  <attribution android:tag="f833" android:label="@string/dummyLabel" />
+  <attribution android:tag="f834" android:label="@string/dummyLabel" />
+  <attribution android:tag="f835" android:label="@string/dummyLabel" />
+  <attribution android:tag="f836" android:label="@string/dummyLabel" />
+  <attribution android:tag="f837" android:label="@string/dummyLabel" />
+  <attribution android:tag="f838" android:label="@string/dummyLabel" />
+  <attribution android:tag="f839" android:label="@string/dummyLabel" />
+  <attribution android:tag="f840" android:label="@string/dummyLabel" />
+  <attribution android:tag="f841" android:label="@string/dummyLabel" />
+  <attribution android:tag="f842" android:label="@string/dummyLabel" />
+  <attribution android:tag="f843" android:label="@string/dummyLabel" />
+  <attribution android:tag="f844" android:label="@string/dummyLabel" />
+  <attribution android:tag="f845" android:label="@string/dummyLabel" />
+  <attribution android:tag="f846" android:label="@string/dummyLabel" />
+  <attribution android:tag="f847" android:label="@string/dummyLabel" />
+  <attribution android:tag="f848" android:label="@string/dummyLabel" />
+  <attribution android:tag="f849" android:label="@string/dummyLabel" />
+  <attribution android:tag="f850" android:label="@string/dummyLabel" />
+  <attribution android:tag="f851" android:label="@string/dummyLabel" />
+  <attribution android:tag="f852" android:label="@string/dummyLabel" />
+  <attribution android:tag="f853" android:label="@string/dummyLabel" />
+  <attribution android:tag="f854" android:label="@string/dummyLabel" />
+  <attribution android:tag="f855" android:label="@string/dummyLabel" />
+  <attribution android:tag="f856" android:label="@string/dummyLabel" />
+  <attribution android:tag="f857" android:label="@string/dummyLabel" />
+  <attribution android:tag="f858" android:label="@string/dummyLabel" />
+  <attribution android:tag="f859" android:label="@string/dummyLabel" />
+  <attribution android:tag="f860" android:label="@string/dummyLabel" />
+  <attribution android:tag="f861" android:label="@string/dummyLabel" />
+  <attribution android:tag="f862" android:label="@string/dummyLabel" />
+  <attribution android:tag="f863" android:label="@string/dummyLabel" />
+  <attribution android:tag="f864" android:label="@string/dummyLabel" />
+  <attribution android:tag="f865" android:label="@string/dummyLabel" />
+  <attribution android:tag="f866" android:label="@string/dummyLabel" />
+  <attribution android:tag="f867" android:label="@string/dummyLabel" />
+  <attribution android:tag="f868" android:label="@string/dummyLabel" />
+  <attribution android:tag="f869" android:label="@string/dummyLabel" />
+  <attribution android:tag="f870" android:label="@string/dummyLabel" />
+  <attribution android:tag="f871" android:label="@string/dummyLabel" />
+  <attribution android:tag="f872" android:label="@string/dummyLabel" />
+  <attribution android:tag="f873" android:label="@string/dummyLabel" />
+  <attribution android:tag="f874" android:label="@string/dummyLabel" />
+  <attribution android:tag="f875" android:label="@string/dummyLabel" />
+  <attribution android:tag="f876" android:label="@string/dummyLabel" />
+  <attribution android:tag="f877" android:label="@string/dummyLabel" />
+  <attribution android:tag="f878" android:label="@string/dummyLabel" />
+  <attribution android:tag="f879" android:label="@string/dummyLabel" />
+  <attribution android:tag="f880" android:label="@string/dummyLabel" />
+  <attribution android:tag="f881" android:label="@string/dummyLabel" />
+  <attribution android:tag="f882" android:label="@string/dummyLabel" />
+  <attribution android:tag="f883" android:label="@string/dummyLabel" />
+  <attribution android:tag="f884" android:label="@string/dummyLabel" />
+  <attribution android:tag="f885" android:label="@string/dummyLabel" />
+  <attribution android:tag="f886" android:label="@string/dummyLabel" />
+  <attribution android:tag="f887" android:label="@string/dummyLabel" />
+  <attribution android:tag="f888" android:label="@string/dummyLabel" />
+  <attribution android:tag="f889" android:label="@string/dummyLabel" />
+  <attribution android:tag="f890" android:label="@string/dummyLabel" />
+  <attribution android:tag="f891" android:label="@string/dummyLabel" />
+  <attribution android:tag="f892" android:label="@string/dummyLabel" />
+  <attribution android:tag="f893" android:label="@string/dummyLabel" />
+  <attribution android:tag="f894" android:label="@string/dummyLabel" />
+  <attribution android:tag="f895" android:label="@string/dummyLabel" />
+  <attribution android:tag="f896" android:label="@string/dummyLabel" />
+  <attribution android:tag="f897" android:label="@string/dummyLabel" />
+  <attribution android:tag="f898" android:label="@string/dummyLabel" />
+  <attribution android:tag="f899" android:label="@string/dummyLabel" />
+  <attribution android:tag="f900" android:label="@string/dummyLabel" />
+  <attribution android:tag="f901" android:label="@string/dummyLabel" />
+  <attribution android:tag="f902" android:label="@string/dummyLabel" />
+  <attribution android:tag="f903" android:label="@string/dummyLabel" />
+  <attribution android:tag="f904" android:label="@string/dummyLabel" />
+  <attribution android:tag="f905" android:label="@string/dummyLabel" />
+  <attribution android:tag="f906" android:label="@string/dummyLabel" />
+  <attribution android:tag="f907" android:label="@string/dummyLabel" />
+  <attribution android:tag="f908" android:label="@string/dummyLabel" />
+  <attribution android:tag="f909" android:label="@string/dummyLabel" />
+  <attribution android:tag="f910" android:label="@string/dummyLabel" />
+  <attribution android:tag="f911" android:label="@string/dummyLabel" />
+  <attribution android:tag="f912" android:label="@string/dummyLabel" />
+  <attribution android:tag="f913" android:label="@string/dummyLabel" />
+  <attribution android:tag="f914" android:label="@string/dummyLabel" />
+  <attribution android:tag="f915" android:label="@string/dummyLabel" />
+  <attribution android:tag="f916" android:label="@string/dummyLabel" />
+  <attribution android:tag="f917" android:label="@string/dummyLabel" />
+  <attribution android:tag="f918" android:label="@string/dummyLabel" />
+  <attribution android:tag="f919" android:label="@string/dummyLabel" />
+  <attribution android:tag="f920" android:label="@string/dummyLabel" />
+  <attribution android:tag="f921" android:label="@string/dummyLabel" />
+  <attribution android:tag="f922" android:label="@string/dummyLabel" />
+  <attribution android:tag="f923" android:label="@string/dummyLabel" />
+  <attribution android:tag="f924" android:label="@string/dummyLabel" />
+  <attribution android:tag="f925" android:label="@string/dummyLabel" />
+  <attribution android:tag="f926" android:label="@string/dummyLabel" />
+  <attribution android:tag="f927" android:label="@string/dummyLabel" />
+  <attribution android:tag="f928" android:label="@string/dummyLabel" />
+  <attribution android:tag="f929" android:label="@string/dummyLabel" />
+  <attribution android:tag="f930" android:label="@string/dummyLabel" />
+  <attribution android:tag="f931" android:label="@string/dummyLabel" />
+  <attribution android:tag="f932" android:label="@string/dummyLabel" />
+  <attribution android:tag="f933" android:label="@string/dummyLabel" />
+  <attribution android:tag="f934" android:label="@string/dummyLabel" />
+  <attribution android:tag="f935" android:label="@string/dummyLabel" />
+  <attribution android:tag="f936" android:label="@string/dummyLabel" />
+  <attribution android:tag="f937" android:label="@string/dummyLabel" />
+  <attribution android:tag="f938" android:label="@string/dummyLabel" />
+  <attribution android:tag="f939" android:label="@string/dummyLabel" />
+  <attribution android:tag="f940" android:label="@string/dummyLabel" />
+  <attribution android:tag="f941" android:label="@string/dummyLabel" />
+  <attribution android:tag="f942" android:label="@string/dummyLabel" />
+  <attribution android:tag="f943" android:label="@string/dummyLabel" />
+  <attribution android:tag="f944" android:label="@string/dummyLabel" />
+  <attribution android:tag="f945" android:label="@string/dummyLabel" />
+  <attribution android:tag="f946" android:label="@string/dummyLabel" />
+  <attribution android:tag="f947" android:label="@string/dummyLabel" />
+  <attribution android:tag="f948" android:label="@string/dummyLabel" />
+  <attribution android:tag="f949" android:label="@string/dummyLabel" />
+  <attribution android:tag="f950" android:label="@string/dummyLabel" />
+  <attribution android:tag="f951" android:label="@string/dummyLabel" />
+  <attribution android:tag="f952" android:label="@string/dummyLabel" />
+  <attribution android:tag="f953" android:label="@string/dummyLabel" />
+  <attribution android:tag="f954" android:label="@string/dummyLabel" />
+  <attribution android:tag="f955" android:label="@string/dummyLabel" />
+  <attribution android:tag="f956" android:label="@string/dummyLabel" />
+  <attribution android:tag="f957" android:label="@string/dummyLabel" />
+  <attribution android:tag="f958" android:label="@string/dummyLabel" />
+  <attribution android:tag="f959" android:label="@string/dummyLabel" />
+  <attribution android:tag="f960" android:label="@string/dummyLabel" />
+  <attribution android:tag="f961" android:label="@string/dummyLabel" />
+  <attribution android:tag="f962" android:label="@string/dummyLabel" />
+  <attribution android:tag="f963" android:label="@string/dummyLabel" />
+  <attribution android:tag="f964" android:label="@string/dummyLabel" />
+  <attribution android:tag="f965" android:label="@string/dummyLabel" />
+  <attribution android:tag="f966" android:label="@string/dummyLabel" />
+  <attribution android:tag="f967" android:label="@string/dummyLabel" />
+  <attribution android:tag="f968" android:label="@string/dummyLabel" />
+  <attribution android:tag="f969" android:label="@string/dummyLabel" />
+  <attribution android:tag="f970" android:label="@string/dummyLabel" />
+  <attribution android:tag="f971" android:label="@string/dummyLabel" />
+  <attribution android:tag="f972" android:label="@string/dummyLabel" />
+  <attribution android:tag="f973" android:label="@string/dummyLabel" />
+  <attribution android:tag="f974" android:label="@string/dummyLabel" />
+  <attribution android:tag="f975" android:label="@string/dummyLabel" />
+  <attribution android:tag="f976" android:label="@string/dummyLabel" />
+  <attribution android:tag="f977" android:label="@string/dummyLabel" />
+  <attribution android:tag="f978" android:label="@string/dummyLabel" />
+  <attribution android:tag="f979" android:label="@string/dummyLabel" />
+  <attribution android:tag="f980" android:label="@string/dummyLabel" />
+  <attribution android:tag="f981" android:label="@string/dummyLabel" />
+  <attribution android:tag="f982" android:label="@string/dummyLabel" />
+  <attribution android:tag="f983" android:label="@string/dummyLabel" />
+  <attribution android:tag="f984" android:label="@string/dummyLabel" />
+  <attribution android:tag="f985" android:label="@string/dummyLabel" />
+  <attribution android:tag="f986" android:label="@string/dummyLabel" />
+  <attribution android:tag="f987" android:label="@string/dummyLabel" />
+  <attribution android:tag="f988" android:label="@string/dummyLabel" />
+  <attribution android:tag="f989" android:label="@string/dummyLabel" />
+  <attribution android:tag="f990" android:label="@string/dummyLabel" />
+  <attribution android:tag="f991" android:label="@string/dummyLabel" />
+  <attribution android:tag="f992" android:label="@string/dummyLabel" />
+  <attribution android:tag="f993" android:label="@string/dummyLabel" />
+  <attribution android:tag="f994" android:label="@string/dummyLabel" />
+  <attribution android:tag="f995" android:label="@string/dummyLabel" />
+  <attribution android:tag="f996" android:label="@string/dummyLabel" />
+  <attribution android:tag="f997" android:label="@string/dummyLabel" />
+  <attribution android:tag="f998" android:label="@string/dummyLabel" />
+  <attribution android:tag="f999" android:label="@string/dummyLabel" />
+
+  <attribution android:tag="toomany" android:label="@string/dummyLabel" />
+
+  <application />
+
+</manifest>
diff --git a/tests/tests/appop/AppWithTooManyFeatures/res/values/strings.xml b/tests/tests/appop/AppWithTooManyAttributions/res/values/strings.xml
similarity index 100%
rename from tests/tests/appop/AppWithTooManyFeatures/res/values/strings.xml
rename to tests/tests/appop/AppWithTooManyAttributions/res/values/strings.xml
diff --git a/tests/tests/appop/AppWithTooManyFeatures/Android.bp b/tests/tests/appop/AppWithTooManyFeatures/Android.bp
deleted file mode 100644
index bc769d6..0000000
--- a/tests/tests/appop/AppWithTooManyFeatures/Android.bp
+++ /dev/null
@@ -1,23 +0,0 @@
-// Copyright (C) 2020 The Android Open Source Project
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-android_test_helper_app {
-    name: "AppWithTooManyFeatures",
-
-    test_suites: [
-        "cts",
-        "vts",
-        "general-tests",
-    ]
-}
\ No newline at end of file
diff --git a/tests/tests/appop/AppWithTooManyFeatures/AndroidManifest.xml b/tests/tests/appop/AppWithTooManyFeatures/AndroidManifest.xml
deleted file mode 100644
index eeecef7..0000000
--- a/tests/tests/appop/AppWithTooManyFeatures/AndroidManifest.xml
+++ /dev/null
@@ -1,1028 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-
-<!--
-  ~ Copyright (C) 2020 The Android Open Source Project
-  ~
-  ~ Licensed under the Apache License, Version 2.0 (the "License");
-  ~ you may not use this file except in compliance with the License.
-  ~ You may obtain a copy of the License at
-  ~
-  ~      http://www.apache.org/licenses/LICENSE-2.0
-  ~
-  ~ Unless required by applicable law or agreed to in writing, software
-  ~ distributed under the License is distributed on an "AS IS" BASIS,
-  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-  ~ See the License for the specific language governing permissions and
-  ~ limitations under the License.
-  -->
-
-<manifest xmlns:android="http://schemas.android.com/apk/res/android"
-    package="android.app.appops.cts.appwithtoomanyfeatures">
-
-  <!-- 1000 features are allowed -->
-  <feature android:featureId="f0" android:label="@string/dummyLabel" />
-  <feature android:featureId="f1" android:label="@string/dummyLabel" />
-  <feature android:featureId="f2" android:label="@string/dummyLabel" />
-  <feature android:featureId="f3" android:label="@string/dummyLabel" />
-  <feature android:featureId="f4" android:label="@string/dummyLabel" />
-  <feature android:featureId="f5" android:label="@string/dummyLabel" />
-  <feature android:featureId="f6" android:label="@string/dummyLabel" />
-  <feature android:featureId="f7" android:label="@string/dummyLabel" />
-  <feature android:featureId="f8" android:label="@string/dummyLabel" />
-  <feature android:featureId="f9" android:label="@string/dummyLabel" />
-  <feature android:featureId="f10" android:label="@string/dummyLabel" />
-  <feature android:featureId="f11" android:label="@string/dummyLabel" />
-  <feature android:featureId="f12" android:label="@string/dummyLabel" />
-  <feature android:featureId="f13" android:label="@string/dummyLabel" />
-  <feature android:featureId="f14" android:label="@string/dummyLabel" />
-  <feature android:featureId="f15" android:label="@string/dummyLabel" />
-  <feature android:featureId="f16" android:label="@string/dummyLabel" />
-  <feature android:featureId="f17" android:label="@string/dummyLabel" />
-  <feature android:featureId="f18" android:label="@string/dummyLabel" />
-  <feature android:featureId="f19" android:label="@string/dummyLabel" />
-  <feature android:featureId="f20" android:label="@string/dummyLabel" />
-  <feature android:featureId="f21" android:label="@string/dummyLabel" />
-  <feature android:featureId="f22" android:label="@string/dummyLabel" />
-  <feature android:featureId="f23" android:label="@string/dummyLabel" />
-  <feature android:featureId="f24" android:label="@string/dummyLabel" />
-  <feature android:featureId="f25" android:label="@string/dummyLabel" />
-  <feature android:featureId="f26" android:label="@string/dummyLabel" />
-  <feature android:featureId="f27" android:label="@string/dummyLabel" />
-  <feature android:featureId="f28" android:label="@string/dummyLabel" />
-  <feature android:featureId="f29" android:label="@string/dummyLabel" />
-  <feature android:featureId="f30" android:label="@string/dummyLabel" />
-  <feature android:featureId="f31" android:label="@string/dummyLabel" />
-  <feature android:featureId="f32" android:label="@string/dummyLabel" />
-  <feature android:featureId="f33" android:label="@string/dummyLabel" />
-  <feature android:featureId="f34" android:label="@string/dummyLabel" />
-  <feature android:featureId="f35" android:label="@string/dummyLabel" />
-  <feature android:featureId="f36" android:label="@string/dummyLabel" />
-  <feature android:featureId="f37" android:label="@string/dummyLabel" />
-  <feature android:featureId="f38" android:label="@string/dummyLabel" />
-  <feature android:featureId="f39" android:label="@string/dummyLabel" />
-  <feature android:featureId="f40" android:label="@string/dummyLabel" />
-  <feature android:featureId="f41" android:label="@string/dummyLabel" />
-  <feature android:featureId="f42" android:label="@string/dummyLabel" />
-  <feature android:featureId="f43" android:label="@string/dummyLabel" />
-  <feature android:featureId="f44" android:label="@string/dummyLabel" />
-  <feature android:featureId="f45" android:label="@string/dummyLabel" />
-  <feature android:featureId="f46" android:label="@string/dummyLabel" />
-  <feature android:featureId="f47" android:label="@string/dummyLabel" />
-  <feature android:featureId="f48" android:label="@string/dummyLabel" />
-  <feature android:featureId="f49" android:label="@string/dummyLabel" />
-  <feature android:featureId="f50" android:label="@string/dummyLabel" />
-  <feature android:featureId="f51" android:label="@string/dummyLabel" />
-  <feature android:featureId="f52" android:label="@string/dummyLabel" />
-  <feature android:featureId="f53" android:label="@string/dummyLabel" />
-  <feature android:featureId="f54" android:label="@string/dummyLabel" />
-  <feature android:featureId="f55" android:label="@string/dummyLabel" />
-  <feature android:featureId="f56" android:label="@string/dummyLabel" />
-  <feature android:featureId="f57" android:label="@string/dummyLabel" />
-  <feature android:featureId="f58" android:label="@string/dummyLabel" />
-  <feature android:featureId="f59" android:label="@string/dummyLabel" />
-  <feature android:featureId="f60" android:label="@string/dummyLabel" />
-  <feature android:featureId="f61" android:label="@string/dummyLabel" />
-  <feature android:featureId="f62" android:label="@string/dummyLabel" />
-  <feature android:featureId="f63" android:label="@string/dummyLabel" />
-  <feature android:featureId="f64" android:label="@string/dummyLabel" />
-  <feature android:featureId="f65" android:label="@string/dummyLabel" />
-  <feature android:featureId="f66" android:label="@string/dummyLabel" />
-  <feature android:featureId="f67" android:label="@string/dummyLabel" />
-  <feature android:featureId="f68" android:label="@string/dummyLabel" />
-  <feature android:featureId="f69" android:label="@string/dummyLabel" />
-  <feature android:featureId="f70" android:label="@string/dummyLabel" />
-  <feature android:featureId="f71" android:label="@string/dummyLabel" />
-  <feature android:featureId="f72" android:label="@string/dummyLabel" />
-  <feature android:featureId="f73" android:label="@string/dummyLabel" />
-  <feature android:featureId="f74" android:label="@string/dummyLabel" />
-  <feature android:featureId="f75" android:label="@string/dummyLabel" />
-  <feature android:featureId="f76" android:label="@string/dummyLabel" />
-  <feature android:featureId="f77" android:label="@string/dummyLabel" />
-  <feature android:featureId="f78" android:label="@string/dummyLabel" />
-  <feature android:featureId="f79" android:label="@string/dummyLabel" />
-  <feature android:featureId="f80" android:label="@string/dummyLabel" />
-  <feature android:featureId="f81" android:label="@string/dummyLabel" />
-  <feature android:featureId="f82" android:label="@string/dummyLabel" />
-  <feature android:featureId="f83" android:label="@string/dummyLabel" />
-  <feature android:featureId="f84" android:label="@string/dummyLabel" />
-  <feature android:featureId="f85" android:label="@string/dummyLabel" />
-  <feature android:featureId="f86" android:label="@string/dummyLabel" />
-  <feature android:featureId="f87" android:label="@string/dummyLabel" />
-  <feature android:featureId="f88" android:label="@string/dummyLabel" />
-  <feature android:featureId="f89" android:label="@string/dummyLabel" />
-  <feature android:featureId="f90" android:label="@string/dummyLabel" />
-  <feature android:featureId="f91" android:label="@string/dummyLabel" />
-  <feature android:featureId="f92" android:label="@string/dummyLabel" />
-  <feature android:featureId="f93" android:label="@string/dummyLabel" />
-  <feature android:featureId="f94" android:label="@string/dummyLabel" />
-  <feature android:featureId="f95" android:label="@string/dummyLabel" />
-  <feature android:featureId="f96" android:label="@string/dummyLabel" />
-  <feature android:featureId="f97" android:label="@string/dummyLabel" />
-  <feature android:featureId="f98" android:label="@string/dummyLabel" />
-  <feature android:featureId="f99" android:label="@string/dummyLabel" />
-  <feature android:featureId="f100" android:label="@string/dummyLabel" />
-  <feature android:featureId="f101" android:label="@string/dummyLabel" />
-  <feature android:featureId="f102" android:label="@string/dummyLabel" />
-  <feature android:featureId="f103" android:label="@string/dummyLabel" />
-  <feature android:featureId="f104" android:label="@string/dummyLabel" />
-  <feature android:featureId="f105" android:label="@string/dummyLabel" />
-  <feature android:featureId="f106" android:label="@string/dummyLabel" />
-  <feature android:featureId="f107" android:label="@string/dummyLabel" />
-  <feature android:featureId="f108" android:label="@string/dummyLabel" />
-  <feature android:featureId="f109" android:label="@string/dummyLabel" />
-  <feature android:featureId="f110" android:label="@string/dummyLabel" />
-  <feature android:featureId="f111" android:label="@string/dummyLabel" />
-  <feature android:featureId="f112" android:label="@string/dummyLabel" />
-  <feature android:featureId="f113" android:label="@string/dummyLabel" />
-  <feature android:featureId="f114" android:label="@string/dummyLabel" />
-  <feature android:featureId="f115" android:label="@string/dummyLabel" />
-  <feature android:featureId="f116" android:label="@string/dummyLabel" />
-  <feature android:featureId="f117" android:label="@string/dummyLabel" />
-  <feature android:featureId="f118" android:label="@string/dummyLabel" />
-  <feature android:featureId="f119" android:label="@string/dummyLabel" />
-  <feature android:featureId="f120" android:label="@string/dummyLabel" />
-  <feature android:featureId="f121" android:label="@string/dummyLabel" />
-  <feature android:featureId="f122" android:label="@string/dummyLabel" />
-  <feature android:featureId="f123" android:label="@string/dummyLabel" />
-  <feature android:featureId="f124" android:label="@string/dummyLabel" />
-  <feature android:featureId="f125" android:label="@string/dummyLabel" />
-  <feature android:featureId="f126" android:label="@string/dummyLabel" />
-  <feature android:featureId="f127" android:label="@string/dummyLabel" />
-  <feature android:featureId="f128" android:label="@string/dummyLabel" />
-  <feature android:featureId="f129" android:label="@string/dummyLabel" />
-  <feature android:featureId="f130" android:label="@string/dummyLabel" />
-  <feature android:featureId="f131" android:label="@string/dummyLabel" />
-  <feature android:featureId="f132" android:label="@string/dummyLabel" />
-  <feature android:featureId="f133" android:label="@string/dummyLabel" />
-  <feature android:featureId="f134" android:label="@string/dummyLabel" />
-  <feature android:featureId="f135" android:label="@string/dummyLabel" />
-  <feature android:featureId="f136" android:label="@string/dummyLabel" />
-  <feature android:featureId="f137" android:label="@string/dummyLabel" />
-  <feature android:featureId="f138" android:label="@string/dummyLabel" />
-  <feature android:featureId="f139" android:label="@string/dummyLabel" />
-  <feature android:featureId="f140" android:label="@string/dummyLabel" />
-  <feature android:featureId="f141" android:label="@string/dummyLabel" />
-  <feature android:featureId="f142" android:label="@string/dummyLabel" />
-  <feature android:featureId="f143" android:label="@string/dummyLabel" />
-  <feature android:featureId="f144" android:label="@string/dummyLabel" />
-  <feature android:featureId="f145" android:label="@string/dummyLabel" />
-  <feature android:featureId="f146" android:label="@string/dummyLabel" />
-  <feature android:featureId="f147" android:label="@string/dummyLabel" />
-  <feature android:featureId="f148" android:label="@string/dummyLabel" />
-  <feature android:featureId="f149" android:label="@string/dummyLabel" />
-  <feature android:featureId="f150" android:label="@string/dummyLabel" />
-  <feature android:featureId="f151" android:label="@string/dummyLabel" />
-  <feature android:featureId="f152" android:label="@string/dummyLabel" />
-  <feature android:featureId="f153" android:label="@string/dummyLabel" />
-  <feature android:featureId="f154" android:label="@string/dummyLabel" />
-  <feature android:featureId="f155" android:label="@string/dummyLabel" />
-  <feature android:featureId="f156" android:label="@string/dummyLabel" />
-  <feature android:featureId="f157" android:label="@string/dummyLabel" />
-  <feature android:featureId="f158" android:label="@string/dummyLabel" />
-  <feature android:featureId="f159" android:label="@string/dummyLabel" />
-  <feature android:featureId="f160" android:label="@string/dummyLabel" />
-  <feature android:featureId="f161" android:label="@string/dummyLabel" />
-  <feature android:featureId="f162" android:label="@string/dummyLabel" />
-  <feature android:featureId="f163" android:label="@string/dummyLabel" />
-  <feature android:featureId="f164" android:label="@string/dummyLabel" />
-  <feature android:featureId="f165" android:label="@string/dummyLabel" />
-  <feature android:featureId="f166" android:label="@string/dummyLabel" />
-  <feature android:featureId="f167" android:label="@string/dummyLabel" />
-  <feature android:featureId="f168" android:label="@string/dummyLabel" />
-  <feature android:featureId="f169" android:label="@string/dummyLabel" />
-  <feature android:featureId="f170" android:label="@string/dummyLabel" />
-  <feature android:featureId="f171" android:label="@string/dummyLabel" />
-  <feature android:featureId="f172" android:label="@string/dummyLabel" />
-  <feature android:featureId="f173" android:label="@string/dummyLabel" />
-  <feature android:featureId="f174" android:label="@string/dummyLabel" />
-  <feature android:featureId="f175" android:label="@string/dummyLabel" />
-  <feature android:featureId="f176" android:label="@string/dummyLabel" />
-  <feature android:featureId="f177" android:label="@string/dummyLabel" />
-  <feature android:featureId="f178" android:label="@string/dummyLabel" />
-  <feature android:featureId="f179" android:label="@string/dummyLabel" />
-  <feature android:featureId="f180" android:label="@string/dummyLabel" />
-  <feature android:featureId="f181" android:label="@string/dummyLabel" />
-  <feature android:featureId="f182" android:label="@string/dummyLabel" />
-  <feature android:featureId="f183" android:label="@string/dummyLabel" />
-  <feature android:featureId="f184" android:label="@string/dummyLabel" />
-  <feature android:featureId="f185" android:label="@string/dummyLabel" />
-  <feature android:featureId="f186" android:label="@string/dummyLabel" />
-  <feature android:featureId="f187" android:label="@string/dummyLabel" />
-  <feature android:featureId="f188" android:label="@string/dummyLabel" />
-  <feature android:featureId="f189" android:label="@string/dummyLabel" />
-  <feature android:featureId="f190" android:label="@string/dummyLabel" />
-  <feature android:featureId="f191" android:label="@string/dummyLabel" />
-  <feature android:featureId="f192" android:label="@string/dummyLabel" />
-  <feature android:featureId="f193" android:label="@string/dummyLabel" />
-  <feature android:featureId="f194" android:label="@string/dummyLabel" />
-  <feature android:featureId="f195" android:label="@string/dummyLabel" />
-  <feature android:featureId="f196" android:label="@string/dummyLabel" />
-  <feature android:featureId="f197" android:label="@string/dummyLabel" />
-  <feature android:featureId="f198" android:label="@string/dummyLabel" />
-  <feature android:featureId="f199" android:label="@string/dummyLabel" />
-  <feature android:featureId="f200" android:label="@string/dummyLabel" />
-  <feature android:featureId="f201" android:label="@string/dummyLabel" />
-  <feature android:featureId="f202" android:label="@string/dummyLabel" />
-  <feature android:featureId="f203" android:label="@string/dummyLabel" />
-  <feature android:featureId="f204" android:label="@string/dummyLabel" />
-  <feature android:featureId="f205" android:label="@string/dummyLabel" />
-  <feature android:featureId="f206" android:label="@string/dummyLabel" />
-  <feature android:featureId="f207" android:label="@string/dummyLabel" />
-  <feature android:featureId="f208" android:label="@string/dummyLabel" />
-  <feature android:featureId="f209" android:label="@string/dummyLabel" />
-  <feature android:featureId="f210" android:label="@string/dummyLabel" />
-  <feature android:featureId="f211" android:label="@string/dummyLabel" />
-  <feature android:featureId="f212" android:label="@string/dummyLabel" />
-  <feature android:featureId="f213" android:label="@string/dummyLabel" />
-  <feature android:featureId="f214" android:label="@string/dummyLabel" />
-  <feature android:featureId="f215" android:label="@string/dummyLabel" />
-  <feature android:featureId="f216" android:label="@string/dummyLabel" />
-  <feature android:featureId="f217" android:label="@string/dummyLabel" />
-  <feature android:featureId="f218" android:label="@string/dummyLabel" />
-  <feature android:featureId="f219" android:label="@string/dummyLabel" />
-  <feature android:featureId="f220" android:label="@string/dummyLabel" />
-  <feature android:featureId="f221" android:label="@string/dummyLabel" />
-  <feature android:featureId="f222" android:label="@string/dummyLabel" />
-  <feature android:featureId="f223" android:label="@string/dummyLabel" />
-  <feature android:featureId="f224" android:label="@string/dummyLabel" />
-  <feature android:featureId="f225" android:label="@string/dummyLabel" />
-  <feature android:featureId="f226" android:label="@string/dummyLabel" />
-  <feature android:featureId="f227" android:label="@string/dummyLabel" />
-  <feature android:featureId="f228" android:label="@string/dummyLabel" />
-  <feature android:featureId="f229" android:label="@string/dummyLabel" />
-  <feature android:featureId="f230" android:label="@string/dummyLabel" />
-  <feature android:featureId="f231" android:label="@string/dummyLabel" />
-  <feature android:featureId="f232" android:label="@string/dummyLabel" />
-  <feature android:featureId="f233" android:label="@string/dummyLabel" />
-  <feature android:featureId="f234" android:label="@string/dummyLabel" />
-  <feature android:featureId="f235" android:label="@string/dummyLabel" />
-  <feature android:featureId="f236" android:label="@string/dummyLabel" />
-  <feature android:featureId="f237" android:label="@string/dummyLabel" />
-  <feature android:featureId="f238" android:label="@string/dummyLabel" />
-  <feature android:featureId="f239" android:label="@string/dummyLabel" />
-  <feature android:featureId="f240" android:label="@string/dummyLabel" />
-  <feature android:featureId="f241" android:label="@string/dummyLabel" />
-  <feature android:featureId="f242" android:label="@string/dummyLabel" />
-  <feature android:featureId="f243" android:label="@string/dummyLabel" />
-  <feature android:featureId="f244" android:label="@string/dummyLabel" />
-  <feature android:featureId="f245" android:label="@string/dummyLabel" />
-  <feature android:featureId="f246" android:label="@string/dummyLabel" />
-  <feature android:featureId="f247" android:label="@string/dummyLabel" />
-  <feature android:featureId="f248" android:label="@string/dummyLabel" />
-  <feature android:featureId="f249" android:label="@string/dummyLabel" />
-  <feature android:featureId="f250" android:label="@string/dummyLabel" />
-  <feature android:featureId="f251" android:label="@string/dummyLabel" />
-  <feature android:featureId="f252" android:label="@string/dummyLabel" />
-  <feature android:featureId="f253" android:label="@string/dummyLabel" />
-  <feature android:featureId="f254" android:label="@string/dummyLabel" />
-  <feature android:featureId="f255" android:label="@string/dummyLabel" />
-  <feature android:featureId="f256" android:label="@string/dummyLabel" />
-  <feature android:featureId="f257" android:label="@string/dummyLabel" />
-  <feature android:featureId="f258" android:label="@string/dummyLabel" />
-  <feature android:featureId="f259" android:label="@string/dummyLabel" />
-  <feature android:featureId="f260" android:label="@string/dummyLabel" />
-  <feature android:featureId="f261" android:label="@string/dummyLabel" />
-  <feature android:featureId="f262" android:label="@string/dummyLabel" />
-  <feature android:featureId="f263" android:label="@string/dummyLabel" />
-  <feature android:featureId="f264" android:label="@string/dummyLabel" />
-  <feature android:featureId="f265" android:label="@string/dummyLabel" />
-  <feature android:featureId="f266" android:label="@string/dummyLabel" />
-  <feature android:featureId="f267" android:label="@string/dummyLabel" />
-  <feature android:featureId="f268" android:label="@string/dummyLabel" />
-  <feature android:featureId="f269" android:label="@string/dummyLabel" />
-  <feature android:featureId="f270" android:label="@string/dummyLabel" />
-  <feature android:featureId="f271" android:label="@string/dummyLabel" />
-  <feature android:featureId="f272" android:label="@string/dummyLabel" />
-  <feature android:featureId="f273" android:label="@string/dummyLabel" />
-  <feature android:featureId="f274" android:label="@string/dummyLabel" />
-  <feature android:featureId="f275" android:label="@string/dummyLabel" />
-  <feature android:featureId="f276" android:label="@string/dummyLabel" />
-  <feature android:featureId="f277" android:label="@string/dummyLabel" />
-  <feature android:featureId="f278" android:label="@string/dummyLabel" />
-  <feature android:featureId="f279" android:label="@string/dummyLabel" />
-  <feature android:featureId="f280" android:label="@string/dummyLabel" />
-  <feature android:featureId="f281" android:label="@string/dummyLabel" />
-  <feature android:featureId="f282" android:label="@string/dummyLabel" />
-  <feature android:featureId="f283" android:label="@string/dummyLabel" />
-  <feature android:featureId="f284" android:label="@string/dummyLabel" />
-  <feature android:featureId="f285" android:label="@string/dummyLabel" />
-  <feature android:featureId="f286" android:label="@string/dummyLabel" />
-  <feature android:featureId="f287" android:label="@string/dummyLabel" />
-  <feature android:featureId="f288" android:label="@string/dummyLabel" />
-  <feature android:featureId="f289" android:label="@string/dummyLabel" />
-  <feature android:featureId="f290" android:label="@string/dummyLabel" />
-  <feature android:featureId="f291" android:label="@string/dummyLabel" />
-  <feature android:featureId="f292" android:label="@string/dummyLabel" />
-  <feature android:featureId="f293" android:label="@string/dummyLabel" />
-  <feature android:featureId="f294" android:label="@string/dummyLabel" />
-  <feature android:featureId="f295" android:label="@string/dummyLabel" />
-  <feature android:featureId="f296" android:label="@string/dummyLabel" />
-  <feature android:featureId="f297" android:label="@string/dummyLabel" />
-  <feature android:featureId="f298" android:label="@string/dummyLabel" />
-  <feature android:featureId="f299" android:label="@string/dummyLabel" />
-  <feature android:featureId="f300" android:label="@string/dummyLabel" />
-  <feature android:featureId="f301" android:label="@string/dummyLabel" />
-  <feature android:featureId="f302" android:label="@string/dummyLabel" />
-  <feature android:featureId="f303" android:label="@string/dummyLabel" />
-  <feature android:featureId="f304" android:label="@string/dummyLabel" />
-  <feature android:featureId="f305" android:label="@string/dummyLabel" />
-  <feature android:featureId="f306" android:label="@string/dummyLabel" />
-  <feature android:featureId="f307" android:label="@string/dummyLabel" />
-  <feature android:featureId="f308" android:label="@string/dummyLabel" />
-  <feature android:featureId="f309" android:label="@string/dummyLabel" />
-  <feature android:featureId="f310" android:label="@string/dummyLabel" />
-  <feature android:featureId="f311" android:label="@string/dummyLabel" />
-  <feature android:featureId="f312" android:label="@string/dummyLabel" />
-  <feature android:featureId="f313" android:label="@string/dummyLabel" />
-  <feature android:featureId="f314" android:label="@string/dummyLabel" />
-  <feature android:featureId="f315" android:label="@string/dummyLabel" />
-  <feature android:featureId="f316" android:label="@string/dummyLabel" />
-  <feature android:featureId="f317" android:label="@string/dummyLabel" />
-  <feature android:featureId="f318" android:label="@string/dummyLabel" />
-  <feature android:featureId="f319" android:label="@string/dummyLabel" />
-  <feature android:featureId="f320" android:label="@string/dummyLabel" />
-  <feature android:featureId="f321" android:label="@string/dummyLabel" />
-  <feature android:featureId="f322" android:label="@string/dummyLabel" />
-  <feature android:featureId="f323" android:label="@string/dummyLabel" />
-  <feature android:featureId="f324" android:label="@string/dummyLabel" />
-  <feature android:featureId="f325" android:label="@string/dummyLabel" />
-  <feature android:featureId="f326" android:label="@string/dummyLabel" />
-  <feature android:featureId="f327" android:label="@string/dummyLabel" />
-  <feature android:featureId="f328" android:label="@string/dummyLabel" />
-  <feature android:featureId="f329" android:label="@string/dummyLabel" />
-  <feature android:featureId="f330" android:label="@string/dummyLabel" />
-  <feature android:featureId="f331" android:label="@string/dummyLabel" />
-  <feature android:featureId="f332" android:label="@string/dummyLabel" />
-  <feature android:featureId="f333" android:label="@string/dummyLabel" />
-  <feature android:featureId="f334" android:label="@string/dummyLabel" />
-  <feature android:featureId="f335" android:label="@string/dummyLabel" />
-  <feature android:featureId="f336" android:label="@string/dummyLabel" />
-  <feature android:featureId="f337" android:label="@string/dummyLabel" />
-  <feature android:featureId="f338" android:label="@string/dummyLabel" />
-  <feature android:featureId="f339" android:label="@string/dummyLabel" />
-  <feature android:featureId="f340" android:label="@string/dummyLabel" />
-  <feature android:featureId="f341" android:label="@string/dummyLabel" />
-  <feature android:featureId="f342" android:label="@string/dummyLabel" />
-  <feature android:featureId="f343" android:label="@string/dummyLabel" />
-  <feature android:featureId="f344" android:label="@string/dummyLabel" />
-  <feature android:featureId="f345" android:label="@string/dummyLabel" />
-  <feature android:featureId="f346" android:label="@string/dummyLabel" />
-  <feature android:featureId="f347" android:label="@string/dummyLabel" />
-  <feature android:featureId="f348" android:label="@string/dummyLabel" />
-  <feature android:featureId="f349" android:label="@string/dummyLabel" />
-  <feature android:featureId="f350" android:label="@string/dummyLabel" />
-  <feature android:featureId="f351" android:label="@string/dummyLabel" />
-  <feature android:featureId="f352" android:label="@string/dummyLabel" />
-  <feature android:featureId="f353" android:label="@string/dummyLabel" />
-  <feature android:featureId="f354" android:label="@string/dummyLabel" />
-  <feature android:featureId="f355" android:label="@string/dummyLabel" />
-  <feature android:featureId="f356" android:label="@string/dummyLabel" />
-  <feature android:featureId="f357" android:label="@string/dummyLabel" />
-  <feature android:featureId="f358" android:label="@string/dummyLabel" />
-  <feature android:featureId="f359" android:label="@string/dummyLabel" />
-  <feature android:featureId="f360" android:label="@string/dummyLabel" />
-  <feature android:featureId="f361" android:label="@string/dummyLabel" />
-  <feature android:featureId="f362" android:label="@string/dummyLabel" />
-  <feature android:featureId="f363" android:label="@string/dummyLabel" />
-  <feature android:featureId="f364" android:label="@string/dummyLabel" />
-  <feature android:featureId="f365" android:label="@string/dummyLabel" />
-  <feature android:featureId="f366" android:label="@string/dummyLabel" />
-  <feature android:featureId="f367" android:label="@string/dummyLabel" />
-  <feature android:featureId="f368" android:label="@string/dummyLabel" />
-  <feature android:featureId="f369" android:label="@string/dummyLabel" />
-  <feature android:featureId="f370" android:label="@string/dummyLabel" />
-  <feature android:featureId="f371" android:label="@string/dummyLabel" />
-  <feature android:featureId="f372" android:label="@string/dummyLabel" />
-  <feature android:featureId="f373" android:label="@string/dummyLabel" />
-  <feature android:featureId="f374" android:label="@string/dummyLabel" />
-  <feature android:featureId="f375" android:label="@string/dummyLabel" />
-  <feature android:featureId="f376" android:label="@string/dummyLabel" />
-  <feature android:featureId="f377" android:label="@string/dummyLabel" />
-  <feature android:featureId="f378" android:label="@string/dummyLabel" />
-  <feature android:featureId="f379" android:label="@string/dummyLabel" />
-  <feature android:featureId="f380" android:label="@string/dummyLabel" />
-  <feature android:featureId="f381" android:label="@string/dummyLabel" />
-  <feature android:featureId="f382" android:label="@string/dummyLabel" />
-  <feature android:featureId="f383" android:label="@string/dummyLabel" />
-  <feature android:featureId="f384" android:label="@string/dummyLabel" />
-  <feature android:featureId="f385" android:label="@string/dummyLabel" />
-  <feature android:featureId="f386" android:label="@string/dummyLabel" />
-  <feature android:featureId="f387" android:label="@string/dummyLabel" />
-  <feature android:featureId="f388" android:label="@string/dummyLabel" />
-  <feature android:featureId="f389" android:label="@string/dummyLabel" />
-  <feature android:featureId="f390" android:label="@string/dummyLabel" />
-  <feature android:featureId="f391" android:label="@string/dummyLabel" />
-  <feature android:featureId="f392" android:label="@string/dummyLabel" />
-  <feature android:featureId="f393" android:label="@string/dummyLabel" />
-  <feature android:featureId="f394" android:label="@string/dummyLabel" />
-  <feature android:featureId="f395" android:label="@string/dummyLabel" />
-  <feature android:featureId="f396" android:label="@string/dummyLabel" />
-  <feature android:featureId="f397" android:label="@string/dummyLabel" />
-  <feature android:featureId="f398" android:label="@string/dummyLabel" />
-  <feature android:featureId="f399" android:label="@string/dummyLabel" />
-  <feature android:featureId="f400" android:label="@string/dummyLabel" />
-  <feature android:featureId="f401" android:label="@string/dummyLabel" />
-  <feature android:featureId="f402" android:label="@string/dummyLabel" />
-  <feature android:featureId="f403" android:label="@string/dummyLabel" />
-  <feature android:featureId="f404" android:label="@string/dummyLabel" />
-  <feature android:featureId="f405" android:label="@string/dummyLabel" />
-  <feature android:featureId="f406" android:label="@string/dummyLabel" />
-  <feature android:featureId="f407" android:label="@string/dummyLabel" />
-  <feature android:featureId="f408" android:label="@string/dummyLabel" />
-  <feature android:featureId="f409" android:label="@string/dummyLabel" />
-  <feature android:featureId="f410" android:label="@string/dummyLabel" />
-  <feature android:featureId="f411" android:label="@string/dummyLabel" />
-  <feature android:featureId="f412" android:label="@string/dummyLabel" />
-  <feature android:featureId="f413" android:label="@string/dummyLabel" />
-  <feature android:featureId="f414" android:label="@string/dummyLabel" />
-  <feature android:featureId="f415" android:label="@string/dummyLabel" />
-  <feature android:featureId="f416" android:label="@string/dummyLabel" />
-  <feature android:featureId="f417" android:label="@string/dummyLabel" />
-  <feature android:featureId="f418" android:label="@string/dummyLabel" />
-  <feature android:featureId="f419" android:label="@string/dummyLabel" />
-  <feature android:featureId="f420" android:label="@string/dummyLabel" />
-  <feature android:featureId="f421" android:label="@string/dummyLabel" />
-  <feature android:featureId="f422" android:label="@string/dummyLabel" />
-  <feature android:featureId="f423" android:label="@string/dummyLabel" />
-  <feature android:featureId="f424" android:label="@string/dummyLabel" />
-  <feature android:featureId="f425" android:label="@string/dummyLabel" />
-  <feature android:featureId="f426" android:label="@string/dummyLabel" />
-  <feature android:featureId="f427" android:label="@string/dummyLabel" />
-  <feature android:featureId="f428" android:label="@string/dummyLabel" />
-  <feature android:featureId="f429" android:label="@string/dummyLabel" />
-  <feature android:featureId="f430" android:label="@string/dummyLabel" />
-  <feature android:featureId="f431" android:label="@string/dummyLabel" />
-  <feature android:featureId="f432" android:label="@string/dummyLabel" />
-  <feature android:featureId="f433" android:label="@string/dummyLabel" />
-  <feature android:featureId="f434" android:label="@string/dummyLabel" />
-  <feature android:featureId="f435" android:label="@string/dummyLabel" />
-  <feature android:featureId="f436" android:label="@string/dummyLabel" />
-  <feature android:featureId="f437" android:label="@string/dummyLabel" />
-  <feature android:featureId="f438" android:label="@string/dummyLabel" />
-  <feature android:featureId="f439" android:label="@string/dummyLabel" />
-  <feature android:featureId="f440" android:label="@string/dummyLabel" />
-  <feature android:featureId="f441" android:label="@string/dummyLabel" />
-  <feature android:featureId="f442" android:label="@string/dummyLabel" />
-  <feature android:featureId="f443" android:label="@string/dummyLabel" />
-  <feature android:featureId="f444" android:label="@string/dummyLabel" />
-  <feature android:featureId="f445" android:label="@string/dummyLabel" />
-  <feature android:featureId="f446" android:label="@string/dummyLabel" />
-  <feature android:featureId="f447" android:label="@string/dummyLabel" />
-  <feature android:featureId="f448" android:label="@string/dummyLabel" />
-  <feature android:featureId="f449" android:label="@string/dummyLabel" />
-  <feature android:featureId="f450" android:label="@string/dummyLabel" />
-  <feature android:featureId="f451" android:label="@string/dummyLabel" />
-  <feature android:featureId="f452" android:label="@string/dummyLabel" />
-  <feature android:featureId="f453" android:label="@string/dummyLabel" />
-  <feature android:featureId="f454" android:label="@string/dummyLabel" />
-  <feature android:featureId="f455" android:label="@string/dummyLabel" />
-  <feature android:featureId="f456" android:label="@string/dummyLabel" />
-  <feature android:featureId="f457" android:label="@string/dummyLabel" />
-  <feature android:featureId="f458" android:label="@string/dummyLabel" />
-  <feature android:featureId="f459" android:label="@string/dummyLabel" />
-  <feature android:featureId="f460" android:label="@string/dummyLabel" />
-  <feature android:featureId="f461" android:label="@string/dummyLabel" />
-  <feature android:featureId="f462" android:label="@string/dummyLabel" />
-  <feature android:featureId="f463" android:label="@string/dummyLabel" />
-  <feature android:featureId="f464" android:label="@string/dummyLabel" />
-  <feature android:featureId="f465" android:label="@string/dummyLabel" />
-  <feature android:featureId="f466" android:label="@string/dummyLabel" />
-  <feature android:featureId="f467" android:label="@string/dummyLabel" />
-  <feature android:featureId="f468" android:label="@string/dummyLabel" />
-  <feature android:featureId="f469" android:label="@string/dummyLabel" />
-  <feature android:featureId="f470" android:label="@string/dummyLabel" />
-  <feature android:featureId="f471" android:label="@string/dummyLabel" />
-  <feature android:featureId="f472" android:label="@string/dummyLabel" />
-  <feature android:featureId="f473" android:label="@string/dummyLabel" />
-  <feature android:featureId="f474" android:label="@string/dummyLabel" />
-  <feature android:featureId="f475" android:label="@string/dummyLabel" />
-  <feature android:featureId="f476" android:label="@string/dummyLabel" />
-  <feature android:featureId="f477" android:label="@string/dummyLabel" />
-  <feature android:featureId="f478" android:label="@string/dummyLabel" />
-  <feature android:featureId="f479" android:label="@string/dummyLabel" />
-  <feature android:featureId="f480" android:label="@string/dummyLabel" />
-  <feature android:featureId="f481" android:label="@string/dummyLabel" />
-  <feature android:featureId="f482" android:label="@string/dummyLabel" />
-  <feature android:featureId="f483" android:label="@string/dummyLabel" />
-  <feature android:featureId="f484" android:label="@string/dummyLabel" />
-  <feature android:featureId="f485" android:label="@string/dummyLabel" />
-  <feature android:featureId="f486" android:label="@string/dummyLabel" />
-  <feature android:featureId="f487" android:label="@string/dummyLabel" />
-  <feature android:featureId="f488" android:label="@string/dummyLabel" />
-  <feature android:featureId="f489" android:label="@string/dummyLabel" />
-  <feature android:featureId="f490" android:label="@string/dummyLabel" />
-  <feature android:featureId="f491" android:label="@string/dummyLabel" />
-  <feature android:featureId="f492" android:label="@string/dummyLabel" />
-  <feature android:featureId="f493" android:label="@string/dummyLabel" />
-  <feature android:featureId="f494" android:label="@string/dummyLabel" />
-  <feature android:featureId="f495" android:label="@string/dummyLabel" />
-  <feature android:featureId="f496" android:label="@string/dummyLabel" />
-  <feature android:featureId="f497" android:label="@string/dummyLabel" />
-  <feature android:featureId="f498" android:label="@string/dummyLabel" />
-  <feature android:featureId="f499" android:label="@string/dummyLabel" />
-  <feature android:featureId="f500" android:label="@string/dummyLabel" />
-  <feature android:featureId="f501" android:label="@string/dummyLabel" />
-  <feature android:featureId="f502" android:label="@string/dummyLabel" />
-  <feature android:featureId="f503" android:label="@string/dummyLabel" />
-  <feature android:featureId="f504" android:label="@string/dummyLabel" />
-  <feature android:featureId="f505" android:label="@string/dummyLabel" />
-  <feature android:featureId="f506" android:label="@string/dummyLabel" />
-  <feature android:featureId="f507" android:label="@string/dummyLabel" />
-  <feature android:featureId="f508" android:label="@string/dummyLabel" />
-  <feature android:featureId="f509" android:label="@string/dummyLabel" />
-  <feature android:featureId="f510" android:label="@string/dummyLabel" />
-  <feature android:featureId="f511" android:label="@string/dummyLabel" />
-  <feature android:featureId="f512" android:label="@string/dummyLabel" />
-  <feature android:featureId="f513" android:label="@string/dummyLabel" />
-  <feature android:featureId="f514" android:label="@string/dummyLabel" />
-  <feature android:featureId="f515" android:label="@string/dummyLabel" />
-  <feature android:featureId="f516" android:label="@string/dummyLabel" />
-  <feature android:featureId="f517" android:label="@string/dummyLabel" />
-  <feature android:featureId="f518" android:label="@string/dummyLabel" />
-  <feature android:featureId="f519" android:label="@string/dummyLabel" />
-  <feature android:featureId="f520" android:label="@string/dummyLabel" />
-  <feature android:featureId="f521" android:label="@string/dummyLabel" />
-  <feature android:featureId="f522" android:label="@string/dummyLabel" />
-  <feature android:featureId="f523" android:label="@string/dummyLabel" />
-  <feature android:featureId="f524" android:label="@string/dummyLabel" />
-  <feature android:featureId="f525" android:label="@string/dummyLabel" />
-  <feature android:featureId="f526" android:label="@string/dummyLabel" />
-  <feature android:featureId="f527" android:label="@string/dummyLabel" />
-  <feature android:featureId="f528" android:label="@string/dummyLabel" />
-  <feature android:featureId="f529" android:label="@string/dummyLabel" />
-  <feature android:featureId="f530" android:label="@string/dummyLabel" />
-  <feature android:featureId="f531" android:label="@string/dummyLabel" />
-  <feature android:featureId="f532" android:label="@string/dummyLabel" />
-  <feature android:featureId="f533" android:label="@string/dummyLabel" />
-  <feature android:featureId="f534" android:label="@string/dummyLabel" />
-  <feature android:featureId="f535" android:label="@string/dummyLabel" />
-  <feature android:featureId="f536" android:label="@string/dummyLabel" />
-  <feature android:featureId="f537" android:label="@string/dummyLabel" />
-  <feature android:featureId="f538" android:label="@string/dummyLabel" />
-  <feature android:featureId="f539" android:label="@string/dummyLabel" />
-  <feature android:featureId="f540" android:label="@string/dummyLabel" />
-  <feature android:featureId="f541" android:label="@string/dummyLabel" />
-  <feature android:featureId="f542" android:label="@string/dummyLabel" />
-  <feature android:featureId="f543" android:label="@string/dummyLabel" />
-  <feature android:featureId="f544" android:label="@string/dummyLabel" />
-  <feature android:featureId="f545" android:label="@string/dummyLabel" />
-  <feature android:featureId="f546" android:label="@string/dummyLabel" />
-  <feature android:featureId="f547" android:label="@string/dummyLabel" />
-  <feature android:featureId="f548" android:label="@string/dummyLabel" />
-  <feature android:featureId="f549" android:label="@string/dummyLabel" />
-  <feature android:featureId="f550" android:label="@string/dummyLabel" />
-  <feature android:featureId="f551" android:label="@string/dummyLabel" />
-  <feature android:featureId="f552" android:label="@string/dummyLabel" />
-  <feature android:featureId="f553" android:label="@string/dummyLabel" />
-  <feature android:featureId="f554" android:label="@string/dummyLabel" />
-  <feature android:featureId="f555" android:label="@string/dummyLabel" />
-  <feature android:featureId="f556" android:label="@string/dummyLabel" />
-  <feature android:featureId="f557" android:label="@string/dummyLabel" />
-  <feature android:featureId="f558" android:label="@string/dummyLabel" />
-  <feature android:featureId="f559" android:label="@string/dummyLabel" />
-  <feature android:featureId="f560" android:label="@string/dummyLabel" />
-  <feature android:featureId="f561" android:label="@string/dummyLabel" />
-  <feature android:featureId="f562" android:label="@string/dummyLabel" />
-  <feature android:featureId="f563" android:label="@string/dummyLabel" />
-  <feature android:featureId="f564" android:label="@string/dummyLabel" />
-  <feature android:featureId="f565" android:label="@string/dummyLabel" />
-  <feature android:featureId="f566" android:label="@string/dummyLabel" />
-  <feature android:featureId="f567" android:label="@string/dummyLabel" />
-  <feature android:featureId="f568" android:label="@string/dummyLabel" />
-  <feature android:featureId="f569" android:label="@string/dummyLabel" />
-  <feature android:featureId="f570" android:label="@string/dummyLabel" />
-  <feature android:featureId="f571" android:label="@string/dummyLabel" />
-  <feature android:featureId="f572" android:label="@string/dummyLabel" />
-  <feature android:featureId="f573" android:label="@string/dummyLabel" />
-  <feature android:featureId="f574" android:label="@string/dummyLabel" />
-  <feature android:featureId="f575" android:label="@string/dummyLabel" />
-  <feature android:featureId="f576" android:label="@string/dummyLabel" />
-  <feature android:featureId="f577" android:label="@string/dummyLabel" />
-  <feature android:featureId="f578" android:label="@string/dummyLabel" />
-  <feature android:featureId="f579" android:label="@string/dummyLabel" />
-  <feature android:featureId="f580" android:label="@string/dummyLabel" />
-  <feature android:featureId="f581" android:label="@string/dummyLabel" />
-  <feature android:featureId="f582" android:label="@string/dummyLabel" />
-  <feature android:featureId="f583" android:label="@string/dummyLabel" />
-  <feature android:featureId="f584" android:label="@string/dummyLabel" />
-  <feature android:featureId="f585" android:label="@string/dummyLabel" />
-  <feature android:featureId="f586" android:label="@string/dummyLabel" />
-  <feature android:featureId="f587" android:label="@string/dummyLabel" />
-  <feature android:featureId="f588" android:label="@string/dummyLabel" />
-  <feature android:featureId="f589" android:label="@string/dummyLabel" />
-  <feature android:featureId="f590" android:label="@string/dummyLabel" />
-  <feature android:featureId="f591" android:label="@string/dummyLabel" />
-  <feature android:featureId="f592" android:label="@string/dummyLabel" />
-  <feature android:featureId="f593" android:label="@string/dummyLabel" />
-  <feature android:featureId="f594" android:label="@string/dummyLabel" />
-  <feature android:featureId="f595" android:label="@string/dummyLabel" />
-  <feature android:featureId="f596" android:label="@string/dummyLabel" />
-  <feature android:featureId="f597" android:label="@string/dummyLabel" />
-  <feature android:featureId="f598" android:label="@string/dummyLabel" />
-  <feature android:featureId="f599" android:label="@string/dummyLabel" />
-  <feature android:featureId="f600" android:label="@string/dummyLabel" />
-  <feature android:featureId="f601" android:label="@string/dummyLabel" />
-  <feature android:featureId="f602" android:label="@string/dummyLabel" />
-  <feature android:featureId="f603" android:label="@string/dummyLabel" />
-  <feature android:featureId="f604" android:label="@string/dummyLabel" />
-  <feature android:featureId="f605" android:label="@string/dummyLabel" />
-  <feature android:featureId="f606" android:label="@string/dummyLabel" />
-  <feature android:featureId="f607" android:label="@string/dummyLabel" />
-  <feature android:featureId="f608" android:label="@string/dummyLabel" />
-  <feature android:featureId="f609" android:label="@string/dummyLabel" />
-  <feature android:featureId="f610" android:label="@string/dummyLabel" />
-  <feature android:featureId="f611" android:label="@string/dummyLabel" />
-  <feature android:featureId="f612" android:label="@string/dummyLabel" />
-  <feature android:featureId="f613" android:label="@string/dummyLabel" />
-  <feature android:featureId="f614" android:label="@string/dummyLabel" />
-  <feature android:featureId="f615" android:label="@string/dummyLabel" />
-  <feature android:featureId="f616" android:label="@string/dummyLabel" />
-  <feature android:featureId="f617" android:label="@string/dummyLabel" />
-  <feature android:featureId="f618" android:label="@string/dummyLabel" />
-  <feature android:featureId="f619" android:label="@string/dummyLabel" />
-  <feature android:featureId="f620" android:label="@string/dummyLabel" />
-  <feature android:featureId="f621" android:label="@string/dummyLabel" />
-  <feature android:featureId="f622" android:label="@string/dummyLabel" />
-  <feature android:featureId="f623" android:label="@string/dummyLabel" />
-  <feature android:featureId="f624" android:label="@string/dummyLabel" />
-  <feature android:featureId="f625" android:label="@string/dummyLabel" />
-  <feature android:featureId="f626" android:label="@string/dummyLabel" />
-  <feature android:featureId="f627" android:label="@string/dummyLabel" />
-  <feature android:featureId="f628" android:label="@string/dummyLabel" />
-  <feature android:featureId="f629" android:label="@string/dummyLabel" />
-  <feature android:featureId="f630" android:label="@string/dummyLabel" />
-  <feature android:featureId="f631" android:label="@string/dummyLabel" />
-  <feature android:featureId="f632" android:label="@string/dummyLabel" />
-  <feature android:featureId="f633" android:label="@string/dummyLabel" />
-  <feature android:featureId="f634" android:label="@string/dummyLabel" />
-  <feature android:featureId="f635" android:label="@string/dummyLabel" />
-  <feature android:featureId="f636" android:label="@string/dummyLabel" />
-  <feature android:featureId="f637" android:label="@string/dummyLabel" />
-  <feature android:featureId="f638" android:label="@string/dummyLabel" />
-  <feature android:featureId="f639" android:label="@string/dummyLabel" />
-  <feature android:featureId="f640" android:label="@string/dummyLabel" />
-  <feature android:featureId="f641" android:label="@string/dummyLabel" />
-  <feature android:featureId="f642" android:label="@string/dummyLabel" />
-  <feature android:featureId="f643" android:label="@string/dummyLabel" />
-  <feature android:featureId="f644" android:label="@string/dummyLabel" />
-  <feature android:featureId="f645" android:label="@string/dummyLabel" />
-  <feature android:featureId="f646" android:label="@string/dummyLabel" />
-  <feature android:featureId="f647" android:label="@string/dummyLabel" />
-  <feature android:featureId="f648" android:label="@string/dummyLabel" />
-  <feature android:featureId="f649" android:label="@string/dummyLabel" />
-  <feature android:featureId="f650" android:label="@string/dummyLabel" />
-  <feature android:featureId="f651" android:label="@string/dummyLabel" />
-  <feature android:featureId="f652" android:label="@string/dummyLabel" />
-  <feature android:featureId="f653" android:label="@string/dummyLabel" />
-  <feature android:featureId="f654" android:label="@string/dummyLabel" />
-  <feature android:featureId="f655" android:label="@string/dummyLabel" />
-  <feature android:featureId="f656" android:label="@string/dummyLabel" />
-  <feature android:featureId="f657" android:label="@string/dummyLabel" />
-  <feature android:featureId="f658" android:label="@string/dummyLabel" />
-  <feature android:featureId="f659" android:label="@string/dummyLabel" />
-  <feature android:featureId="f660" android:label="@string/dummyLabel" />
-  <feature android:featureId="f661" android:label="@string/dummyLabel" />
-  <feature android:featureId="f662" android:label="@string/dummyLabel" />
-  <feature android:featureId="f663" android:label="@string/dummyLabel" />
-  <feature android:featureId="f664" android:label="@string/dummyLabel" />
-  <feature android:featureId="f665" android:label="@string/dummyLabel" />
-  <feature android:featureId="f666" android:label="@string/dummyLabel" />
-  <feature android:featureId="f667" android:label="@string/dummyLabel" />
-  <feature android:featureId="f668" android:label="@string/dummyLabel" />
-  <feature android:featureId="f669" android:label="@string/dummyLabel" />
-  <feature android:featureId="f670" android:label="@string/dummyLabel" />
-  <feature android:featureId="f671" android:label="@string/dummyLabel" />
-  <feature android:featureId="f672" android:label="@string/dummyLabel" />
-  <feature android:featureId="f673" android:label="@string/dummyLabel" />
-  <feature android:featureId="f674" android:label="@string/dummyLabel" />
-  <feature android:featureId="f675" android:label="@string/dummyLabel" />
-  <feature android:featureId="f676" android:label="@string/dummyLabel" />
-  <feature android:featureId="f677" android:label="@string/dummyLabel" />
-  <feature android:featureId="f678" android:label="@string/dummyLabel" />
-  <feature android:featureId="f679" android:label="@string/dummyLabel" />
-  <feature android:featureId="f680" android:label="@string/dummyLabel" />
-  <feature android:featureId="f681" android:label="@string/dummyLabel" />
-  <feature android:featureId="f682" android:label="@string/dummyLabel" />
-  <feature android:featureId="f683" android:label="@string/dummyLabel" />
-  <feature android:featureId="f684" android:label="@string/dummyLabel" />
-  <feature android:featureId="f685" android:label="@string/dummyLabel" />
-  <feature android:featureId="f686" android:label="@string/dummyLabel" />
-  <feature android:featureId="f687" android:label="@string/dummyLabel" />
-  <feature android:featureId="f688" android:label="@string/dummyLabel" />
-  <feature android:featureId="f689" android:label="@string/dummyLabel" />
-  <feature android:featureId="f690" android:label="@string/dummyLabel" />
-  <feature android:featureId="f691" android:label="@string/dummyLabel" />
-  <feature android:featureId="f692" android:label="@string/dummyLabel" />
-  <feature android:featureId="f693" android:label="@string/dummyLabel" />
-  <feature android:featureId="f694" android:label="@string/dummyLabel" />
-  <feature android:featureId="f695" android:label="@string/dummyLabel" />
-  <feature android:featureId="f696" android:label="@string/dummyLabel" />
-  <feature android:featureId="f697" android:label="@string/dummyLabel" />
-  <feature android:featureId="f698" android:label="@string/dummyLabel" />
-  <feature android:featureId="f699" android:label="@string/dummyLabel" />
-  <feature android:featureId="f700" android:label="@string/dummyLabel" />
-  <feature android:featureId="f701" android:label="@string/dummyLabel" />
-  <feature android:featureId="f702" android:label="@string/dummyLabel" />
-  <feature android:featureId="f703" android:label="@string/dummyLabel" />
-  <feature android:featureId="f704" android:label="@string/dummyLabel" />
-  <feature android:featureId="f705" android:label="@string/dummyLabel" />
-  <feature android:featureId="f706" android:label="@string/dummyLabel" />
-  <feature android:featureId="f707" android:label="@string/dummyLabel" />
-  <feature android:featureId="f708" android:label="@string/dummyLabel" />
-  <feature android:featureId="f709" android:label="@string/dummyLabel" />
-  <feature android:featureId="f710" android:label="@string/dummyLabel" />
-  <feature android:featureId="f711" android:label="@string/dummyLabel" />
-  <feature android:featureId="f712" android:label="@string/dummyLabel" />
-  <feature android:featureId="f713" android:label="@string/dummyLabel" />
-  <feature android:featureId="f714" android:label="@string/dummyLabel" />
-  <feature android:featureId="f715" android:label="@string/dummyLabel" />
-  <feature android:featureId="f716" android:label="@string/dummyLabel" />
-  <feature android:featureId="f717" android:label="@string/dummyLabel" />
-  <feature android:featureId="f718" android:label="@string/dummyLabel" />
-  <feature android:featureId="f719" android:label="@string/dummyLabel" />
-  <feature android:featureId="f720" android:label="@string/dummyLabel" />
-  <feature android:featureId="f721" android:label="@string/dummyLabel" />
-  <feature android:featureId="f722" android:label="@string/dummyLabel" />
-  <feature android:featureId="f723" android:label="@string/dummyLabel" />
-  <feature android:featureId="f724" android:label="@string/dummyLabel" />
-  <feature android:featureId="f725" android:label="@string/dummyLabel" />
-  <feature android:featureId="f726" android:label="@string/dummyLabel" />
-  <feature android:featureId="f727" android:label="@string/dummyLabel" />
-  <feature android:featureId="f728" android:label="@string/dummyLabel" />
-  <feature android:featureId="f729" android:label="@string/dummyLabel" />
-  <feature android:featureId="f730" android:label="@string/dummyLabel" />
-  <feature android:featureId="f731" android:label="@string/dummyLabel" />
-  <feature android:featureId="f732" android:label="@string/dummyLabel" />
-  <feature android:featureId="f733" android:label="@string/dummyLabel" />
-  <feature android:featureId="f734" android:label="@string/dummyLabel" />
-  <feature android:featureId="f735" android:label="@string/dummyLabel" />
-  <feature android:featureId="f736" android:label="@string/dummyLabel" />
-  <feature android:featureId="f737" android:label="@string/dummyLabel" />
-  <feature android:featureId="f738" android:label="@string/dummyLabel" />
-  <feature android:featureId="f739" android:label="@string/dummyLabel" />
-  <feature android:featureId="f740" android:label="@string/dummyLabel" />
-  <feature android:featureId="f741" android:label="@string/dummyLabel" />
-  <feature android:featureId="f742" android:label="@string/dummyLabel" />
-  <feature android:featureId="f743" android:label="@string/dummyLabel" />
-  <feature android:featureId="f744" android:label="@string/dummyLabel" />
-  <feature android:featureId="f745" android:label="@string/dummyLabel" />
-  <feature android:featureId="f746" android:label="@string/dummyLabel" />
-  <feature android:featureId="f747" android:label="@string/dummyLabel" />
-  <feature android:featureId="f748" android:label="@string/dummyLabel" />
-  <feature android:featureId="f749" android:label="@string/dummyLabel" />
-  <feature android:featureId="f750" android:label="@string/dummyLabel" />
-  <feature android:featureId="f751" android:label="@string/dummyLabel" />
-  <feature android:featureId="f752" android:label="@string/dummyLabel" />
-  <feature android:featureId="f753" android:label="@string/dummyLabel" />
-  <feature android:featureId="f754" android:label="@string/dummyLabel" />
-  <feature android:featureId="f755" android:label="@string/dummyLabel" />
-  <feature android:featureId="f756" android:label="@string/dummyLabel" />
-  <feature android:featureId="f757" android:label="@string/dummyLabel" />
-  <feature android:featureId="f758" android:label="@string/dummyLabel" />
-  <feature android:featureId="f759" android:label="@string/dummyLabel" />
-  <feature android:featureId="f760" android:label="@string/dummyLabel" />
-  <feature android:featureId="f761" android:label="@string/dummyLabel" />
-  <feature android:featureId="f762" android:label="@string/dummyLabel" />
-  <feature android:featureId="f763" android:label="@string/dummyLabel" />
-  <feature android:featureId="f764" android:label="@string/dummyLabel" />
-  <feature android:featureId="f765" android:label="@string/dummyLabel" />
-  <feature android:featureId="f766" android:label="@string/dummyLabel" />
-  <feature android:featureId="f767" android:label="@string/dummyLabel" />
-  <feature android:featureId="f768" android:label="@string/dummyLabel" />
-  <feature android:featureId="f769" android:label="@string/dummyLabel" />
-  <feature android:featureId="f770" android:label="@string/dummyLabel" />
-  <feature android:featureId="f771" android:label="@string/dummyLabel" />
-  <feature android:featureId="f772" android:label="@string/dummyLabel" />
-  <feature android:featureId="f773" android:label="@string/dummyLabel" />
-  <feature android:featureId="f774" android:label="@string/dummyLabel" />
-  <feature android:featureId="f775" android:label="@string/dummyLabel" />
-  <feature android:featureId="f776" android:label="@string/dummyLabel" />
-  <feature android:featureId="f777" android:label="@string/dummyLabel" />
-  <feature android:featureId="f778" android:label="@string/dummyLabel" />
-  <feature android:featureId="f779" android:label="@string/dummyLabel" />
-  <feature android:featureId="f780" android:label="@string/dummyLabel" />
-  <feature android:featureId="f781" android:label="@string/dummyLabel" />
-  <feature android:featureId="f782" android:label="@string/dummyLabel" />
-  <feature android:featureId="f783" android:label="@string/dummyLabel" />
-  <feature android:featureId="f784" android:label="@string/dummyLabel" />
-  <feature android:featureId="f785" android:label="@string/dummyLabel" />
-  <feature android:featureId="f786" android:label="@string/dummyLabel" />
-  <feature android:featureId="f787" android:label="@string/dummyLabel" />
-  <feature android:featureId="f788" android:label="@string/dummyLabel" />
-  <feature android:featureId="f789" android:label="@string/dummyLabel" />
-  <feature android:featureId="f790" android:label="@string/dummyLabel" />
-  <feature android:featureId="f791" android:label="@string/dummyLabel" />
-  <feature android:featureId="f792" android:label="@string/dummyLabel" />
-  <feature android:featureId="f793" android:label="@string/dummyLabel" />
-  <feature android:featureId="f794" android:label="@string/dummyLabel" />
-  <feature android:featureId="f795" android:label="@string/dummyLabel" />
-  <feature android:featureId="f796" android:label="@string/dummyLabel" />
-  <feature android:featureId="f797" android:label="@string/dummyLabel" />
-  <feature android:featureId="f798" android:label="@string/dummyLabel" />
-  <feature android:featureId="f799" android:label="@string/dummyLabel" />
-  <feature android:featureId="f800" android:label="@string/dummyLabel" />
-  <feature android:featureId="f801" android:label="@string/dummyLabel" />
-  <feature android:featureId="f802" android:label="@string/dummyLabel" />
-  <feature android:featureId="f803" android:label="@string/dummyLabel" />
-  <feature android:featureId="f804" android:label="@string/dummyLabel" />
-  <feature android:featureId="f805" android:label="@string/dummyLabel" />
-  <feature android:featureId="f806" android:label="@string/dummyLabel" />
-  <feature android:featureId="f807" android:label="@string/dummyLabel" />
-  <feature android:featureId="f808" android:label="@string/dummyLabel" />
-  <feature android:featureId="f809" android:label="@string/dummyLabel" />
-  <feature android:featureId="f810" android:label="@string/dummyLabel" />
-  <feature android:featureId="f811" android:label="@string/dummyLabel" />
-  <feature android:featureId="f812" android:label="@string/dummyLabel" />
-  <feature android:featureId="f813" android:label="@string/dummyLabel" />
-  <feature android:featureId="f814" android:label="@string/dummyLabel" />
-  <feature android:featureId="f815" android:label="@string/dummyLabel" />
-  <feature android:featureId="f816" android:label="@string/dummyLabel" />
-  <feature android:featureId="f817" android:label="@string/dummyLabel" />
-  <feature android:featureId="f818" android:label="@string/dummyLabel" />
-  <feature android:featureId="f819" android:label="@string/dummyLabel" />
-  <feature android:featureId="f820" android:label="@string/dummyLabel" />
-  <feature android:featureId="f821" android:label="@string/dummyLabel" />
-  <feature android:featureId="f822" android:label="@string/dummyLabel" />
-  <feature android:featureId="f823" android:label="@string/dummyLabel" />
-  <feature android:featureId="f824" android:label="@string/dummyLabel" />
-  <feature android:featureId="f825" android:label="@string/dummyLabel" />
-  <feature android:featureId="f826" android:label="@string/dummyLabel" />
-  <feature android:featureId="f827" android:label="@string/dummyLabel" />
-  <feature android:featureId="f828" android:label="@string/dummyLabel" />
-  <feature android:featureId="f829" android:label="@string/dummyLabel" />
-  <feature android:featureId="f830" android:label="@string/dummyLabel" />
-  <feature android:featureId="f831" android:label="@string/dummyLabel" />
-  <feature android:featureId="f832" android:label="@string/dummyLabel" />
-  <feature android:featureId="f833" android:label="@string/dummyLabel" />
-  <feature android:featureId="f834" android:label="@string/dummyLabel" />
-  <feature android:featureId="f835" android:label="@string/dummyLabel" />
-  <feature android:featureId="f836" android:label="@string/dummyLabel" />
-  <feature android:featureId="f837" android:label="@string/dummyLabel" />
-  <feature android:featureId="f838" android:label="@string/dummyLabel" />
-  <feature android:featureId="f839" android:label="@string/dummyLabel" />
-  <feature android:featureId="f840" android:label="@string/dummyLabel" />
-  <feature android:featureId="f841" android:label="@string/dummyLabel" />
-  <feature android:featureId="f842" android:label="@string/dummyLabel" />
-  <feature android:featureId="f843" android:label="@string/dummyLabel" />
-  <feature android:featureId="f844" android:label="@string/dummyLabel" />
-  <feature android:featureId="f845" android:label="@string/dummyLabel" />
-  <feature android:featureId="f846" android:label="@string/dummyLabel" />
-  <feature android:featureId="f847" android:label="@string/dummyLabel" />
-  <feature android:featureId="f848" android:label="@string/dummyLabel" />
-  <feature android:featureId="f849" android:label="@string/dummyLabel" />
-  <feature android:featureId="f850" android:label="@string/dummyLabel" />
-  <feature android:featureId="f851" android:label="@string/dummyLabel" />
-  <feature android:featureId="f852" android:label="@string/dummyLabel" />
-  <feature android:featureId="f853" android:label="@string/dummyLabel" />
-  <feature android:featureId="f854" android:label="@string/dummyLabel" />
-  <feature android:featureId="f855" android:label="@string/dummyLabel" />
-  <feature android:featureId="f856" android:label="@string/dummyLabel" />
-  <feature android:featureId="f857" android:label="@string/dummyLabel" />
-  <feature android:featureId="f858" android:label="@string/dummyLabel" />
-  <feature android:featureId="f859" android:label="@string/dummyLabel" />
-  <feature android:featureId="f860" android:label="@string/dummyLabel" />
-  <feature android:featureId="f861" android:label="@string/dummyLabel" />
-  <feature android:featureId="f862" android:label="@string/dummyLabel" />
-  <feature android:featureId="f863" android:label="@string/dummyLabel" />
-  <feature android:featureId="f864" android:label="@string/dummyLabel" />
-  <feature android:featureId="f865" android:label="@string/dummyLabel" />
-  <feature android:featureId="f866" android:label="@string/dummyLabel" />
-  <feature android:featureId="f867" android:label="@string/dummyLabel" />
-  <feature android:featureId="f868" android:label="@string/dummyLabel" />
-  <feature android:featureId="f869" android:label="@string/dummyLabel" />
-  <feature android:featureId="f870" android:label="@string/dummyLabel" />
-  <feature android:featureId="f871" android:label="@string/dummyLabel" />
-  <feature android:featureId="f872" android:label="@string/dummyLabel" />
-  <feature android:featureId="f873" android:label="@string/dummyLabel" />
-  <feature android:featureId="f874" android:label="@string/dummyLabel" />
-  <feature android:featureId="f875" android:label="@string/dummyLabel" />
-  <feature android:featureId="f876" android:label="@string/dummyLabel" />
-  <feature android:featureId="f877" android:label="@string/dummyLabel" />
-  <feature android:featureId="f878" android:label="@string/dummyLabel" />
-  <feature android:featureId="f879" android:label="@string/dummyLabel" />
-  <feature android:featureId="f880" android:label="@string/dummyLabel" />
-  <feature android:featureId="f881" android:label="@string/dummyLabel" />
-  <feature android:featureId="f882" android:label="@string/dummyLabel" />
-  <feature android:featureId="f883" android:label="@string/dummyLabel" />
-  <feature android:featureId="f884" android:label="@string/dummyLabel" />
-  <feature android:featureId="f885" android:label="@string/dummyLabel" />
-  <feature android:featureId="f886" android:label="@string/dummyLabel" />
-  <feature android:featureId="f887" android:label="@string/dummyLabel" />
-  <feature android:featureId="f888" android:label="@string/dummyLabel" />
-  <feature android:featureId="f889" android:label="@string/dummyLabel" />
-  <feature android:featureId="f890" android:label="@string/dummyLabel" />
-  <feature android:featureId="f891" android:label="@string/dummyLabel" />
-  <feature android:featureId="f892" android:label="@string/dummyLabel" />
-  <feature android:featureId="f893" android:label="@string/dummyLabel" />
-  <feature android:featureId="f894" android:label="@string/dummyLabel" />
-  <feature android:featureId="f895" android:label="@string/dummyLabel" />
-  <feature android:featureId="f896" android:label="@string/dummyLabel" />
-  <feature android:featureId="f897" android:label="@string/dummyLabel" />
-  <feature android:featureId="f898" android:label="@string/dummyLabel" />
-  <feature android:featureId="f899" android:label="@string/dummyLabel" />
-  <feature android:featureId="f900" android:label="@string/dummyLabel" />
-  <feature android:featureId="f901" android:label="@string/dummyLabel" />
-  <feature android:featureId="f902" android:label="@string/dummyLabel" />
-  <feature android:featureId="f903" android:label="@string/dummyLabel" />
-  <feature android:featureId="f904" android:label="@string/dummyLabel" />
-  <feature android:featureId="f905" android:label="@string/dummyLabel" />
-  <feature android:featureId="f906" android:label="@string/dummyLabel" />
-  <feature android:featureId="f907" android:label="@string/dummyLabel" />
-  <feature android:featureId="f908" android:label="@string/dummyLabel" />
-  <feature android:featureId="f909" android:label="@string/dummyLabel" />
-  <feature android:featureId="f910" android:label="@string/dummyLabel" />
-  <feature android:featureId="f911" android:label="@string/dummyLabel" />
-  <feature android:featureId="f912" android:label="@string/dummyLabel" />
-  <feature android:featureId="f913" android:label="@string/dummyLabel" />
-  <feature android:featureId="f914" android:label="@string/dummyLabel" />
-  <feature android:featureId="f915" android:label="@string/dummyLabel" />
-  <feature android:featureId="f916" android:label="@string/dummyLabel" />
-  <feature android:featureId="f917" android:label="@string/dummyLabel" />
-  <feature android:featureId="f918" android:label="@string/dummyLabel" />
-  <feature android:featureId="f919" android:label="@string/dummyLabel" />
-  <feature android:featureId="f920" android:label="@string/dummyLabel" />
-  <feature android:featureId="f921" android:label="@string/dummyLabel" />
-  <feature android:featureId="f922" android:label="@string/dummyLabel" />
-  <feature android:featureId="f923" android:label="@string/dummyLabel" />
-  <feature android:featureId="f924" android:label="@string/dummyLabel" />
-  <feature android:featureId="f925" android:label="@string/dummyLabel" />
-  <feature android:featureId="f926" android:label="@string/dummyLabel" />
-  <feature android:featureId="f927" android:label="@string/dummyLabel" />
-  <feature android:featureId="f928" android:label="@string/dummyLabel" />
-  <feature android:featureId="f929" android:label="@string/dummyLabel" />
-  <feature android:featureId="f930" android:label="@string/dummyLabel" />
-  <feature android:featureId="f931" android:label="@string/dummyLabel" />
-  <feature android:featureId="f932" android:label="@string/dummyLabel" />
-  <feature android:featureId="f933" android:label="@string/dummyLabel" />
-  <feature android:featureId="f934" android:label="@string/dummyLabel" />
-  <feature android:featureId="f935" android:label="@string/dummyLabel" />
-  <feature android:featureId="f936" android:label="@string/dummyLabel" />
-  <feature android:featureId="f937" android:label="@string/dummyLabel" />
-  <feature android:featureId="f938" android:label="@string/dummyLabel" />
-  <feature android:featureId="f939" android:label="@string/dummyLabel" />
-  <feature android:featureId="f940" android:label="@string/dummyLabel" />
-  <feature android:featureId="f941" android:label="@string/dummyLabel" />
-  <feature android:featureId="f942" android:label="@string/dummyLabel" />
-  <feature android:featureId="f943" android:label="@string/dummyLabel" />
-  <feature android:featureId="f944" android:label="@string/dummyLabel" />
-  <feature android:featureId="f945" android:label="@string/dummyLabel" />
-  <feature android:featureId="f946" android:label="@string/dummyLabel" />
-  <feature android:featureId="f947" android:label="@string/dummyLabel" />
-  <feature android:featureId="f948" android:label="@string/dummyLabel" />
-  <feature android:featureId="f949" android:label="@string/dummyLabel" />
-  <feature android:featureId="f950" android:label="@string/dummyLabel" />
-  <feature android:featureId="f951" android:label="@string/dummyLabel" />
-  <feature android:featureId="f952" android:label="@string/dummyLabel" />
-  <feature android:featureId="f953" android:label="@string/dummyLabel" />
-  <feature android:featureId="f954" android:label="@string/dummyLabel" />
-  <feature android:featureId="f955" android:label="@string/dummyLabel" />
-  <feature android:featureId="f956" android:label="@string/dummyLabel" />
-  <feature android:featureId="f957" android:label="@string/dummyLabel" />
-  <feature android:featureId="f958" android:label="@string/dummyLabel" />
-  <feature android:featureId="f959" android:label="@string/dummyLabel" />
-  <feature android:featureId="f960" android:label="@string/dummyLabel" />
-  <feature android:featureId="f961" android:label="@string/dummyLabel" />
-  <feature android:featureId="f962" android:label="@string/dummyLabel" />
-  <feature android:featureId="f963" android:label="@string/dummyLabel" />
-  <feature android:featureId="f964" android:label="@string/dummyLabel" />
-  <feature android:featureId="f965" android:label="@string/dummyLabel" />
-  <feature android:featureId="f966" android:label="@string/dummyLabel" />
-  <feature android:featureId="f967" android:label="@string/dummyLabel" />
-  <feature android:featureId="f968" android:label="@string/dummyLabel" />
-  <feature android:featureId="f969" android:label="@string/dummyLabel" />
-  <feature android:featureId="f970" android:label="@string/dummyLabel" />
-  <feature android:featureId="f971" android:label="@string/dummyLabel" />
-  <feature android:featureId="f972" android:label="@string/dummyLabel" />
-  <feature android:featureId="f973" android:label="@string/dummyLabel" />
-  <feature android:featureId="f974" android:label="@string/dummyLabel" />
-  <feature android:featureId="f975" android:label="@string/dummyLabel" />
-  <feature android:featureId="f976" android:label="@string/dummyLabel" />
-  <feature android:featureId="f977" android:label="@string/dummyLabel" />
-  <feature android:featureId="f978" android:label="@string/dummyLabel" />
-  <feature android:featureId="f979" android:label="@string/dummyLabel" />
-  <feature android:featureId="f980" android:label="@string/dummyLabel" />
-  <feature android:featureId="f981" android:label="@string/dummyLabel" />
-  <feature android:featureId="f982" android:label="@string/dummyLabel" />
-  <feature android:featureId="f983" android:label="@string/dummyLabel" />
-  <feature android:featureId="f984" android:label="@string/dummyLabel" />
-  <feature android:featureId="f985" android:label="@string/dummyLabel" />
-  <feature android:featureId="f986" android:label="@string/dummyLabel" />
-  <feature android:featureId="f987" android:label="@string/dummyLabel" />
-  <feature android:featureId="f988" android:label="@string/dummyLabel" />
-  <feature android:featureId="f989" android:label="@string/dummyLabel" />
-  <feature android:featureId="f990" android:label="@string/dummyLabel" />
-  <feature android:featureId="f991" android:label="@string/dummyLabel" />
-  <feature android:featureId="f992" android:label="@string/dummyLabel" />
-  <feature android:featureId="f993" android:label="@string/dummyLabel" />
-  <feature android:featureId="f994" android:label="@string/dummyLabel" />
-  <feature android:featureId="f995" android:label="@string/dummyLabel" />
-  <feature android:featureId="f996" android:label="@string/dummyLabel" />
-  <feature android:featureId="f997" android:label="@string/dummyLabel" />
-  <feature android:featureId="f998" android:label="@string/dummyLabel" />
-  <feature android:featureId="f999" android:label="@string/dummyLabel" />
-
-  <feature android:featureId="toomany" android:label="@string/dummyLabel" />
-
-  <application />
-
-</manifest>
diff --git a/tests/tests/appop/aidl/AppOpsUserService/src/android/app/appops/cts/IAppOpsUserClient.aidl b/tests/tests/appop/aidl/AppOpsUserService/src/android/app/appops/cts/IAppOpsUserClient.aidl
index f3af855..e4125f7 100644
--- a/tests/tests/appop/aidl/AppOpsUserService/src/android/app/appops/cts/IAppOpsUserClient.aidl
+++ b/tests/tests/appop/aidl/AppOpsUserService/src/android/app/appops/cts/IAppOpsUserClient.aidl
@@ -18,7 +18,7 @@
 
 interface IAppOpsUserClient {
     void noteSyncOp();
-    void noteSyncOpWithFeature(String featureId);
+    void noteSyncOpWithAttribution(String attributionTag);
     void callBackIntoService();
     void noteNonPermissionSyncOp();
     void noteSyncOpTwice();
@@ -30,7 +30,7 @@
     void noteSyncOpOtherUid();
     void noteSyncOpOtherUidNative();
     void noteAsyncOp();
-    void noteAsyncOpWithFeature(String featureId);
+    void noteAsyncOpWithAttribution(String attributionTag);
     void noteAsyncOpWithCustomMessage();
     void noteAsyncOpNative();
     void noteAsyncOpNativeWithCustomMessage();
diff --git a/tests/tests/appop/aidl/AppOpsUserService/src/android/app/appops/cts/IAppOpsUserService.aidl b/tests/tests/appop/aidl/AppOpsUserService/src/android/app/appops/cts/IAppOpsUserService.aidl
index a19705f..0b073fb 100644
--- a/tests/tests/appop/aidl/AppOpsUserService/src/android/app/appops/cts/IAppOpsUserService.aidl
+++ b/tests/tests/appop/aidl/AppOpsUserService/src/android/app/appops/cts/IAppOpsUserService.aidl
@@ -23,7 +23,7 @@
     void disableCollectorAndCallASyncOpsWhichWillBeCollected(in IAppOpsUserClient client);
     void callApiThatNotesSyncOpAndCheckLog(in IAppOpsUserClient client);
     void callApiThatNotesSyncOpAndClearLog(in IAppOpsUserClient client);
-    void callApiThatNotesSyncOpWithFeatureAndCheckLog(in IAppOpsUserClient client);
+    void callApiThatNotesSyncOpWithAttributionAndCheckLog(in IAppOpsUserClient client);
     void callApiThatCallsBackIntoServiceAndCheckLog(in IAppOpsUserClient client);
     void callApiThatNotesSyncOpFromNativeCodeAndCheckLog(in IAppOpsUserClient client);
     void callApiThatNotesSyncOpFromNativeCodeAndCheckMessage(in IAppOpsUserClient client);
@@ -38,7 +38,7 @@
     void callApiThatNotesSyncOpOtherUidAndCheckLog(in IAppOpsUserClient client);
     void callApiThatNotesSyncOpOtherUidNativelyAndCheckLog(in IAppOpsUserClient client);
     void callApiThatNotesAsyncOpAndCheckLog(in IAppOpsUserClient client);
-    void callApiThatNotesAsyncOpWithFeatureAndCheckLog(in IAppOpsUserClient client);
+    void callApiThatNotesAsyncOpWithAttributionAndCheckLog(in IAppOpsUserClient client);
     void callApiThatNotesAsyncOpAndCheckDefaultMessage(in IAppOpsUserClient client);
     void callApiThatNotesAsyncOpAndCheckCustomMessage(in IAppOpsUserClient client);
     void callApiThatNotesAsyncOpNativelyAndCheckCustomMessage(in IAppOpsUserClient client);
diff --git a/tests/tests/appop/appopsTestUtilLib/src/android/app/appops/cts/AppOpsUtils.kt b/tests/tests/appop/appopsTestUtilLib/src/android/app/appops/cts/AppOpsUtils.kt
index da8f8d2..b1588d5 100644
--- a/tests/tests/appop/appopsTestUtilLib/src/android/app/appops/cts/AppOpsUtils.kt
+++ b/tests/tests/appop/appopsTestUtilLib/src/android/app/appops/cts/AppOpsUtils.kt
@@ -29,7 +29,7 @@
 private const val LOG_TAG = "AppOpsUtils"
 private const val TIMEOUT_MILLIS = 10000L
 
-const val TEST_FEATURE_ID = "testFeature"
+const val TEST_ATTRIBUTION_TAG = "testAttribution"
 
 /**
  * Resets a package's app ops configuration to the device default. See AppOpsManager for the
diff --git a/tests/tests/appop/jni/android/app/appops/cts/AppOpsLoggingTest.cpp b/tests/tests/appop/jni/android/app/appops/cts/AppOpsLoggingTest.cpp
index 0b47701..a403163 100644
--- a/tests/tests/appop/jni/android/app/appops/cts/AppOpsLoggingTest.cpp
+++ b/tests/tests/appop/jni/android/app/appops/cts/AppOpsLoggingTest.cpp
@@ -29,17 +29,17 @@
 // Note op from native code
 extern "C" JNIEXPORT void JNICALL
 Java_android_app_appops_cts_AppOpsLoggingTestKt_nativeNoteOp(JNIEnv* env, jobject obj,
-        jint op, jint uid, jstring jCallingPackageName, jstring jFeatureId, jstring jMessage) {
+        jint op, jint uid, jstring jCallingPackageName, jstring jAttributionTag, jstring jMessage) {
     AppOpsManager appOpsManager;
 
     const char *nativeCallingPackageName = env->GetStringUTFChars(jCallingPackageName, 0);
     String16 callingPackageName(nativeCallingPackageName);
 
-    const char *nativeFeatureId;
-    std::unique_ptr<String16> featureId;
-    if (jFeatureId != nullptr) {
-        nativeFeatureId = env->GetStringUTFChars(jFeatureId, 0);
-        featureId = std::unique_ptr<String16>(new String16(nativeFeatureId));
+    const char *nativeAttributionTag;
+    std::unique_ptr<String16> attributionTag;
+    if (jAttributionTag != nullptr) {
+        nativeAttributionTag = env->GetStringUTFChars(jAttributionTag, 0);
+        attributionTag = std::unique_ptr<String16>(new String16(nativeAttributionTag));
     }
 
     const char *nativeMessage;
@@ -51,12 +51,12 @@
         message = new String16();
     }
 
-    appOpsManager.noteOp(op, uid, callingPackageName, featureId, *message);
+    appOpsManager.noteOp(op, uid, callingPackageName, attributionTag, *message);
 
     env->ReleaseStringUTFChars(jCallingPackageName, nativeCallingPackageName);
 
-    if (jFeatureId != nullptr) {
-        env->ReleaseStringUTFChars(jFeatureId, nativeFeatureId);
+    if (jAttributionTag != nullptr) {
+        env->ReleaseStringUTFChars(jAttributionTag, nativeAttributionTag);
     }
 
     if (jMessage != nullptr) {
diff --git a/tests/tests/appop/src/android/app/appops/cts/AppOpEventCollectionTest.kt b/tests/tests/appop/src/android/app/appops/cts/AppOpEventCollectionTest.kt
index 51bad70..103a4b2 100644
--- a/tests/tests/appop/src/android/app/appops/cts/AppOpEventCollectionTest.kt
+++ b/tests/tests/appop/src/android/app/appops/cts/AppOpEventCollectionTest.kt
@@ -96,36 +96,36 @@
     }
 
     @Test
-    fun noteWithFeatureAndCheckOpEntries() {
+    fun noteWithAttributionAndCheckOpEntries() {
         val before = System.currentTimeMillis()
-        appOpsManager.noteOp(OPSTR_WIFI_SCAN, myUid, myPackage, TEST_FEATURE_ID, null)
+        appOpsManager.noteOp(OPSTR_WIFI_SCAN, myUid, myPackage, TEST_ATTRIBUTION_TAG, null)
         val after = System.currentTimeMillis()
 
         val opEntry = getOpEntry(myUid, myPackage, OPSTR_WIFI_SCAN)!!
-        val featureOpEntry = opEntry.features[TEST_FEATURE_ID]!!
+        val attributionOpEntry = opEntry.attributedOpEntries[TEST_ATTRIBUTION_TAG]!!
 
-        assertThat(featureOpEntry.getLastAccessForegroundTime(OP_FLAG_SELF)).isIn(before..after)
+        assertThat(attributionOpEntry.getLastAccessForegroundTime(OP_FLAG_SELF)).isIn(before..after)
 
         // Access should should also show up in the combined state for all op-flags
-        assertThat(featureOpEntry.getLastAccessForegroundTime(OP_FLAGS_ALL)).isIn(before..after)
+        assertThat(attributionOpEntry.getLastAccessForegroundTime(OP_FLAGS_ALL)).isIn(before..after)
         assertThat(opEntry.getLastAccessTime(OP_FLAGS_ALL)).isIn(before..after)
 
         // Foreground access should should also show up in the combined state for fg and bg
-        assertThat(featureOpEntry.getLastAccessTime(OP_FLAG_SELF)).isIn(before..after)
+        assertThat(attributionOpEntry.getLastAccessTime(OP_FLAG_SELF)).isIn(before..after)
         assertThat(opEntry.getLastAccessTime(OP_FLAG_SELF)).isIn(before..after)
 
         // The access was in foreground, hence there is no background access
-        assertThat(featureOpEntry.getLastBackgroundDuration(OP_FLAG_SELF)).isLessThan(before)
+        assertThat(attributionOpEntry.getLastBackgroundDuration(OP_FLAG_SELF)).isLessThan(before)
         assertThat(opEntry.getLastBackgroundDuration(OP_FLAG_SELF)).isLessThan(before)
 
-        // The access was for a feature, hence there is no access for the default feature
-        if (null in opEntry.features) {
-            assertThat(opEntry.features[null]!!.getLastAccessForegroundTime(OP_FLAG_SELF))
-                    .isLessThan(before)
+        // The access was for a attribution, hence there is no access for the default attribution
+        if (null in opEntry.attributedOpEntries) {
+            assertThat(opEntry.attributedOpEntries[null]!!
+                    .getLastAccessForegroundTime(OP_FLAG_SELF)).isLessThan(before)
         }
 
         // The access does not show up for other op-flags
-        assertThat(featureOpEntry.getLastAccessForegroundTime(
+        assertThat(attributionOpEntry.getLastAccessForegroundTime(
                 OP_FLAGS_ALL and OP_FLAG_SELF.inv())).isLessThan(before)
         assertThat(opEntry.getLastAccessForegroundTime(
                 OP_FLAGS_ALL and OP_FLAG_SELF.inv())).isLessThan(before)
@@ -149,40 +149,40 @@
         val after = System.currentTimeMillis()
 
         val opEntry = getOpEntry(myUid, myPackage, OPSTR_WIFI_SCAN)!!
-        val featureOpEntry = opEntry.features[null]!!
+        val attributionOpEntry = opEntry.attributedOpEntries[null]!!
 
-        assertThat(featureOpEntry.getLastAccessTime(OP_FLAG_TRUSTED_PROXY))
+        assertThat(attributionOpEntry.getLastAccessTime(OP_FLAG_TRUSTED_PROXY))
                 .isIn(before..afterTrusted)
-        assertThat(featureOpEntry.getLastAccessTime(OP_FLAG_SELF)).isIn(afterTrusted..after)
+        assertThat(attributionOpEntry.getLastAccessTime(OP_FLAG_SELF)).isIn(afterTrusted..after)
         assertThat(opEntry.getLastAccessTime(OP_FLAG_TRUSTED_PROXY)).isIn(before..afterTrusted)
         assertThat(opEntry.getLastAccessTime(OP_FLAG_SELF)).isIn(afterTrusted..after)
 
         // When asked for any flags, the second access overrides the first
-        assertThat(featureOpEntry.getLastAccessTime(OP_FLAGS_ALL)).isIn(afterTrusted..after)
+        assertThat(attributionOpEntry.getLastAccessTime(OP_FLAGS_ALL)).isIn(afterTrusted..after)
         assertThat(opEntry.getLastAccessTime(OP_FLAGS_ALL)).isIn(afterTrusted..after)
     }
 
     @Test
-    fun noteForTwoFeaturesCheckOpEntries() {
+    fun noteForTwoAttributionsCheckOpEntries() {
         val before = System.currentTimeMillis()
-        appOpsManager.noteOp(OPSTR_WIFI_SCAN, myUid, myPackage, "firstFeature", null)
+        appOpsManager.noteOp(OPSTR_WIFI_SCAN, myUid, myPackage, "firstAttribution", null)
         val afterFirst = System.currentTimeMillis()
 
         // Make sure timestamps are distinct
         sleep(1)
 
         // self note
-        appOpsManager.noteOp(OPSTR_WIFI_SCAN, myUid, myPackage, "secondFeature", null)
+        appOpsManager.noteOp(OPSTR_WIFI_SCAN, myUid, myPackage, "secondAttribution", null)
         val after = System.currentTimeMillis()
 
         val opEntry = getOpEntry(myUid, myPackage, OPSTR_WIFI_SCAN)!!
-        val firstFeatureOpEntry = opEntry.features["firstFeature"]!!
-        val secondFeatureOpEntry = opEntry.features["secondFeature"]!!
+        val firstAttributionOpEntry = opEntry.attributedOpEntries["firstAttribution"]!!
+        val secondAttributionOpEntry = opEntry.attributedOpEntries["secondAttribution"]!!
 
-        assertThat(firstFeatureOpEntry.getLastAccessTime(OP_FLAG_SELF)).isIn(before..afterFirst)
-        assertThat(secondFeatureOpEntry.getLastAccessTime(OP_FLAG_SELF)).isIn(afterFirst..after)
+        assertThat(firstAttributionOpEntry.getLastAccessTime(OP_FLAG_SELF)).isIn(before..afterFirst)
+        assertThat(secondAttributionOpEntry.getLastAccessTime(OP_FLAG_SELF)).isIn(afterFirst..after)
 
-        // When asked for any feature, the second access overrides the first
+        // When asked for any attribution, the second access overrides the first
         assertThat(opEntry.getLastAccessTime(OP_FLAG_SELF)).isIn(afterFirst..after)
     }
 
@@ -198,7 +198,7 @@
 
         // Using the shell identity causes a trusted proxy note
         runWithShellPermissionIdentity {
-            context.createFeatureContext("firstProxyFeature")
+            context.createAttributionContext("firstProxyAttribution")
                     .getSystemService(AppOpsManager::class.java)
                     .noteProxyOp(OPSTR_WIFI_SCAN, otherPkg, otherUid, null, null)
         }
@@ -207,35 +207,37 @@
         sleep(1)
 
         // untrusted proxy note
-        context.createFeatureContext("secondProxyFeature")
+        context.createAttributionContext("secondProxyAttribution")
                 .getSystemService(AppOpsManager::class.java)
                 .noteProxyOp(OPSTR_WIFI_SCAN, otherPkg, otherUid, null, null)
 
         val opEntry = getOpEntry(otherUid, otherPkg, OPSTR_WIFI_SCAN)!!
-        val featureOpEntry = opEntry.features[null]!!
+        val attributionOpEntry = opEntry.attributedOpEntries[null]!!
 
-        assertThat(featureOpEntry.getLastProxyInfo(OP_FLAG_TRUSTED_PROXIED)?.packageName)
+        assertThat(attributionOpEntry.getLastProxyInfo(OP_FLAG_TRUSTED_PROXIED)?.packageName)
                 .isEqualTo(myPackage)
         assertThat(opEntry.getLastProxyInfo(OP_FLAG_TRUSTED_PROXIED)?.packageName)
                 .isEqualTo(myPackage)
-        assertThat(featureOpEntry.getLastProxyInfo(OP_FLAG_TRUSTED_PROXIED)?.uid).isEqualTo(myUid)
+        assertThat(attributionOpEntry.getLastProxyInfo(OP_FLAG_TRUSTED_PROXIED)?.uid)
+                .isEqualTo(myUid)
         assertThat(opEntry.getLastProxyInfo(OP_FLAG_TRUSTED_PROXIED)?.uid).isEqualTo(myUid)
 
-        assertThat(featureOpEntry.getLastProxyInfo(OP_FLAG_UNTRUSTED_PROXIED)?.packageName)
+        assertThat(attributionOpEntry.getLastProxyInfo(OP_FLAG_UNTRUSTED_PROXIED)?.packageName)
                 .isEqualTo(myPackage)
         assertThat(opEntry.getLastProxyInfo(OP_FLAG_UNTRUSTED_PROXIED)?.packageName)
                 .isEqualTo(myPackage)
-        assertThat(featureOpEntry.getLastProxyInfo(OP_FLAG_UNTRUSTED_PROXIED)?.uid).isEqualTo(myUid)
+        assertThat(attributionOpEntry.getLastProxyInfo(OP_FLAG_UNTRUSTED_PROXIED)?.uid)
+                .isEqualTo(myUid)
         assertThat(opEntry.getLastProxyInfo(OP_FLAG_UNTRUSTED_PROXIED)?.uid).isEqualTo(myUid)
 
-        assertThat(featureOpEntry.getLastProxyInfo(OP_FLAG_TRUSTED_PROXIED)?.featureId)
-                .isEqualTo("firstProxyFeature")
-        assertThat(featureOpEntry.getLastProxyInfo(OP_FLAG_UNTRUSTED_PROXIED)?.featureId)
-                .isEqualTo("secondProxyFeature")
+        assertThat(attributionOpEntry.getLastProxyInfo(OP_FLAG_TRUSTED_PROXIED)?.attributionTag)
+                .isEqualTo("firstProxyAttribution")
+        assertThat(attributionOpEntry.getLastProxyInfo(OP_FLAG_UNTRUSTED_PROXIED)?.attributionTag)
+                .isEqualTo("secondProxyAttribution")
 
-        // If asked for all op-flags the second feature overrides the first
-        assertThat(featureOpEntry.getLastProxyInfo(OP_FLAGS_ALL)?.featureId)
-                .isEqualTo("secondProxyFeature")
+        // If asked for all op-flags the second attribution overrides the first
+        assertThat(attributionOpEntry.getLastProxyInfo(OP_FLAGS_ALL)?.attributionTag)
+                .isEqualTo("secondProxyAttribution")
     }
 
     @Test
@@ -243,140 +245,141 @@
         appOpsManager.startOp(OPSTR_WIFI_SCAN, myUid, myPackage, null, null)
 
         with(getOpEntry(myUid, myPackage, OPSTR_WIFI_SCAN)!!) {
-            assertThat(features[null]!!.isRunning).isTrue()
-            features[TEST_FEATURE_ID]?.let { assertThat(it.isRunning).isFalse() }
+            assertThat(attributedOpEntries[null]!!.isRunning).isTrue()
+            attributedOpEntries[TEST_ATTRIBUTION_TAG]?.let { assertThat(it.isRunning).isFalse() }
             assertThat(isRunning).isTrue()
         }
 
-        appOpsManager.startOp(OPSTR_WIFI_SCAN, myUid, myPackage, TEST_FEATURE_ID, null)
+        appOpsManager.startOp(OPSTR_WIFI_SCAN, myUid, myPackage, TEST_ATTRIBUTION_TAG, null)
 
         with(getOpEntry(myUid, myPackage, OPSTR_WIFI_SCAN)!!) {
-            assertThat(features[null]!!.isRunning).isTrue()
-            assertThat(features[TEST_FEATURE_ID]!!.isRunning).isTrue()
+            assertThat(attributedOpEntries[null]!!.isRunning).isTrue()
+            assertThat(attributedOpEntries[TEST_ATTRIBUTION_TAG]!!.isRunning).isTrue()
             assertThat(isRunning).isTrue()
         }
 
-        appOpsManager.startOp(OPSTR_WIFI_SCAN, myUid, myPackage, TEST_FEATURE_ID, null)
+        appOpsManager.startOp(OPSTR_WIFI_SCAN, myUid, myPackage, TEST_ATTRIBUTION_TAG, null)
 
         with(getOpEntry(myUid, myPackage, OPSTR_WIFI_SCAN)!!) {
-            assertThat(features[null]!!.isRunning).isTrue()
-            assertThat(features[TEST_FEATURE_ID]!!.isRunning).isTrue()
+            assertThat(attributedOpEntries[null]!!.isRunning).isTrue()
+            assertThat(attributedOpEntries[TEST_ATTRIBUTION_TAG]!!.isRunning).isTrue()
             assertThat(isRunning).isTrue()
         }
 
-        appOpsManager.finishOp(OPSTR_WIFI_SCAN, myUid, myPackage, TEST_FEATURE_ID)
+        appOpsManager.finishOp(OPSTR_WIFI_SCAN, myUid, myPackage, TEST_ATTRIBUTION_TAG)
 
         with(getOpEntry(myUid, myPackage, OPSTR_WIFI_SCAN)!!) {
-            assertThat(features[null]!!.isRunning).isTrue()
-            assertThat(features[TEST_FEATURE_ID]!!.isRunning).isTrue()
+            assertThat(attributedOpEntries[null]!!.isRunning).isTrue()
+            assertThat(attributedOpEntries[TEST_ATTRIBUTION_TAG]!!.isRunning).isTrue()
             assertThat(isRunning).isTrue()
         }
 
-        appOpsManager.finishOp(OPSTR_WIFI_SCAN, myUid, myPackage, TEST_FEATURE_ID)
+        appOpsManager.finishOp(OPSTR_WIFI_SCAN, myUid, myPackage, TEST_ATTRIBUTION_TAG)
 
         with(getOpEntry(myUid, myPackage, OPSTR_WIFI_SCAN)!!) {
-            assertThat(features[null]!!.isRunning).isTrue()
-            assertThat(features[TEST_FEATURE_ID]!!.isRunning).isFalse()
+            assertThat(attributedOpEntries[null]!!.isRunning).isTrue()
+            assertThat(attributedOpEntries[TEST_ATTRIBUTION_TAG]!!.isRunning).isFalse()
             assertThat(isRunning).isTrue()
         }
 
         appOpsManager.finishOp(OPSTR_WIFI_SCAN, myUid, myPackage, null)
 
         with(getOpEntry(myUid, myPackage, OPSTR_WIFI_SCAN)!!) {
-            assertThat(features[null]!!.isRunning).isFalse()
-            assertThat(features[TEST_FEATURE_ID]!!.isRunning).isFalse()
+            assertThat(attributedOpEntries[null]!!.isRunning).isFalse()
+            assertThat(attributedOpEntries[TEST_ATTRIBUTION_TAG]!!.isRunning).isFalse()
             assertThat(isRunning).isFalse()
         }
     }
 
     @Test
     fun startStopMultipleOpsAndVerifyLastAccess() {
-        val beforeNullFeatureStart = System.currentTimeMillis()
+        val beforeNullAttributionStart = System.currentTimeMillis()
         appOpsManager.startOp(OPSTR_WIFI_SCAN, myUid, myPackage, null, null)
-        val afterNullFeatureStart = System.currentTimeMillis()
+        val afterNullAttributionStart = System.currentTimeMillis()
 
         with(getOpEntry(myUid, myPackage, OPSTR_WIFI_SCAN)!!) {
-            assertThat(features[null]!!.getLastAccessTime(OP_FLAGS_ALL))
-                    .isIn(beforeNullFeatureStart..afterNullFeatureStart)
-            features[TEST_FEATURE_ID]?.let {
-                assertThat(it.getLastAccessTime(OP_FLAGS_ALL)).isAtMost(beforeNullFeatureStart)
+            assertThat(attributedOpEntries[null]!!.getLastAccessTime(OP_FLAGS_ALL))
+                    .isIn(beforeNullAttributionStart..afterNullAttributionStart)
+            attributedOpEntries[TEST_ATTRIBUTION_TAG]?.let {
+                assertThat(it.getLastAccessTime(OP_FLAGS_ALL)).isAtMost(beforeNullAttributionStart)
             }
             assertThat(getLastAccessTime(OP_FLAGS_ALL))
-                    .isIn(beforeNullFeatureStart..afterNullFeatureStart)
+                    .isIn(beforeNullAttributionStart..afterNullAttributionStart)
         }
 
-        val beforeFirstFeatureStart = System.currentTimeMillis()
-        appOpsManager.startOp(OPSTR_WIFI_SCAN, myUid, myPackage, TEST_FEATURE_ID, null)
-        val afterFirstFeatureStart = System.currentTimeMillis()
+        val beforeFirstAttributionStart = System.currentTimeMillis()
+        appOpsManager.startOp(OPSTR_WIFI_SCAN, myUid, myPackage, TEST_ATTRIBUTION_TAG, null)
+        val afterFirstAttributionStart = System.currentTimeMillis()
 
         with(getOpEntry(myUid, myPackage, OPSTR_WIFI_SCAN)!!) {
-            assertThat(features[null]!!.getLastAccessTime(OP_FLAGS_ALL))
-                    .isIn(beforeNullFeatureStart..afterNullFeatureStart)
-            assertThat(features[TEST_FEATURE_ID]!!.getLastAccessTime(OP_FLAGS_ALL))
-                    .isIn(beforeFirstFeatureStart..afterFirstFeatureStart)
+            assertThat(attributedOpEntries[null]!!.getLastAccessTime(OP_FLAGS_ALL))
+                    .isIn(beforeNullAttributionStart..afterNullAttributionStart)
+            assertThat(attributedOpEntries[TEST_ATTRIBUTION_TAG]!!.getLastAccessTime(OP_FLAGS_ALL))
+                    .isIn(beforeFirstAttributionStart..afterFirstAttributionStart)
             assertThat(getLastAccessTime(OP_FLAGS_ALL))
-                    .isIn(beforeFirstFeatureStart..afterFirstFeatureStart)
+                    .isIn(beforeFirstAttributionStart..afterFirstAttributionStart)
         }
 
-        appOpsManager.startOp(OPSTR_WIFI_SCAN, myUid, myPackage, TEST_FEATURE_ID, null)
+        appOpsManager.startOp(OPSTR_WIFI_SCAN, myUid, myPackage, TEST_ATTRIBUTION_TAG, null)
 
         // Nested startOps do _not_ count as another access
         with(getOpEntry(myUid, myPackage, OPSTR_WIFI_SCAN)!!) {
-            assertThat(features[null]!!.getLastAccessTime(OP_FLAGS_ALL))
-                    .isIn(beforeNullFeatureStart..afterNullFeatureStart)
-            assertThat(features[TEST_FEATURE_ID]!!.getLastAccessTime(OP_FLAGS_ALL))
-                    .isIn(beforeFirstFeatureStart..afterFirstFeatureStart)
+            assertThat(attributedOpEntries[null]!!.getLastAccessTime(OP_FLAGS_ALL))
+                    .isIn(beforeNullAttributionStart..afterNullAttributionStart)
+            assertThat(attributedOpEntries[TEST_ATTRIBUTION_TAG]!!.getLastAccessTime(OP_FLAGS_ALL))
+                    .isIn(beforeFirstAttributionStart..afterFirstAttributionStart)
             assertThat(getLastAccessTime(OP_FLAGS_ALL))
-                    .isIn(beforeFirstFeatureStart..afterFirstFeatureStart)
+                    .isIn(beforeFirstAttributionStart..afterFirstAttributionStart)
         }
 
-        appOpsManager.finishOp(OPSTR_WIFI_SCAN, myUid, myPackage, TEST_FEATURE_ID)
-        appOpsManager.finishOp(OPSTR_WIFI_SCAN, myUid, myPackage, TEST_FEATURE_ID)
+        appOpsManager.finishOp(OPSTR_WIFI_SCAN, myUid, myPackage, TEST_ATTRIBUTION_TAG)
+        appOpsManager.finishOp(OPSTR_WIFI_SCAN, myUid, myPackage, TEST_ATTRIBUTION_TAG)
         appOpsManager.finishOp(OPSTR_WIFI_SCAN, myUid, myPackage, null)
     }
 
     @Test
     fun startStopMultipleOpsAndVerifyDuration() {
-        val beforeNullFeatureStart = SystemClock.elapsedRealtime()
+        val beforeNullAttributionStart = SystemClock.elapsedRealtime()
         appOpsManager.startOp(OPSTR_WIFI_SCAN, myUid, myPackage, null, null)
-        val afterNullFeatureStart = SystemClock.elapsedRealtime()
+        val afterNullAttributionStart = SystemClock.elapsedRealtime()
 
         run {
             val beforeGetOp = SystemClock.elapsedRealtime()
             with(getOpEntry(myUid, myPackage, OPSTR_WIFI_SCAN)!!) {
                 val afterGetOp = SystemClock.elapsedRealtime()
 
-                assertThat(features[null]!!.getLastDuration(OP_FLAGS_ALL))
-                        .isIn(beforeGetOp - afterNullFeatureStart
-                                ..afterGetOp - beforeNullFeatureStart)
+                assertThat(attributedOpEntries[null]!!.getLastDuration(OP_FLAGS_ALL))
+                        .isIn(beforeGetOp - afterNullAttributionStart
+                                ..afterGetOp - beforeNullAttributionStart)
                 assertThat(getLastDuration(OP_FLAGS_ALL))
-                        .isIn(beforeGetOp - afterNullFeatureStart
-                                ..afterGetOp - beforeNullFeatureStart)
+                        .isIn(beforeGetOp - afterNullAttributionStart
+                                ..afterGetOp - beforeNullAttributionStart)
             }
         }
 
-        val beforeFeatureStart = SystemClock.elapsedRealtime()
-        appOpsManager.startOp(OPSTR_WIFI_SCAN, myUid, myPackage, TEST_FEATURE_ID, null)
-        val afterFeatureStart = SystemClock.elapsedRealtime()
+        val beforeAttributionStart = SystemClock.elapsedRealtime()
+        appOpsManager.startOp(OPSTR_WIFI_SCAN, myUid, myPackage, TEST_ATTRIBUTION_TAG, null)
+        val afterAttributionStart = SystemClock.elapsedRealtime()
 
         run {
             val beforeGetOp = SystemClock.elapsedRealtime()
             with(getOpEntry(myUid, myPackage, OPSTR_WIFI_SCAN)!!) {
                 val afterGetOp = SystemClock.elapsedRealtime()
 
-                assertThat(features[null]!!.getLastDuration(OP_FLAGS_ALL))
-                        .isIn(beforeGetOp - afterNullFeatureStart
-                                ..afterGetOp - beforeNullFeatureStart)
-                assertThat(features[TEST_FEATURE_ID]!!.getLastDuration(OP_FLAGS_ALL))
-                        .isIn(beforeGetOp - afterFeatureStart..afterGetOp - beforeFeatureStart)
+                assertThat(attributedOpEntries[null]!!.getLastDuration(OP_FLAGS_ALL))
+                        .isIn(beforeGetOp - afterNullAttributionStart
+                                ..afterGetOp - beforeNullAttributionStart)
+                assertThat(attributedOpEntries[TEST_ATTRIBUTION_TAG]!!
+                        .getLastDuration(OP_FLAGS_ALL)).isIn(beforeGetOp -
+                                afterAttributionStart..afterGetOp - beforeAttributionStart)
 
-                // The last duration is the duration of the last started feature
-                assertThat(getLastDuration(OP_FLAGS_ALL))
-                        .isIn(beforeGetOp - afterFeatureStart..afterGetOp - beforeFeatureStart)
+                // The last duration is the duration of the last started attribution
+                assertThat(getLastDuration(OP_FLAGS_ALL)).isIn(beforeGetOp -
+                        afterAttributionStart..afterGetOp - beforeAttributionStart)
             }
         }
 
-        appOpsManager.startOp(OPSTR_WIFI_SCAN, myUid, myPackage, TEST_FEATURE_ID, null)
+        appOpsManager.startOp(OPSTR_WIFI_SCAN, myUid, myPackage, TEST_ATTRIBUTION_TAG, null)
 
         // Nested startOps do _not_ start another duration counting, hence the nested
         // startOp and finishOp calls have no affect
@@ -385,68 +388,72 @@
             with(getOpEntry(myUid, myPackage, OPSTR_WIFI_SCAN)!!) {
                 val afterGetOp = SystemClock.elapsedRealtime()
 
-                assertThat(features[null]!!.getLastDuration(OP_FLAGS_ALL))
-                        .isIn(beforeGetOp - afterNullFeatureStart
-                                ..afterGetOp - beforeNullFeatureStart)
-                assertThat(features[TEST_FEATURE_ID]!!.getLastDuration(OP_FLAGS_ALL))
-                        .isIn(beforeGetOp - afterFeatureStart..afterGetOp - beforeFeatureStart)
+                assertThat(attributedOpEntries[null]!!.getLastDuration(OP_FLAGS_ALL))
+                        .isIn(beforeGetOp - afterNullAttributionStart
+                                ..afterGetOp - beforeNullAttributionStart)
+                assertThat(attributedOpEntries[TEST_ATTRIBUTION_TAG]!!
+                        .getLastDuration(OP_FLAGS_ALL)).isIn(beforeGetOp -
+                        afterAttributionStart..afterGetOp - beforeAttributionStart)
                 assertThat(getLastDuration(OP_FLAGS_ALL))
-                        .isIn(beforeGetOp - afterFeatureStart..afterGetOp - beforeFeatureStart)
+                        .isIn(beforeGetOp -
+                                afterAttributionStart..afterGetOp - beforeAttributionStart)
             }
         }
 
-        appOpsManager.finishOp(OPSTR_WIFI_SCAN, myUid, myPackage, TEST_FEATURE_ID)
+        appOpsManager.finishOp(OPSTR_WIFI_SCAN, myUid, myPackage, TEST_ATTRIBUTION_TAG)
 
         run {
             val beforeGetOp = SystemClock.elapsedRealtime()
             with(getOpEntry(myUid, myPackage, OPSTR_WIFI_SCAN)!!) {
                 val afterGetOp = SystemClock.elapsedRealtime()
 
-                assertThat(features[null]!!.getLastDuration(OP_FLAGS_ALL))
-                        .isIn(beforeGetOp - afterNullFeatureStart
-                                ..afterGetOp - beforeNullFeatureStart)
-                assertThat(features[TEST_FEATURE_ID]!!.getLastDuration(OP_FLAGS_ALL))
-                        .isIn(beforeGetOp - afterFeatureStart..afterGetOp - beforeFeatureStart)
-                assertThat(getLastDuration(OP_FLAGS_ALL))
-                        .isIn(beforeGetOp - afterFeatureStart..afterGetOp - beforeFeatureStart)
+                assertThat(attributedOpEntries[null]!!.getLastDuration(OP_FLAGS_ALL))
+                        .isIn(beforeGetOp - afterNullAttributionStart
+                                ..afterGetOp - beforeNullAttributionStart)
+                assertThat(attributedOpEntries[TEST_ATTRIBUTION_TAG]!!
+                        .getLastDuration(OP_FLAGS_ALL)).isIn(beforeGetOp -
+                                afterAttributionStart..afterGetOp - beforeAttributionStart)
+                assertThat(getLastDuration(OP_FLAGS_ALL)).isIn(beforeGetOp -
+                                afterAttributionStart..afterGetOp - beforeAttributionStart)
             }
         }
 
-        val beforeFeatureStop = SystemClock.elapsedRealtime()
-        appOpsManager.finishOp(OPSTR_WIFI_SCAN, myUid, myPackage, TEST_FEATURE_ID)
-        val afterFeatureStop = SystemClock.elapsedRealtime()
+        val beforeAttributionStop = SystemClock.elapsedRealtime()
+        appOpsManager.finishOp(OPSTR_WIFI_SCAN, myUid, myPackage, TEST_ATTRIBUTION_TAG)
+        val afterAttributionStop = SystemClock.elapsedRealtime()
 
         run {
             val beforeGetOp = SystemClock.elapsedRealtime()
             with(getOpEntry(myUid, myPackage, OPSTR_WIFI_SCAN)!!) {
                 val afterGetOp = SystemClock.elapsedRealtime()
 
-                assertThat(features[null]!!.getLastDuration(OP_FLAGS_ALL))
-                        .isIn(beforeGetOp - afterNullFeatureStart
-                                ..afterGetOp - beforeNullFeatureStart)
-                assertThat(features[TEST_FEATURE_ID]!!.getLastDuration(OP_FLAGS_ALL))
-                        .isIn(beforeFeatureStop - afterFeatureStart
-                                ..afterFeatureStop - beforeFeatureStart)
+                assertThat(attributedOpEntries[null]!!.getLastDuration(OP_FLAGS_ALL))
+                        .isIn(beforeGetOp - afterNullAttributionStart
+                                ..afterGetOp - beforeNullAttributionStart)
+                assertThat(attributedOpEntries[TEST_ATTRIBUTION_TAG]!!
+                        .getLastDuration(OP_FLAGS_ALL)).isIn(
+                        beforeAttributionStop - afterAttributionStart
+                                ..afterAttributionStop - beforeAttributionStart)
                 assertThat(getLastDuration(OP_FLAGS_ALL))
-                        .isIn(beforeFeatureStop - afterFeatureStart
-                                ..afterFeatureStop - beforeFeatureStart)
+                        .isIn(beforeAttributionStop - afterAttributionStart
+                                ..afterAttributionStop - beforeAttributionStart)
             }
         }
 
-        val beforeNullFeatureStop = SystemClock.elapsedRealtime()
+        val beforeNullAttributionStop = SystemClock.elapsedRealtime()
         appOpsManager.finishOp(OPSTR_WIFI_SCAN, myUid, myPackage, null)
-        val afterNullFeatureStop = SystemClock.elapsedRealtime()
+        val afterNullAttributionStop = SystemClock.elapsedRealtime()
 
         with(getOpEntry(myUid, myPackage, OPSTR_WIFI_SCAN)!!) {
-            assertThat(features[null]!!.getLastDuration(OP_FLAGS_ALL))
-                    .isIn(beforeNullFeatureStop - afterNullFeatureStart
-                            ..afterNullFeatureStop - beforeNullFeatureStart)
-            assertThat(features[TEST_FEATURE_ID]!!.getLastDuration(OP_FLAGS_ALL))
-                    .isIn(beforeFeatureStop - afterFeatureStart
-                            ..afterFeatureStop - beforeFeatureStart)
+            assertThat(attributedOpEntries[null]!!.getLastDuration(OP_FLAGS_ALL))
+                    .isIn(beforeNullAttributionStop - afterNullAttributionStart
+                            ..afterNullAttributionStop - beforeNullAttributionStart)
+            assertThat(attributedOpEntries[TEST_ATTRIBUTION_TAG]!!.getLastDuration(OP_FLAGS_ALL))
+                    .isIn(beforeAttributionStop - afterAttributionStart
+                            ..afterAttributionStop - beforeAttributionStart)
             assertThat(getLastDuration(OP_FLAGS_ALL))
-                    .isIn(beforeFeatureStop - afterFeatureStart
-                            ..afterFeatureStop - beforeFeatureStart)
+                    .isIn(beforeAttributionStop - afterAttributionStart
+                            ..afterAttributionStop - beforeAttributionStart)
         }
     }
 }
diff --git a/tests/tests/appop/src/android/app/appops/cts/AppOpsLoggingTest.kt b/tests/tests/appop/src/android/app/appops/cts/AppOpsLoggingTest.kt
index 7b94625..e8db5e2 100644
--- a/tests/tests/appop/src/android/app/appops/cts/AppOpsLoggingTest.kt
+++ b/tests/tests/appop/src/android/app/appops/cts/AppOpsLoggingTest.kt
@@ -17,7 +17,7 @@
 package android.app.appops.cts
 
 import android.app.AppOpsManager
-import android.app.AppOpsManager.AppOpsCollector
+import android.app.AppOpsManager.OnOpNotedCallback
 import android.app.AppOpsManager.OPSTR_ACCESS_ACCESSIBILITY
 import android.app.AppOpsManager.OPSTR_CAMERA
 import android.app.AppOpsManager.OPSTR_COARSE_LOCATION
@@ -78,7 +78,7 @@
     op: Int,
     uid: Int,
     packageName: String,
-    featureId: String? = null,
+    attributionTag: String? = null,
     message: String? = null
 )
 
@@ -137,8 +137,8 @@
     }
 
     private fun setNotedAppOpsCollector() {
-        appOpsManager.setNotedAppOpsCollector(
-                object : AppOpsCollector() {
+        appOpsManager.setOnOpNotedCallback(Executor { it.run() },
+                object : OnOpNotedCallback() {
                     override fun onNoted(op: SyncNotedAppOp) {
                         noted.add(op to Throwable().stackTrace)
                     }
@@ -150,11 +150,6 @@
                     override fun onAsyncNoted(asyncOp: AsyncNotedAppOp) {
                         asyncNoted.add(asyncOp)
                     }
-
-                    override fun getAsyncNotedExecutor(): Executor {
-                        // Execute callbacks immediately
-                        return Executor { it.run() }
-                    }
                 })
     }
 
@@ -173,15 +168,16 @@
         assertThat(noted).isEmpty()
         assertThat(asyncNoted).isEmpty()
 
-        assertThat(selfNoted.map { it.first.featureId to it.first.op })
+        assertThat(selfNoted.map { it.first.attributionTag to it.first.op })
             .containsExactly(null to OPSTR_COARSE_LOCATION)
     }
 
     @Test
-    fun selfNoteAndCheckFeature() {
-        appOpsManager.noteOpNoThrow(OPSTR_COARSE_LOCATION, myUid, myPackage, TEST_FEATURE_ID, null)
+    fun selfNoteAndCheckAttribution() {
+        appOpsManager.noteOpNoThrow(OPSTR_COARSE_LOCATION, myUid, myPackage, TEST_ATTRIBUTION_TAG,
+                null)
 
-        assertThat(selfNoted.map { it.first.featureId }).containsExactly(TEST_FEATURE_ID)
+        assertThat(selfNoted.map { it.first.attributionTag }).containsExactly(TEST_ATTRIBUTION_TAG)
     }
 
     @Test
@@ -193,7 +189,7 @@
 
         // All native notes will be reported as async notes
         eventually {
-            assertThat(asyncNoted[0].featureId).isEqualTo(null)
+            assertThat(asyncNoted[0].attributionTag).isEqualTo(null)
             // There is always a message.
             assertThat(asyncNoted[0].message).isNotEqualTo(null)
             assertThat(asyncNoted[0].op).isEqualTo(OPSTR_COARSE_LOCATION)
@@ -202,13 +198,13 @@
     }
 
     @Test
-    fun nativeSelfNoteWithFeatureAndMsgAndCheckLog() {
+    fun nativeSelfNoteWithAttributionAndMsgAndCheckLog() {
         nativeNoteOp(strOpToOp(OPSTR_COARSE_LOCATION), myUid, myPackage,
-            featureId = TEST_FEATURE_ID, message = "testMsg")
+            attributionTag = TEST_ATTRIBUTION_TAG, message = "testMsg")
 
         // All native notes will be reported as async notes
         eventually {
-            assertThat(asyncNoted[0].featureId).isEqualTo(TEST_FEATURE_ID)
+            assertThat(asyncNoted[0].attributionTag).isEqualTo(TEST_ATTRIBUTION_TAG)
             assertThat(asyncNoted[0].message).isEqualTo("testMsg")
         }
     }
@@ -237,9 +233,9 @@
     }
 
     @Test
-    fun noteSyncWithFeatureOpAndCheckLog() {
+    fun noteSyncWithAttributionOpAndCheckLog() {
         rethrowThrowableFrom {
-            testService.callApiThatNotesSyncOpWithFeatureAndCheckLog(AppOpsUserClient(context))
+            testService.callApiThatNotesSyncOpWithAttributionAndCheckLog(AppOpsUserClient(context))
         }
     }
 
@@ -346,9 +342,9 @@
     }
 
     @Test
-    fun noteAsyncOpWithFeatureAndCheckLog() {
+    fun noteAsyncOpWithAttributionAndCheckLog() {
         rethrowThrowableFrom {
-            testService.callApiThatNotesAsyncOpWithFeatureAndCheckLog(AppOpsUserClient(context))
+            testService.callApiThatNotesAsyncOpWithAttributionAndCheckLog(AppOpsUserClient(context))
         }
     }
 
@@ -386,13 +382,13 @@
      */
     @Test
     fun getWifiScanResults() {
-        val wifiManager = context.createFeatureContext(TEST_FEATURE_ID)
+        val wifiManager = context.createAttributionContext(TEST_ATTRIBUTION_TAG)
             .getSystemService(WifiManager::class.java)
 
         val results = wifiManager.scanResults
 
         assertThat(noted[0].first.op).isEqualTo(OPSTR_FINE_LOCATION)
-        assertThat(noted[0].first.featureId).isEqualTo(TEST_FEATURE_ID)
+        assertThat(noted[0].first.attributionTag).isEqualTo(TEST_ATTRIBUTION_TAG)
         assertThat(noted[0].second.map { it.methodName }).contains("getWifiScanResults")
     }
 
@@ -404,13 +400,13 @@
         assumeTrue("Device does not support bluetooth",
                 context.packageManager.hasSystemFeature(FEATURE_BLUETOOTH))
 
-        val btManager = context.createFeatureContext(TEST_FEATURE_ID)
+        val btManager = context.createAttributionContext(TEST_ATTRIBUTION_TAG)
                 .getSystemService(BluetoothManager::class.java)
 
         btManager.adapter.startDiscovery()
         try {
             assertThat(noted[0].first.op).isEqualTo(OPSTR_FINE_LOCATION)
-            assertThat(noted[0].first.featureId).isEqualTo(TEST_FEATURE_ID)
+            assertThat(noted[0].first.attributionTag).isEqualTo(TEST_ATTRIBUTION_TAG)
             assertThat(noted[0].second.map { it.methodName }).contains("getBTScanResults")
         } finally {
             btManager.adapter.cancelDiscovery()
@@ -422,7 +418,7 @@
      */
     @Test
     fun getLastKnownLocation() {
-        val locationManager = context.createFeatureContext(TEST_FEATURE_ID)
+        val locationManager = context.createAttributionContext(TEST_ATTRIBUTION_TAG)
             .getSystemService(LocationManager::class.java)
 
         assumeTrue("Device does not have a network provider",
@@ -433,7 +429,7 @@
 
         assertThat(noted.map { it.first.op }).containsAnyOf(OPSTR_COARSE_LOCATION,
             OPSTR_FINE_LOCATION)
-        assertThat(noted[0].first.featureId).isEqualTo(TEST_FEATURE_ID)
+        assertThat(noted[0].first.attributionTag).isEqualTo(TEST_ATTRIBUTION_TAG)
         assertThat(noted[0].second.map { it.methodName }).contains("getLastKnownLocation")
     }
 
@@ -442,7 +438,7 @@
      */
     @Test
     fun getAsyncLocation() {
-        val locationManager = context.createFeatureContext(TEST_FEATURE_ID)
+        val locationManager = context.createAttributionContext(TEST_ATTRIBUTION_TAG)
             .getSystemService(LocationManager::class.java)
 
         assumeTrue("Device does not have a network provider",
@@ -472,7 +468,7 @@
         eventually {
             assertThat(asyncNoted.map { it.op }).containsAnyOf(OPSTR_COARSE_LOCATION,
                 OPSTR_FINE_LOCATION)
-            assertThat(asyncNoted[0].featureId).isEqualTo(TEST_FEATURE_ID)
+            assertThat(asyncNoted[0].attributionTag).isEqualTo(TEST_ATTRIBUTION_TAG)
 
             assertThat(asyncNoted[0].message).contains(locationListener::class.java.name)
             assertThat(asyncNoted[0].message).contains(
@@ -489,7 +485,7 @@
 
         val gotProximityAlert = CompletableFuture<Unit>()
 
-        val locationManager = context.createFeatureContext(TEST_FEATURE_ID)
+        val locationManager = context.createAttributionContext(TEST_ATTRIBUTION_TAG)
             .getSystemService(LocationManager::class.java)!!
 
         val proximityAlertReceiver = object : BroadcastReceiver() {
@@ -516,7 +512,7 @@
 
                 eventually {
                     assertThat(asyncNoted.map { it.op }).contains(OPSTR_FINE_LOCATION)
-                    assertThat(asyncNoted[0].featureId).isEqualTo(TEST_FEATURE_ID)
+                    assertThat(asyncNoted[0].attributionTag).isEqualTo(TEST_ATTRIBUTION_TAG)
 
                     assertThat(asyncNoted[0].message).contains(
                         proximityAlertReceiverPendingIntent::class.java.name)
@@ -537,11 +533,11 @@
      */
     @Test
     fun readFromContactsProvider() {
-        context.createFeatureContext(TEST_FEATURE_ID).contentResolver
+        context.createAttributionContext(TEST_ATTRIBUTION_TAG).contentResolver
             .query(ContactsContract.Contacts.CONTENT_URI, null, null, null, null)
 
         assertThat(noted.map { it.first.op }).containsExactly(OPSTR_READ_CONTACTS)
-        assertThat(noted[0].first.featureId).isEqualTo(TEST_FEATURE_ID)
+        assertThat(noted[0].first.attributionTag).isEqualTo(TEST_ATTRIBUTION_TAG)
         assertThat(noted[0].second.map { it.methodName }).contains("readFromContactsProvider")
     }
 
@@ -550,11 +546,11 @@
      */
     @Test
     fun writeToContactsProvider() {
-        context.createFeatureContext(TEST_FEATURE_ID).contentResolver
+        context.createAttributionContext(TEST_ATTRIBUTION_TAG).contentResolver
             .insert(ContactsContract.RawContacts.CONTENT_URI, ContentValues())
 
         assertThat(noted.map { it.first.op }).containsExactly(OPSTR_WRITE_CONTACTS)
-        assertThat(noted[0].first.featureId).isEqualTo(TEST_FEATURE_ID)
+        assertThat(noted[0].first.attributionTag).isEqualTo(TEST_ATTRIBUTION_TAG)
         assertThat(noted[0].second.map { it.methodName }).contains("writeToContactsProvider")
     }
 
@@ -565,13 +561,13 @@
     fun getCellInfo() {
         assumeTrue(context.packageManager.hasSystemFeature(FEATURE_TELEPHONY))
 
-        val telephonyManager = context.createFeatureContext(TEST_FEATURE_ID)
+        val telephonyManager = context.createAttributionContext(TEST_ATTRIBUTION_TAG)
             .getSystemService(TelephonyManager::class.java)
 
         telephonyManager.allCellInfo
 
         assertThat(noted[0].first.op).isEqualTo(OPSTR_FINE_LOCATION)
-        assertThat(noted[0].first.featureId).isEqualTo(TEST_FEATURE_ID)
+        assertThat(noted[0].first.attributionTag).isEqualTo(TEST_ATTRIBUTION_TAG)
         assertThat(noted[0].second.map { it.methodName }).contains("getCellInfo")
     }
 
@@ -596,7 +592,7 @@
 
         eventually {
             assertThat(asyncNoted[0].op).isEqualTo(OPSTR_CAMERA)
-            assertThat(asyncNoted[0].featureId).isEqualTo(context.featureId)
+            assertThat(asyncNoted[0].attributionTag).isEqualTo(context.attributionTag)
             assertThat(asyncNoted[0].message).contains(cameraManager.cameraIdList[0])
         }
     }
@@ -605,17 +601,17 @@
      * Realistic end-to-end test for opening camera
      */
     @Test
-    fun openCameraWithFeature() {
-        openCamera(context.createFeatureContext(TEST_FEATURE_ID))
+    fun openCameraWithAttribution() {
+        openCamera(context.createAttributionContext(TEST_ATTRIBUTION_TAG))
     }
 
     /**
-     * Realistic end-to-end test for opening camera. This uses the default (==null) feature. This
-     * is interesting as null feature handling is more complex in native code.
+     * Realistic end-to-end test for opening camera. This uses the default (==null) attribution.
+     * This is interesting as null attribution handling is more complex in native code.
      */
     @Test
-    fun openCameraWithDefaultFeature() {
-        openCamera(context.createFeatureContext(null))
+    fun openCameraWithDefaultAttribution() {
+        openCamera(context.createAttributionContext(null))
     }
 
     /**
@@ -625,13 +621,13 @@
     fun getMultiSimSupport() {
         assumeTrue(context.packageManager.hasSystemFeature(FEATURE_TELEPHONY))
 
-        val telephonyManager = context.createFeatureContext(TEST_FEATURE_ID)
+        val telephonyManager = context.createAttributionContext(TEST_ATTRIBUTION_TAG)
             .getSystemService(TelephonyManager::class.java)
 
         telephonyManager.isMultiSimSupported
 
         assertThat(noted[0].first.op).isEqualTo(OPSTR_READ_PHONE_STATE)
-        assertThat(noted[0].first.featureId).isEqualTo(TEST_FEATURE_ID)
+        assertThat(noted[0].first.attributionTag).isEqualTo(TEST_ATTRIBUTION_TAG)
         assertThat(noted[0].second.map { it.methodName }).contains("getMultiSimSupport")
     }
 
@@ -640,13 +636,13 @@
      */
     @Test
     fun getWallpaper() {
-        val wallpaperManager = context.createFeatureContext(TEST_FEATURE_ID)
+        val wallpaperManager = context.createAttributionContext(TEST_ATTRIBUTION_TAG)
                 .getSystemService(WallpaperManager::class.java)
 
         wallpaperManager.getWallpaperFile(FLAG_SYSTEM)
 
         assertThat(noted[0].first.op).isEqualTo(OPSTR_READ_EXTERNAL_STORAGE)
-        assertThat(noted[0].first.featureId).isEqualTo(TEST_FEATURE_ID)
+        assertThat(noted[0].first.attributionTag).isEqualTo(TEST_ATTRIBUTION_TAG)
         assertThat(noted[0].second.map { it.methodName }).contains("getWallpaper")
     }
 
@@ -655,13 +651,13 @@
      */
     @Test
     fun isInCall() {
-        val telecomManager = context.createFeatureContext(TEST_FEATURE_ID)
+        val telecomManager = context.createAttributionContext(TEST_ATTRIBUTION_TAG)
                 .getSystemService(TelecomManager::class.java)
 
         telecomManager.isInCall()
 
         assertThat(noted[0].first.op).isEqualTo(OPSTR_READ_PHONE_STATE)
-        assertThat(noted[0].first.featureId).isEqualTo(TEST_FEATURE_ID)
+        assertThat(noted[0].first.attributionTag).isEqualTo(TEST_ATTRIBUTION_TAG)
         assertThat(noted[0].second.map { it.methodName }).contains("isInCall")
     }
 
@@ -670,19 +666,19 @@
      */
     @Test
     fun startActivity() {
-        context.createFeatureContext(TEST_FEATURE_ID).startActivity(
+        context.createAttributionContext(TEST_ATTRIBUTION_TAG).startActivity(
                 Intent().setComponent(ComponentName(TEST_SERVICE_PKG,
                         TEST_SERVICE_PKG + ".AutoClosingActivity"))
                         .setFlags(FLAG_ACTIVITY_NEW_TASK))
 
         assertThat(noted[0].first.op).isEqualTo(OPSTR_FINE_LOCATION)
-        assertThat(noted[0].first.featureId).isEqualTo(TEST_FEATURE_ID)
+        assertThat(noted[0].first.attributionTag).isEqualTo(TEST_ATTRIBUTION_TAG)
         assertThat(noted[0].second.map { it.methodName }).contains("startActivity")
     }
 
     @After
     fun removeNotedAppOpsCollector() {
-        appOpsManager.setNotedAppOpsCollector(null)
+        appOpsManager.setOnOpNotedCallback(null, null)
     }
 
     @After
@@ -711,10 +707,10 @@
             }
         }
 
-        override fun noteSyncOpWithFeature(featureId: String) {
+        override fun noteSyncOpWithAttribution(attributionTag: String) {
             runWithShellPermissionIdentity {
                 appOpsManager.noteOpNoThrow(OPSTR_COARSE_LOCATION, getCallingUid(),
-                    TEST_SERVICE_PKG, featureId, null)
+                    TEST_SERVICE_PKG, attributionTag, null)
             }
         }
 
@@ -794,13 +790,13 @@
             }
         }
 
-        override fun noteAsyncOpWithFeature(featureId: String) {
+        override fun noteAsyncOpWithAttribution(attributionTag: String) {
             val callingUid = getCallingUid()
 
             handler.post {
                 runWithShellPermissionIdentity {
                     appOpsManager.noteOpNoThrow(OPSTR_COARSE_LOCATION, callingUid, TEST_SERVICE_PKG,
-                        featureId, null)
+                        attributionTag, null)
                 }
             }
         }
diff --git a/tests/tests/appop/src/android/app/appops/cts/AppOpsTest.kt b/tests/tests/appop/src/android/app/appops/cts/AppOpsTest.kt
index f9f8d47..3b4dda1 100644
--- a/tests/tests/appop/src/android/app/appops/cts/AppOpsTest.kt
+++ b/tests/tests/appop/src/android/app/appops/cts/AppOpsTest.kt
@@ -228,7 +228,7 @@
     }
 
     @Test
-    fun overlappingActiveFeatureOps() {
+    fun overlappingActiveAttributionOps() {
         runWithShellPermissionIdentity {
             val gotActive = CompletableFuture<Unit>()
             val gotInActive = CompletableFuture<Unit>()
@@ -249,17 +249,17 @@
             mAppOps.startWatchingActive(arrayOf(OPSTR_WRITE_CALENDAR), Executor { it.run() },
                 activeWatcher)
             try {
-                mAppOps.startOp(OPSTR_WRITE_CALENDAR, mMyUid, mOpPackageName, "feature1", null)
+                mAppOps.startOp(OPSTR_WRITE_CALENDAR, mMyUid, mOpPackageName, "attribution1", null)
                 assertTrue(mAppOps.isOpActive(OPSTR_WRITE_CALENDAR, mMyUid, mOpPackageName))
                 gotActive.get(TIMEOUT_MS, TimeUnit.MILLISECONDS)
 
                 mAppOps.startOp(OPSTR_WRITE_CALENDAR, Process.myUid(), mOpPackageName,
-                    "feature2", null)
+                    "attribution2", null)
                 assertTrue(mAppOps.isOpActive(OPSTR_WRITE_CALENDAR, mMyUid, mOpPackageName))
                 assertFalse(gotInActive.isDone)
 
                 mAppOps.finishOp(OPSTR_WRITE_CALENDAR, Process.myUid(), mOpPackageName,
-                    "feature1")
+                    "attribution1")
 
                 // Allow some time for premature "watchingActive" callbacks to arrive
                 Thread.sleep(500)
@@ -268,7 +268,7 @@
                 assertFalse(gotInActive.isDone)
 
                 mAppOps.finishOp(OPSTR_WRITE_CALENDAR, Process.myUid(), mOpPackageName,
-                    "feature2")
+                    "attribution2")
                 assertFalse(mAppOps.isOpActive(OPSTR_WRITE_CALENDAR, mMyUid, mOpPackageName))
                 gotInActive.get(TIMEOUT_MS, TimeUnit.MILLISECONDS)
             } finally {
diff --git a/tests/tests/appop/src/android/app/appops/cts/AttributionTest.kt b/tests/tests/appop/src/android/app/appops/cts/AttributionTest.kt
new file mode 100644
index 0000000..0bdf312
--- /dev/null
+++ b/tests/tests/appop/src/android/app/appops/cts/AttributionTest.kt
@@ -0,0 +1,138 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.app.appops.cts
+
+import android.app.AppOpsManager
+import android.app.AppOpsManager.OPSTR_WIFI_SCAN
+import android.app.AppOpsManager.OP_FLAGS_ALL
+import android.platform.test.annotations.AppModeFull
+import androidx.test.platform.app.InstrumentationRegistry
+import com.google.common.truth.Truth.assertThat
+import org.junit.Before
+import org.junit.Test
+import java.lang.AssertionError
+import java.lang.Thread.sleep
+
+private const val APK_PATH = "/data/local/tmp/cts/appops/"
+
+private const val APP_PKG = "android.app.appops.cts.apptoblame"
+
+private const val ATTRIBUTION_1 = "attribution1"
+private const val ATTRIBUTION_2 = "attribution2"
+private const val ATTRIBUTION_3 = "attribution3"
+private const val ATTRIBUTION_4 = "attribution4"
+private const val ATTRIBUTION_5 = "attribution5"
+private const val ATTRIBUTION_6 = "attribution6"
+private const val ATTRIBUTION_7 = "attribution7"
+
+@AppModeFull(reason = "Test relies on seeing other apps. Instant apps can't see other apps")
+class AttributionTest {
+    private val instrumentation = InstrumentationRegistry.getInstrumentation()
+    private val context = instrumentation.targetContext
+    private val appOpsManager = context.getSystemService(AppOpsManager::class.java)
+    private val appUid by lazy { context.packageManager.getPackageUid(APP_PKG, 0) }
+
+    private fun installApk(apk: String) {
+        val result = runCommand("pm install -r --force-queryable $APK_PATH$apk")
+        assertThat(result.trim()).isEqualTo("Success")
+    }
+
+    @Before
+    fun resetTestApp() {
+        runCommand("pm uninstall $APP_PKG")
+        installApk("CtsAppToBlame1.apk")
+    }
+
+    private fun noteForAttribution(attribution: String) {
+        // Make sure note times as distinct
+        sleep(1)
+
+        runWithShellPermissionIdentity {
+            appOpsManager.noteOpNoThrow(OPSTR_WIFI_SCAN, appUid, APP_PKG, attribution, null)
+        }
+    }
+
+    @Test
+    fun inheritNotedAppOpsOnUpgrade() {
+        noteForAttribution(ATTRIBUTION_1)
+        noteForAttribution(ATTRIBUTION_2)
+        noteForAttribution(ATTRIBUTION_3)
+        noteForAttribution(ATTRIBUTION_4)
+        noteForAttribution(ATTRIBUTION_5)
+
+        val beforeUpdate = getOpEntry(appUid, APP_PKG, OPSTR_WIFI_SCAN)!!
+        installApk("CtsAppToBlame2.apk")
+
+        eventually {
+            val afterUpdate = getOpEntry(appUid, APP_PKG, OPSTR_WIFI_SCAN)!!
+
+            // Attribution 1 is unchanged
+            assertThat(afterUpdate.attributedOpEntries[ATTRIBUTION_1]!!
+                    .getLastAccessTime(OP_FLAGS_ALL))
+                    .isEqualTo(beforeUpdate.attributedOpEntries[ATTRIBUTION_1]!!
+                            .getLastAccessTime(OP_FLAGS_ALL))
+
+            // Attribution 3 disappeared (i.e. was added into "null" attribution)
+            assertThat(afterUpdate.attributedOpEntries[null]!!.getLastAccessTime(OP_FLAGS_ALL))
+                    .isEqualTo(beforeUpdate.attributedOpEntries[ATTRIBUTION_3]!!
+                            .getLastAccessTime(OP_FLAGS_ALL))
+
+            // Attribution 6 inherits from attribution 2
+            assertThat(afterUpdate.attributedOpEntries[ATTRIBUTION_6]!!
+                    .getLastAccessTime(OP_FLAGS_ALL))
+                    .isEqualTo(beforeUpdate.attributedOpEntries[ATTRIBUTION_2]!!
+                            .getLastAccessTime(OP_FLAGS_ALL))
+
+            // Attribution 7 inherits from attribution 4 and 5. 5 was noted after 4, hence 4 is
+            // removed
+            assertThat(afterUpdate.attributedOpEntries[ATTRIBUTION_7]!!
+                    .getLastAccessTime(OP_FLAGS_ALL))
+                    .isEqualTo(beforeUpdate.attributedOpEntries[ATTRIBUTION_5]!!
+                            .getLastAccessTime(OP_FLAGS_ALL))
+        }
+    }
+
+    @Test(expected = AssertionError::class)
+    fun cannotInheritFromSelf() {
+        installApk("AppWithAttributionInheritingFromSelf.apk")
+    }
+
+    @Test(expected = AssertionError::class)
+    fun noDuplicateAttributions() {
+        installApk("AppWithDuplicateAttribution.apk")
+    }
+
+    @Test(expected = AssertionError::class)
+    fun cannotInheritFromExisting() {
+        installApk("AppWithAttributionInheritingFromExisting.apk")
+    }
+
+    @Test(expected = AssertionError::class)
+    fun cannotInheritFromSameAsOther() {
+        installApk("AppWithAttributionInheritingFromSameAsOther.apk")
+    }
+
+    @Test(expected = AssertionError::class)
+    fun cannotUseVeryLongAttributionTags() {
+        installApk("AppWithLongAttributionTag.apk")
+    }
+
+    @Test(expected = AssertionError::class)
+    fun cannotUseTooManyAttributions() {
+        installApk("AppWithTooManyAttributions.apk")
+    }
+}
\ No newline at end of file
diff --git a/tests/tests/appop/src/android/app/appops/cts/FeatureTest.kt b/tests/tests/appop/src/android/app/appops/cts/FeatureTest.kt
deleted file mode 100644
index d199055..0000000
--- a/tests/tests/appop/src/android/app/appops/cts/FeatureTest.kt
+++ /dev/null
@@ -1,130 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.app.appops.cts
-
-import android.app.AppOpsManager
-import android.app.AppOpsManager.OPSTR_WIFI_SCAN
-import android.app.AppOpsManager.OP_FLAGS_ALL
-import android.platform.test.annotations.AppModeFull
-import androidx.test.platform.app.InstrumentationRegistry
-import com.google.common.truth.Truth.assertThat
-import org.junit.Before
-import org.junit.Test
-import java.lang.AssertionError
-import java.lang.Thread.sleep
-
-private const val APK_PATH = "/data/local/tmp/cts/appops/"
-
-private const val APP_PKG = "android.app.appops.cts.apptoblame"
-
-private const val FEATURE_1 = "feature1"
-private const val FEATURE_2 = "feature2"
-private const val FEATURE_3 = "feature3"
-private const val FEATURE_4 = "feature4"
-private const val FEATURE_5 = "feature5"
-private const val FEATURE_6 = "feature6"
-private const val FEATURE_7 = "feature7"
-
-@AppModeFull(reason = "Test relies on seeing other apps. Instant apps can't see other apps")
-class FeatureTest {
-    private val instrumentation = InstrumentationRegistry.getInstrumentation()
-    private val context = instrumentation.targetContext
-    private val appOpsManager = context.getSystemService(AppOpsManager::class.java)
-    private val appUid by lazy { context.packageManager.getPackageUid(APP_PKG, 0) }
-
-    private fun installApk(apk: String) {
-        val result = runCommand("pm install -r --force-queryable $APK_PATH$apk")
-        assertThat(result.trim()).isEqualTo("Success")
-    }
-
-    @Before
-    fun resetTestApp() {
-        runCommand("pm uninstall $APP_PKG")
-        installApk("CtsAppToBlame1.apk")
-    }
-
-    private fun noteForFeature(feature: String) {
-        // Make sure note times as distinct
-        sleep(1)
-
-        runWithShellPermissionIdentity {
-            appOpsManager.noteOpNoThrow(OPSTR_WIFI_SCAN, appUid, APP_PKG, feature, null)
-        }
-    }
-
-    @Test
-    fun inheritNotedAppOpsOnUpgrade() {
-        noteForFeature(FEATURE_1)
-        noteForFeature(FEATURE_2)
-        noteForFeature(FEATURE_3)
-        noteForFeature(FEATURE_4)
-        noteForFeature(FEATURE_5)
-
-        val beforeUpdate = getOpEntry(appUid, APP_PKG, OPSTR_WIFI_SCAN)!!
-        installApk("CtsAppToBlame2.apk")
-
-        eventually {
-            val afterUpdate = getOpEntry(appUid, APP_PKG, OPSTR_WIFI_SCAN)!!
-
-            // Feature 1 is unchanged
-            assertThat(afterUpdate.features[FEATURE_1]!!.getLastAccessTime(OP_FLAGS_ALL))
-                    .isEqualTo(beforeUpdate.features[FEATURE_1]!!.getLastAccessTime(OP_FLAGS_ALL))
-
-            // Feature 3 disappeared (i.e. was added into "null" feature)
-            assertThat(afterUpdate.features[null]!!.getLastAccessTime(OP_FLAGS_ALL))
-                    .isEqualTo(beforeUpdate.features[FEATURE_3]!!.getLastAccessTime(OP_FLAGS_ALL))
-
-            // Feature 6 inherits from feature 2
-            assertThat(afterUpdate.features[FEATURE_6]!!.getLastAccessTime(OP_FLAGS_ALL))
-                    .isEqualTo(beforeUpdate.features[FEATURE_2]!!.getLastAccessTime(OP_FLAGS_ALL))
-
-            // Feature 7 inherits from feature 4 and 5. 5 was noted after 4, hence 4 is removed
-            assertThat(afterUpdate.features[FEATURE_7]!!.getLastAccessTime(OP_FLAGS_ALL))
-                    .isEqualTo(beforeUpdate.features[FEATURE_5]!!.getLastAccessTime(OP_FLAGS_ALL))
-        }
-    }
-
-    @Test(expected = AssertionError::class)
-    fun cannotInheritFromSelf() {
-        installApk("AppWithFeatureInheritingFromSelf.apk")
-    }
-
-    @Test(expected = AssertionError::class)
-    fun noDuplicateFeatures() {
-        installApk("AppWithDuplicateFeature.apk")
-    }
-
-    @Test(expected = AssertionError::class)
-    fun cannotInheritFromExisting() {
-        installApk("AppWithFeatureInheritingFromExisting.apk")
-    }
-
-    @Test(expected = AssertionError::class)
-    fun cannotInheritFromSameAsOther() {
-        installApk("AppWithFeatureInheritingFromSameAsOther.apk")
-    }
-
-    @Test(expected = AssertionError::class)
-    fun cannotUseVeryLongFeatureIDs() {
-        installApk("AppWithLongFeatureIdFeature.apk")
-    }
-
-    @Test(expected = AssertionError::class)
-    fun cannotUseTooManyFeatures() {
-        installApk("AppWithTooManyFeatures.apk")
-    }
-}
\ No newline at end of file
diff --git a/tests/tests/appop/src/android/app/appops/cts/HistoricalAppopsTest.kt b/tests/tests/appop/src/android/app/appops/cts/HistoricalAppopsTest.kt
index 28ebc26..eaef444 100644
--- a/tests/tests/appop/src/android/app/appops/cts/HistoricalAppopsTest.kt
+++ b/tests/tests/appop/src/android/app/appops/cts/HistoricalAppopsTest.kt
@@ -201,7 +201,7 @@
     }
 
     @Test
-    fun testGetHistoricalAggregationOverFeatures() {
+    fun testGetHistoricalAggregationOverAttributions() {
         // Configure historical registry behavior.
         appOpsManager.setHistoryParameters(
                 AppOpsManager.HISTORICAL_MODE_ENABLED_ACTIVE,
@@ -212,17 +212,19 @@
 
         UidStateForceActivity.waitForResumed()
 
-        appOpsManager.noteOp(OPSTR_REQUEST_DELETE_PACKAGES, uid, packageName, "firstFeature", null)
-        appOpsManager.noteOp(OPSTR_REQUEST_DELETE_PACKAGES, uid, packageName, "secondFeature", null)
+        appOpsManager.noteOp(OPSTR_REQUEST_DELETE_PACKAGES, uid, packageName, "firstAttribution",
+                null)
+        appOpsManager.noteOp(OPSTR_REQUEST_DELETE_PACKAGES, uid, packageName, "secondAttribution",
+                null)
 
         val memOps = getHistoricalOps(appOpsManager, uid = uid)!!
 
         assertThat(memOps.getUidOpsAt(0).getPackageOpsAt(0).getOp(OPSTR_REQUEST_DELETE_PACKAGES)!!
                 .getForegroundAccessCount(OP_FLAGS_ALL)).isEqualTo(2)
-        assertThat(memOps.getUidOpsAt(0).getPackageOpsAt(0).getFeatureOps("firstFeature")!!
+        assertThat(memOps.getUidOpsAt(0).getPackageOpsAt(0).getAttributedOps("firstAttribution")!!
                 .getOp(OPSTR_REQUEST_DELETE_PACKAGES)!!.getForegroundAccessCount(OP_FLAGS_ALL))
                 .isEqualTo(1)
-        assertThat(memOps.getUidOpsAt(0).getPackageOpsAt(0).getFeatureOps("secondFeature")!!
+        assertThat(memOps.getUidOpsAt(0).getPackageOpsAt(0).getAttributedOps("secondAttribution")!!
                 .getOp(OPSTR_REQUEST_DELETE_PACKAGES)!!.getForegroundAccessCount(OP_FLAGS_ALL))
                 .isEqualTo(1)
 
diff --git a/tests/tests/appop/src/android/app/appops/cts/RuntimeMessageCollectionTest.kt b/tests/tests/appop/src/android/app/appops/cts/RuntimeMessageCollectionTest.kt
index e6730c1..d5e8748 100644
--- a/tests/tests/appop/src/android/app/appops/cts/RuntimeMessageCollectionTest.kt
+++ b/tests/tests/appop/src/android/app/appops/cts/RuntimeMessageCollectionTest.kt
@@ -58,7 +58,7 @@
             val start = System.currentTimeMillis()
             runWithShellPermissionIdentity {
                 appOpsManager.noteOp(AppOpsManager.OPSTR_READ_CONTACTS, appUid, APP_PKG,
-                        TEST_FEATURE_ID, MESSAGE)
+                        TEST_ATTRIBUTION_TAG, MESSAGE)
             }
             while (System.currentTimeMillis() - start < TIMEOUT_MILLIS) {
                 sleep(200)
@@ -68,7 +68,7 @@
                     if (message != null && message.packageName.equals(APP_PKG)) {
                         assertThat(message.op).isEqualTo(AppOpsManager.OPSTR_READ_CONTACTS)
                         assertThat(message.uid).isEqualTo(appUid)
-                        assertThat(message.featureId).isEqualTo(TEST_FEATURE_ID)
+                        assertThat(message.attributionTag).isEqualTo(TEST_ATTRIBUTION_TAG)
                         assertThat(message.message).isEqualTo(MESSAGE)
                         assertThat(message.samplingStrategy)
                                 .isEqualTo(RUNTIME_APP_OP_ACCESS__SAMPLING_STRATEGY__RARELY_USED)
diff --git a/tests/tests/batterysaving/AndroidManifest.xml b/tests/tests/batterysaving/AndroidManifest.xml
index 9f326e0..55e9050 100755
--- a/tests/tests/batterysaving/AndroidManifest.xml
+++ b/tests/tests/batterysaving/AndroidManifest.xml
@@ -21,6 +21,7 @@
     <uses-permission android:name="android.permission.ACCESS_MOCK_LOCATION"/>
     <!-- Needed to whitelist package to be able to avoid request throttling. -->
     <uses-permission android:name="android.permission.WRITE_SECURE_SETTINGS" />
+    <uses-permission android:name="android.permission.READ_DEVICE_CONFIG" />
 
     <application>
         <uses-library android:name="android.test.runner" />
@@ -33,4 +34,4 @@
             android:value="com.android.cts.runner.CtsTestRunListener" />
     </instrumentation>
 
-</manifest>
\ No newline at end of file
+</manifest>
diff --git a/tests/tests/batterysaving/src/android/os/cts/batterysaving/BatterySaverTest.java b/tests/tests/batterysaving/src/android/os/cts/batterysaving/BatterySaverTest.java
index afae17e..56fce94 100644
--- a/tests/tests/batterysaving/src/android/os/cts/batterysaving/BatterySaverTest.java
+++ b/tests/tests/batterysaving/src/android/os/cts/batterysaving/BatterySaverTest.java
@@ -17,6 +17,7 @@
 
 import static com.android.compatibility.common.util.BatteryUtils.enableBatterySaver;
 import static com.android.compatibility.common.util.BatteryUtils.runDumpsysBatteryUnplug;
+import static com.android.compatibility.common.util.TestUtils.waitUntil;
 
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertFalse;
@@ -112,36 +113,38 @@
 
             enableBatterySaver(true);
 
-            // Allow time for UI change.
-            Thread.sleep(1000);
             assertTrue(powerManager.isPowerSaveMode());
             assertEquals(PowerManager.LOCATION_MODE_ALL_DISABLED_WHEN_SCREEN_OFF,
                     powerManager.getLocationPowerSaveMode());
-            assertEquals(Configuration.UI_MODE_NIGHT_YES,
-                    getContext().getResources().getConfiguration().uiMode
-                        & Configuration.UI_MODE_NIGHT_MASK);
+            // UI change can take a while to propagate, so need to wait for this check.
+            waitUntil("UI mode didn't change to " + Configuration.UI_MODE_NIGHT_YES,
+                    () -> Configuration.UI_MODE_NIGHT_YES ==
+                            (getContext().getResources().getConfiguration().uiMode
+                                    & Configuration.UI_MODE_NIGHT_MASK));
 
             uiModeManager.enableCarMode(0);
-            // Allow time for UI change.
-            Thread.sleep(1000);
 
+            // Wait for UI change first before checking location mode since we can then be
+            // confident that the broadcast has been processed.
+            waitUntil("UI mode didn't change to " + Configuration.UI_MODE_NIGHT_NO,
+                    () -> Configuration.UI_MODE_NIGHT_NO ==
+                            (getContext().getResources().getConfiguration().uiMode
+                                    & Configuration.UI_MODE_NIGHT_MASK));
             final int locationPowerSaveMode = powerManager.getLocationPowerSaveMode();
             assertTrue("Location power save mode didn't change from " + locationPowerSaveMode,
                     locationPowerSaveMode == PowerManager.LOCATION_MODE_FOREGROUND_ONLY
                             || locationPowerSaveMode == PowerManager.LOCATION_MODE_NO_CHANGE);
-            assertEquals(Configuration.UI_MODE_NIGHT_NO,
-                getContext().getResources().getConfiguration().uiMode
-                    & Configuration.UI_MODE_NIGHT_MASK);
 
             uiModeManager.disableCarMode(0);
-            // Allow time for UI change.
-            Thread.sleep(1000);
 
+            // Wait for UI change first before checking location mode since we can then be
+            // confident that the broadcast has been processed.
+            waitUntil("UI mode didn't change to " + Configuration.UI_MODE_NIGHT_YES,
+                    () -> Configuration.UI_MODE_NIGHT_YES ==
+                            (getContext().getResources().getConfiguration().uiMode
+                                    & Configuration.UI_MODE_NIGHT_MASK));
             assertEquals(PowerManager.LOCATION_MODE_ALL_DISABLED_WHEN_SCREEN_OFF,
                 powerManager.getLocationPowerSaveMode());
-            assertEquals(Configuration.UI_MODE_NIGHT_YES,
-                getContext().getResources().getConfiguration().uiMode
-                    & Configuration.UI_MODE_NIGHT_MASK);
         } finally {
             uiModeManager.disableCarMode(0);
             SettingsUtils.delete(SettingsUtils.NAMESPACE_GLOBAL, "battery_saver_constants");
diff --git a/tests/tests/car/AndroidManifest.xml b/tests/tests/car/AndroidManifest.xml
index d146b32..3894b0b 100644
--- a/tests/tests/car/AndroidManifest.xml
+++ b/tests/tests/car/AndroidManifest.xml
@@ -29,6 +29,8 @@
     <uses-permission android:name="android.permission.BLUETOOTH_ADMIN" />
     <uses-permission android:name="android.permission.INTERACT_ACROSS_USERS" />
     <uses-permission android:name="android.permission.INTERACT_ACROSS_USERS_FULL" />
+    <!-- Allow query of any normal app on the device -->
+    <uses-permission android:name="android.permission.QUERY_ALL_PACKAGES" />
 
     <application>
         <uses-library android:name="android.test.runner" />
diff --git a/tests/tests/car/res/values/minimum_required_packages.xml b/tests/tests/car/res/values/minimum_required_packages.xml
new file mode 100644
index 0000000..b730bbf
--- /dev/null
+++ b/tests/tests/car/res/values/minimum_required_packages.xml
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  ~ Copyright (C) 2020 The Android Open Source Project
+  ~
+  ~ Licensed under the Apache License, Version 2.0 (the "License");
+  ~ you may not use this file except in compliance with the License.
+  ~ You may obtain a copy of the License at
+  ~
+  ~      http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing, software
+  ~ distributed under the License is distributed on an "AS IS" BASIS,
+  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  ~ See the License for the specific language governing permissions and
+  ~ limitations under the License
+  -->
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+        xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string-array translatable="false" name="installed_system_and_full">
+        <item>android</item>
+        <item>com.android.car</item>
+        <item>com.android.car.frameworkpackagestubs</item>
+    </string-array>
+
+    <string-array translatable="false" name="installed_full_only">
+        <item>com.google.android.carassistant</item>
+    </string-array>
+</resources>
\ No newline at end of file
diff --git a/tests/tests/car/src/android/car/cts/CarApiTestBase.java b/tests/tests/car/src/android/car/cts/CarApiTestBase.java
index 445593b..6d3ffbc 100644
--- a/tests/tests/car/src/android/car/cts/CarApiTestBase.java
+++ b/tests/tests/car/src/android/car/cts/CarApiTestBase.java
@@ -20,6 +20,8 @@
 import static org.junit.Assume.assumeTrue;
 
 import android.car.Car;
+import android.car.FuelType;
+import android.car.PortLocationType;
 import android.content.ComponentName;
 import android.content.Context;
 import android.content.ServiceConnection;
@@ -32,6 +34,8 @@
 
 import org.junit.After;
 
+import java.util.Arrays;
+import java.util.List;
 import java.util.concurrent.Semaphore;
 import java.util.concurrent.TimeUnit;
 
@@ -40,6 +44,17 @@
 
     private Car mCar;
 
+    // Enums in FuelType
+    final static List<Integer> EXPECTED_FUEL_TYPES =
+            Arrays.asList(FuelType.UNKNOWN, FuelType.UNLEADED, FuelType.LEADED, FuelType.DIESEL_1,
+                    FuelType.DIESEL_2, FuelType.BIODIESEL, FuelType.E85, FuelType.LPG, FuelType.CNG,
+                    FuelType.LNG, FuelType.ELECTRIC, FuelType.HYDROGEN, FuelType.OTHER);
+    // Enums in PortLocationType
+    final static List<Integer> EXPECTED_PORT_LOCATIONS =
+            Arrays.asList(PortLocationType.UNKNOWN, PortLocationType.FRONT_LEFT,
+                    PortLocationType.FRONT_RIGHT, PortLocationType.REAR_RIGHT,
+                    PortLocationType.REAR_LEFT, PortLocationType.FRONT, PortLocationType.REAR);
+
     private final DefaultServiceConnectionListener mConnectionListener =
             new DefaultServiceConnectionListener();
 
diff --git a/tests/tests/car/src/android/car/cts/CarInfoManagerTest.java b/tests/tests/car/src/android/car/cts/CarInfoManagerTest.java
index e3ca341..f901a4a 100644
--- a/tests/tests/car/src/android/car/cts/CarInfoManagerTest.java
+++ b/tests/tests/car/src/android/car/cts/CarInfoManagerTest.java
@@ -29,7 +29,6 @@
 import static com.google.common.truth.Truth.assertThat;
 import androidx.test.runner.AndroidJUnit4;
 
-import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.List;
 import org.junit.Before;
@@ -85,14 +84,9 @@
     @Test
     public void testGetFuelTypes() throws Exception {
         assertNotNull(mCarInfoManager.getFuelTypes());
-
         int[] actualResults = mCarInfoManager.getFuelTypes();
-        List<Integer> expectedResults =
-            Arrays.asList(FuelType.UNKNOWN, FuelType.UNLEADED, FuelType.LEADED, FuelType.DIESEL_1,
-                FuelType.DIESEL_2, FuelType.BIODIESEL, FuelType.E85, FuelType.LPG, FuelType.CNG,
-                FuelType.LNG, FuelType.ELECTRIC, FuelType.HYDROGEN, FuelType.OTHER);
         for (int result : actualResults) {
-            assertThat(expectedResults).contains(result);
+            assertThat(result).isIn(EXPECTED_FUEL_TYPES);
         }
 
     }
@@ -120,7 +114,7 @@
                 SCAME, GBT_DC);
 
         for (int result : actualResults) {
-            assertThat(expectedResults).contains(result);
+            assertThat(result).isIn(expectedResults);
         }
     }
 
@@ -136,7 +130,7 @@
                 VehicleAreaSeat.SEAT_ROW_2_LEFT, VehicleAreaSeat.SEAT_ROW_2_CENTER,
                 VehicleAreaSeat.SEAT_ROW_2_RIGHT, VehicleAreaSeat.SEAT_ROW_3_LEFT,
                 VehicleAreaSeat.SEAT_ROW_3_CENTER, VehicleAreaSeat.SEAT_ROW_1_RIGHT);
-        assertThat(expectedResult).contains(mCarInfoManager.getDriverSeat());
+        assertThat(mCarInfoManager.getDriverSeat()).isIn(expectedResult);
     }
 
     /**
@@ -145,11 +139,7 @@
      */
     @Test
     public void testGetEvPortLocation() throws Exception {
-        List<Integer> expectedResult =
-            Arrays.asList(PortLocationType.UNKNOWN, PortLocationType.FRONT_LEFT,
-                PortLocationType.FRONT_RIGHT, PortLocationType.REAR_RIGHT,
-                PortLocationType.REAR_LEFT, PortLocationType.FRONT, PortLocationType.REAR);
-        assertThat(expectedResult).contains(mCarInfoManager.getEvPortLocation());
+        assertThat(mCarInfoManager.getEvPortLocation()).isIn(EXPECTED_PORT_LOCATIONS);
     }
 
     /**
@@ -158,10 +148,6 @@
      */
     @Test
     public void testGetFuelDoorLocation() throws Exception {
-        List<Integer> expectedResult =
-            Arrays.asList(PortLocationType.UNKNOWN, PortLocationType.FRONT_LEFT,
-                        PortLocationType.FRONT_RIGHT, PortLocationType.REAR_RIGHT,
-                        PortLocationType.REAR_LEFT, PortLocationType.FRONT, PortLocationType.REAR);
-        assertThat(expectedResult).contains(mCarInfoManager.getFuelDoorLocation());
+        assertThat(mCarInfoManager.getFuelDoorLocation()).isIn(EXPECTED_PORT_LOCATIONS);
     }
 }
diff --git a/tests/tests/car/src/android/car/cts/CarPackageManagerTest.java b/tests/tests/car/src/android/car/cts/CarPackageManagerTest.java
index 357f985..865b986 100644
--- a/tests/tests/car/src/android/car/cts/CarPackageManagerTest.java
+++ b/tests/tests/car/src/android/car/cts/CarPackageManagerTest.java
@@ -19,9 +19,10 @@
 import static org.junit.Assert.assertTrue;
 import static org.junit.Assert.fail;
 
+import android.app.PendingIntent;
 import android.car.Car;
-import android.car.CarNotConnectedException;
 import android.car.content.pm.CarPackageManager;
+import android.content.Intent;
 import android.os.Build;
 import android.platform.test.annotations.RequiresDevice;
 import android.test.suitebuilder.annotation.SmallTest;
@@ -76,7 +77,7 @@
     }
 
     @Test
-    public void testDistractionOptimizedActivityIsAllowed() throws CarNotConnectedException {
+    public void testDistractionOptimizedActivityIsAllowed() {
         // This test relies on test activity in installed apk, and AndroidManifest declaration.
         if (Build.TYPE.equalsIgnoreCase("user")) {
             // Skip this test on user build, which checks the install source for DO activity list.
@@ -87,7 +88,7 @@
     }
 
     @Test
-    public void testNonDistractionOptimizedActivityNotAllowed() throws CarNotConnectedException {
+    public void testNonDistractionOptimizedActivityNotAllowed() {
         // This test relies on test activity in installed apk, and AndroidManifest declaration.
         if (Build.TYPE.equalsIgnoreCase("user")) {
             // Skip this test on user build, which checks the install source for DO activity list.
@@ -96,4 +97,34 @@
         assertFalse(mCarPm.isActivityDistractionOptimized("android.car.cts",
                 "android.car.cts.drivingstate.NonDistractionOptimizedActivity"));
     }
+
+    private PendingIntent createIntent(String packageName, String relativeClassName) {
+        Intent intent = new Intent();
+        intent.setClassName(packageName, packageName + relativeClassName);
+        intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+        return PendingIntent.getActivity(sContext, 0, intent, 0);
+    }
+
+    @Test
+    public void testPendingIntentToDistractionOptimizedActivityIsAllowed() {
+        // This test relies on test activity in installed apk, and AndroidManifest declaration.
+        if (Build.TYPE.equalsIgnoreCase("user")) {
+            // Skip this test on user build, which checks the install source for DO activity list.
+            return;
+        }
+        assertTrue(mCarPm.isPendingIntentDistractionOptimized(
+                createIntent("android.car.cts", ".drivingstate.DistractionOptimizedActivity")));
+    }
+
+    @Test
+    public void testPendingIntentToNonDistractionOptimizedActivityNotAllowed() {
+        // This test relies on test activity in installed apk, and AndroidManifest declaration.
+        if (Build.TYPE.equalsIgnoreCase("user")) {
+            // Skip this test on user build, which checks the install source for DO activity list.
+            return;
+        }
+        assertFalse(mCarPm.isPendingIntentDistractionOptimized(
+                createIntent("android.car.cts", ".drivingstate.NonDistractionOptimizedActivity")));
+    }
+
 }
diff --git a/tests/tests/car/src/android/car/cts/CarPropertyManagerTest.java b/tests/tests/car/src/android/car/cts/CarPropertyManagerTest.java
index 770f20d..8f2057d 100644
--- a/tests/tests/car/src/android/car/cts/CarPropertyManagerTest.java
+++ b/tests/tests/car/src/android/car/cts/CarPropertyManagerTest.java
@@ -15,6 +15,9 @@
  */
 package android.car.cts;
 
+import static org.testng.Assert.assertThrows;
+import static com.google.common.truth.Truth.assertThat;
+
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertFalse;
 import static org.junit.Assert.assertNotEquals;
@@ -25,6 +28,7 @@
 
 import android.car.Car;
 import android.car.VehicleAreaSeat;
+import android.car.VehicleAreaType;
 import android.car.VehiclePropertyIds;
 import android.car.hardware.CarPropertyConfig;
 import android.car.hardware.CarPropertyValue;
@@ -42,6 +46,7 @@
 import com.android.compatibility.common.util.CddTest;
 
 import org.junit.Assert;
+import org.junit.Assume;
 import org.junit.Before;
 import org.junit.Test;
 import org.junit.runner.RunWith;
@@ -234,6 +239,47 @@
     }
 
     @Test
+    public void testGetIntArrayProperty() {
+        List<CarPropertyConfig> allConfigs = mCarPropertyManager.getPropertyList();
+        for (CarPropertyConfig cfg : allConfigs) {
+            if (cfg.getAccess() == CarPropertyConfig.VEHICLE_PROPERTY_ACCESS_NONE
+                    || cfg.getAccess() == CarPropertyConfig.VEHICLE_PROPERTY_ACCESS_WRITE
+                    || cfg.getPropertyType() != Integer[].class) {
+                // skip the test if the property is not readable or not an int array type property.
+                continue;
+            }
+            switch (cfg.getPropertyId()) {
+                case VehiclePropertyIds.INFO_FUEL_TYPE:
+                    int[] fuelTypes = mCarPropertyManager.getIntArrayProperty(cfg.getPropertyId(),
+                            VehicleAreaType.VEHICLE_AREA_TYPE_GLOBAL);
+                    verifyEnumsRange(EXPECTED_FUEL_TYPES, fuelTypes);
+                    break;
+                case VehiclePropertyIds.INFO_MULTI_EV_PORT_LOCATIONS:
+                    int[] evPortLocations = mCarPropertyManager.getIntArrayProperty(
+                            cfg.getPropertyId(),VehicleAreaType.VEHICLE_AREA_TYPE_GLOBAL);
+                    verifyEnumsRange(EXPECTED_PORT_LOCATIONS, evPortLocations);
+                    break;
+                default:
+                    int[] areaIds = getAreaIdsHelper(cfg);
+                    for(int areaId : areaIds) {
+                        mCarPropertyManager.getIntArrayProperty(cfg.getPropertyId(), areaId);
+                    }
+            }
+        }
+    }
+
+    private void verifyEnumsRange(List<Integer> expectedResults, int[] results) {
+        assertThat(results).isNotNull();
+        // If the property is not implemented in cars, getIntArrayProperty returns an empty array.
+        if (results.length == 0) {
+            return;
+        }
+        for (int result : results) {
+            assertThat(result).isIn(expectedResults);
+        }
+    }
+
+    @Test
     public void testIsPropertyAvailable() {
         List<CarPropertyConfig> configs = mCarPropertyManager.getPropertyList(mPropertyIds);
 
@@ -251,15 +297,16 @@
         for (CarPropertyConfig cfg : configs) {
             if (cfg.getAccess() == CarPropertyConfig.VEHICLE_PROPERTY_ACCESS_READ_WRITE
                     && cfg.getPropertyType() == Boolean.class) {
-                // Get the current value, and set a different value to the property and verify it.
+                // In R, there is no property which is writable for third-party apps.
                 for (int areaId : getAreaIdsHelper(cfg)) {
-                    assertTrue(setBooleanPropertyHelper(cfg.getPropertyId(), areaId));
+                    assertThrows(SecurityException.class,
+                            () -> mCarPropertyManager.setBooleanProperty(
+                                    cfg.getPropertyId(), areaId,true));
                 }
             }
         }
     }
 
-
     @Test
     public void testRegisterCallback() throws Exception {
         //Test on registering a invalid property
@@ -282,7 +329,7 @@
                 CarPropertyManager.SENSOR_RATE_NORMAL);
         mCarPropertyManager.registerCallback(speedListenerUI, vehicleSpeed,
                 CarPropertyManager.SENSOR_RATE_FASTEST);
-
+        // TODO(b/149778976): Use CountDownLatch in listener instead of waitingTime
         Thread.sleep(WAIT_CALLBACK);
         assertNotEquals(0, speedListenerNormal.receivedEvent(vehicleSpeed));
         assertNotEquals(0, speedListenerUI.receivedEvent(vehicleSpeed));
@@ -311,7 +358,7 @@
         CarPropertyEventCounter speedListenerUI = new CarPropertyEventCounter();
 
         mCarPropertyManager.registerCallback(speedListenerNormal, vehicleSpeed,
-            CarPropertyManager.SENSOR_RATE_NORMAL);
+                CarPropertyManager.SENSOR_RATE_NORMAL);
 
         // test on unregistering a callback that was never registered
         try {
@@ -321,7 +368,7 @@
         }
 
         mCarPropertyManager.registerCallback(speedListenerUI, vehicleSpeed,
-            CarPropertyManager.SENSOR_RATE_UI);
+                CarPropertyManager.SENSOR_RATE_UI);
         Thread.sleep(WAIT_CALLBACK);
 
         mCarPropertyManager.unregisterCallback(speedListenerNormal, vehicleSpeed);
@@ -342,31 +389,40 @@
         assertEquals(currentEventUI, speedListenerUI.receivedEvent(vehicleSpeed));
     }
 
-    /**
-     * Returns true if set boolean value successfully.
-     * @param propId
-     * @param areaId
-     * @return
-     */
-    private boolean setBooleanPropertyHelper(int propId, int areaId) {
-        boolean currentValue = mCarPropertyManager.getBooleanProperty(propId, areaId);
-        boolean expectedValue = !currentValue;
-        try {
-            mCarPropertyManager.setBooleanProperty(propId, areaId, expectedValue);
-            Thread.sleep(WAIT_CALLBACK);
-            currentValue = mCarPropertyManager.getBooleanProperty(propId, areaId);
-            return expectedValue == currentValue;
-        } catch (Exception e) {
-            Log.e(TAG, new StringBuilder()
-                        .append("Failed to verify Property Id: 0x")
-                        .append(toHexString(propId))
-                        .append(", in areaId: 0x")
-                        .append(toHexString(areaId))
-                        .toString());
-        }
-        return false;
+    @Test
+    public void testUnregisterWithPropertyId() throws Exception {
+        // Ignores the test if wheel_tick property does not exist in the car.
+        Assume.assumeTrue("WheelTick is not available, skip unregisterCallback test",
+                mCarPropertyManager.isPropertyAvailable(
+                        VehiclePropertyIds.WHEEL_TICK, VehicleAreaType.VEHICLE_AREA_TYPE_GLOBAL));
+
+        CarPropertyEventCounter speedAndWheelTicksListener = new CarPropertyEventCounter();
+        mCarPropertyManager.registerCallback(speedAndWheelTicksListener,
+                VehiclePropertyIds.PERF_VEHICLE_SPEED, CarPropertyManager.SENSOR_RATE_FAST);
+        mCarPropertyManager.registerCallback(speedAndWheelTicksListener,
+                VehiclePropertyIds.WHEEL_TICK, CarPropertyManager.SENSOR_RATE_FAST);
+
+        // TODO(b/149778976): Use CountDownLatch in listener instead of waitingTime
+        Thread.sleep(WAIT_CALLBACK);
+        mCarPropertyManager.unregisterCallback(speedAndWheelTicksListener,
+                VehiclePropertyIds.PERF_VEHICLE_SPEED);
+        int currentSpeedEvents = speedAndWheelTicksListener.receivedEvent(
+                VehiclePropertyIds.PERF_VEHICLE_SPEED);
+        int currentWheelTickEvents = speedAndWheelTicksListener.receivedEvent(
+                VehiclePropertyIds.WHEEL_TICK);
+
+        Thread.sleep(WAIT_CALLBACK);
+        int speedEventsAfterUnregister = speedAndWheelTicksListener.receivedEvent(
+                VehiclePropertyIds.PERF_VEHICLE_SPEED);
+        int wheelTicksEventsAfterUnregister = speedAndWheelTicksListener.receivedEvent(
+                VehiclePropertyIds.WHEEL_TICK);
+
+        assertThat(currentSpeedEvents).isEqualTo(speedEventsAfterUnregister);
+        assertThat(wheelTicksEventsAfterUnregister).isGreaterThan(currentWheelTickEvents);
     }
 
+
+    // Returns {0} if the property is global property, otherwise query areaId for CarPropertyConfig
     private int[] getAreaIdsHelper(CarPropertyConfig config) {
         if (config.isGlobalProperty()) {
             int[] areaIds = {0};
diff --git a/tests/tests/car/src/android/car/cts/CarUserManagerTest.java b/tests/tests/car/src/android/car/cts/CarUserManagerTest.java
index 622fa28..bf76d3d 100644
--- a/tests/tests/car/src/android/car/cts/CarUserManagerTest.java
+++ b/tests/tests/car/src/android/car/cts/CarUserManagerTest.java
@@ -16,13 +16,16 @@
 package android.car.cts;
 
 import static android.os.Process.myUid;
+import static android.os.UserHandle.USER_SYSTEM;
 
 import static com.android.compatibility.common.util.ShellIdentityUtils.invokeMethodWithShellPermissions;
 import static com.android.compatibility.common.util.ShellIdentityUtils.invokeMethodWithShellPermissionsNoReturn;
 import static com.android.compatibility.common.util.ShellUtils.runShellCommand;
-
+import static com.android.compatibility.common.util.TestUtils.BooleanSupplierWithThrow;
 import static com.google.common.truth.Truth.assertWithMessage;
 
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
 import static org.junit.Assert.fail;
 
 import static org.testng.Assert.assertThrows;
@@ -32,7 +35,9 @@
 import android.car.Car;
 import android.car.user.CarUserManager;
 import android.car.user.CarUserManager.UserLifecycleListener;
+import android.content.pm.PackageInfo;
 import android.content.pm.PackageManager;
+import android.os.PowerManager;
 import android.os.SystemClock;
 import android.os.UserHandle;
 import android.util.Log;
@@ -45,6 +50,7 @@
 import org.junit.Test;
 
 import java.util.ArrayList;
+import java.util.Arrays;
 import java.util.List;
 import java.util.concurrent.CountDownLatch;
 import java.util.concurrent.Executor;
@@ -59,7 +65,7 @@
     /**
      * Constant used to wait for a condition that is triggered by checking a condition.
      */
-    private static final int SWITCH_TIMEOUT_USING_CHECK_MS = 30_000;
+    private static final int SWITCH_TIMEOUT_USING_CHECK_MS = 40_000;
 
     /**
      * Constant used to wait blindly, when there is no condition that can be checked.
@@ -67,12 +73,19 @@
     private static final int SWITCH_TIMEOUT_WITHOUT_CHECK_MS = 10_000;
 
     /**
+     * Constant used to wait blindly, when there is no condition that can be checked.
+     */
+    private static final int SUSPEND_TIMEOUT_MS = 5_000;
+
+    /**
      * How long to sleep (multiple times) while waiting for a condition.
      */
-    private static final int SMALL_NAP_MS = 500;
+    private static final int SMALL_NAP_MS = 100;
 
     private static CarUserManager sCarUserManager;
 
+    private PackageManager mPackageManager;
+
     private static int sInitialUserId = UserHandle.myUserId();
     private static int sNewUserId = UserHandle.USER_NULL;
 
@@ -91,9 +104,11 @@
         }
 
         sCarUserManager = (CarUserManager) getCar().getCarManager(Car.CAR_USER_SERVICE);
-        sNewUserId = createNewUser("CarUserManagerTest");
+        sNewUserId = createNewUser("CarUserManagerTest", /* isGuestUser= */ false);
         Log.i(TAG, "setUp(): myUid=" + myUid() + ", currentUser=" + sInitialUserId
                 + ", newUser=" + sNewUserId);
+
+        mPackageManager = sContext.getPackageManager();
     }
 
     @AfterClass
@@ -180,7 +195,6 @@
         };
         Log.d(TAG, "registering listener: " + listener);
 
-
         AtomicBoolean executedRef = new AtomicBoolean();
         sCarUserManager.addListener((r) -> {
             executedRef.set(true);
@@ -216,10 +230,49 @@
         }
     }
 
+
+    /**
+     * Tests resume behabior when current user is ephemeral guest, a new guest user should be
+     * created and switched to.
+     */
+    @Test
+    public void testGuestUserResumeToNewGuestUser() throws Exception {
+        // Create new guest user
+        int guestUserId = createNewUser("TestGuest", /* isGuestUser= */ true);
+
+        // Wait for this user to be active
+        switchUser(guestUserId);
+        waitForCurrentUser(guestUserId, SWITCH_TIMEOUT_USING_CHECK_MS);
+        waitUntil("Timeout: current user is not initialized: " + guestUserId,
+                SWITCH_TIMEOUT_USING_CHECK_MS, () -> isCurrentUserInitialized());
+
+        // Emulate suspend to RAM
+        suspendToRamAndResume();
+
+        // Wait for current user to be valid guest user, otherwise
+        assertWithMessage("not resumed to new guest user and current user is: %s", getCurrentUser())
+                .that(waitUntil("Timeout: current user is not valid guest user",
+                        SWITCH_TIMEOUT_USING_CHECK_MS,
+                        () -> (isCurrentUserValidGuestUser() && getCurrentUser() != guestUserId)))
+                .isTrue();
+    }
+
+    /**
+     * Tests resume behavior when current user is  persistent user
+     */
+    @Test
+    public void testPersistentUserResumeToUser() throws Exception {
+        switchUser(sNewUserId);
+        suspendToRamAndResume();
+
+        assertWithMessage("not resumed to previous user: %s", sNewUserId)
+                .that(getCurrentUser()).isEqualTo(sNewUserId);
+    }
+
     /**
      * Used to temporarily revoke the permission.
      */
-    private void toggleInteractAcrossUsersPermission(boolean enabled) {
+    private static void toggleInteractAcrossUsersPermission(boolean enabled) {
         String permission = "android.permission.INTERACT_ACROSS_USERS";
         String pkgName = sContext.getPackageName();
         UiAutomation automan = InstrumentationRegistry.getInstrumentation().getUiAutomation();
@@ -234,13 +287,44 @@
         }
     }
 
+    @Test
+    public void testPackageInstalledForSystemAndFullUser() throws Exception {
+        String[] packages = sContext.getResources()
+                .getStringArray(R.array.installed_system_and_full);
+        for (String pkg : packages) {
+            assertWithMessage(pkg + " should be installed for system user.")
+                    .that(isInstalled(pkg, USER_SYSTEM)).isTrue();
+            assertWithMessage(pkg + " should be installed for system user.")
+                    .that(isInstalled(pkg, sNewUserId)).isTrue();
+        }
+    }
+
+    @Test
+    public void testPackageInstalledForFullUserOnly() throws Exception {
+        String[] packages = sContext.getResources()
+                .getStringArray(R.array.installed_full_only);
+        for (String pkg : packages) {
+            assertWithMessage(pkg + " should not be installed for system user.")
+                    .that(isInstalled(pkg, USER_SYSTEM)).isFalse();
+            assertWithMessage(pkg + " should be installed for full user")
+                    .that(isInstalled(pkg, sNewUserId)).isTrue();
+        }
+    }
+
+    private boolean isInstalled(String packageName, int userId) {
+        List<PackageInfo> packages = new ArrayList<PackageInfo>();
+        packages = mPackageManager.getInstalledPackagesAsUser(/*PackageInfoFlags = */ 0, userId);
+        return packages.stream().filter(pkg -> pkg.packageName.equals(packageName))
+                .findAny().orElse(null) != null;
+    }
+
     /**
-     * Creates a new Android user.
+     * Creates a new Android user, returning its id.
      */
-    private int createNewUser(String name) {
+    private int createNewUser(String name, boolean isGuestUser) {
         Log.i(TAG, "Creating new user " + name);
         int newUserId = invokeMethodWithShellPermissions(sCarUserManager,
-                (um) -> um.createUser(name));
+                (um) -> um.createUser(name, isGuestUser));
         Log.i(TAG, "New user created with id " + newUserId);
         return newUserId;
     }
@@ -267,25 +351,66 @@
     }
 
     /**
-     * Waits until the current Android user is {@code userId}, or fail if it times out.
+     * Wait until the current Android user is {@code userId}, or fail if it times out.
      */
     private static void waitForCurrentUser(int userId, long timeoutMs) {
-        Log.i(TAG, "Waiting until current user is " + userId);
-        long deadline = System.currentTimeMillis() + timeoutMs;
-        do {
-            int actualUserId = getCurrentUser();
-            if (actualUserId == userId) {
-                Log.d(TAG, "the wait is over!");
-                return;
-            }
-            Log.d(TAG, "still on " + actualUserId + "; sleeping " + SMALL_NAP_MS + "ms");
-            SystemClock.sleep(SMALL_NAP_MS);
-        } while (System.currentTimeMillis() < deadline);
-        fail("didn't switch to user " + userId + " in " + timeoutMs + " ms");
+        waitUntil("didn't switch to user" + userId + " in " + timeoutMs + " ms", 
+                timeoutMs, () -> (getCurrentUser() == userId));
     }
 
     private static int getCurrentUser() {
         // TODO: should use Activity.getCurrentUser(), but that's a @SystemApi (not @TestApi)
         return Integer.parseInt(runShellCommand("am get-current-user"));
     }
+
+    private static void suspendToRamAndResume() throws Exception {
+        Log.d(TAG, "Emulate suspend to RAM and resume");
+        PowerManager powerManager = sContext.getSystemService(PowerManager.class);
+        runShellCommand("cmd car_service suspend");
+        // Check for suspend success
+        waitUntil("Suspsend is not successful",
+                SUSPEND_TIMEOUT_MS, () -> !powerManager.isScreenOn());
+        // Force turn off garage mode
+        runShellCommand("cmd car_service garage-mode off");
+        runShellCommand("cmd car_service resume");
+    }
+
+    private static boolean isCurrentUserValidGuestUser() {
+        Log.d(TAG, "checking isCurrentUserValidGuestUser");
+        for (String msg : runShellCommand("cmd user list -v").split("\\r?\\n")) {
+            if (msg.contains("(current)") && !msg.contains("DISABLED")) {
+                // If current user is valid,  check before exit
+                return msg.contains("GUEST");
+            }
+        }
+        return false;
+    }
+
+    private static boolean isCurrentUserInitialized() {
+        for (String msg : runShellCommand("cmd user list -v").split("\\r?\\n")) {
+            if (msg.contains("(current)")) {
+                return msg.contains("INITIALIZED");
+            }
+        }
+        return false;
+    }
+
+    private static boolean waitUntil(String msg, long timeoutMs,
+            BooleanSupplierWithThrow condition) {
+        long deadline = SystemClock.elapsedRealtime() + timeoutMs;
+        do {
+            try {
+                if (condition.getAsBoolean()) {
+                    return true;
+                }
+            } catch (Exception e) {
+                Log.e(TAG, "Exception in waitUntil: " + msg);
+                throw new RuntimeException(e);
+            }
+            SystemClock.sleep(SMALL_NAP_MS);
+        } while (SystemClock.elapsedRealtime() < deadline);
+
+        fail(msg + " after: " + timeoutMs + "ms");
+        return false;
+    }
 }
diff --git a/tests/tests/contactsproviderwipe/src/android/provider/cts/contactsproviderwipe/ContactsContract_Wipe.java b/tests/tests/contactsproviderwipe/src/android/provider/cts/contactsproviderwipe/ContactsContract_Wipe.java
index 8bc8134..d1bd895 100644
--- a/tests/tests/contactsproviderwipe/src/android/provider/cts/contactsproviderwipe/ContactsContract_Wipe.java
+++ b/tests/tests/contactsproviderwipe/src/android/provider/cts/contactsproviderwipe/ContactsContract_Wipe.java
@@ -185,6 +185,9 @@
             @Override
             public void onChange(boolean selfChange, Uri uri) {
                 Log.i(TAG, "Received notification on " + uri);
+                if (uri == null || !uri.equals(ProviderStatus.CONTENT_URI)) {
+                    return; // we only care about a change to ProviderStatus.CONTENT_URI
+                }
                 notifiedUri.set(uri);
                 latch.countDown();
             }
diff --git a/tests/tests/content/Android.bp b/tests/tests/content/Android.bp
index fa04cba..311974b 100644
--- a/tests/tests/content/Android.bp
+++ b/tests/tests/content/Android.bp
@@ -41,6 +41,7 @@
         // TODO: remove once Android migrates to JUnit 4.12, which provides assertThrows:
         "testng",
         "androidx.legacy_legacy-support-v4",
+        "androidx.test.core",
     ],
     // Use multi-dex as the compatibility-common-util-devicesidelib dependency
     // on compatibility-device-util-axt pushes us beyond 64k methods.
diff --git a/tests/tests/content/AndroidManifest.xml b/tests/tests/content/AndroidManifest.xml
index bf7674d..aee27b6 100644
--- a/tests/tests/content/AndroidManifest.xml
+++ b/tests/tests/content/AndroidManifest.xml
@@ -33,6 +33,7 @@
     <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
     <uses-permission android:name="android.content.cts.permission.TEST_GRANTED" />
     <uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
+    <uses-permission android:name="android.permission.QUERY_ALL_PACKAGES" />
 
     <!-- Used for ContextTest#testCreatePackageContextAsUser -->
     <uses-permission android:name="android.permission.INTERACT_ACROSS_USERS" />
diff --git a/tests/tests/content/data/v4-only-original.apk.idsig b/tests/tests/content/data/v4-only-original.apk.idsig
index 3ac4c80..c6ea405 100644
--- a/tests/tests/content/data/v4-only-original.apk.idsig
+++ b/tests/tests/content/data/v4-only-original.apk.idsig
Binary files differ
diff --git a/tests/tests/content/src/android/content/cts/ContentResolverTest.java b/tests/tests/content/src/android/content/cts/ContentResolverTest.java
index f635625..f56a6ca 100644
--- a/tests/tests/content/src/android/content/cts/ContentResolverTest.java
+++ b/tests/tests/content/src/android/content/cts/ContentResolverTest.java
@@ -16,6 +16,9 @@
 
 package android.content.cts;
 
+import static android.content.ContentResolver.NOTIFY_INSERT;
+import static android.content.ContentResolver.NOTIFY_UPDATE;
+
 import android.accounts.Account;
 import android.content.ContentProviderClient;
 import android.content.ContentResolver;
@@ -42,6 +45,7 @@
 import com.android.compatibility.common.util.PollingCheck;
 import com.android.internal.util.ArrayUtils;
 
+import java.io.File;
 import java.io.FileInputStream;
 import java.io.FileNotFoundException;
 import java.io.IOException;
@@ -50,11 +54,17 @@
 import java.io.OutputStream;
 import java.util.ArrayList;
 import java.util.Arrays;
+import java.util.Collection;
+import java.util.HashSet;
 import java.util.List;
+import java.util.Objects;
+import java.util.Set;
 import java.util.concurrent.CountDownLatch;
 import java.util.concurrent.TimeUnit;
 
 public class ContentResolverTest extends AndroidTestCase {
+    private static final String TAG = "ContentResolverTest";
+
     private final static String COLUMN_ID_NAME = "_id";
     private final static String COLUMN_KEY_NAME = "key";
     private final static String COLUMN_VALUE_NAME = "value";
@@ -1245,7 +1255,12 @@
         mContentResolver.unregisterContentObserver(mco);
     }
 
-    public void testNotifyChange_Multiple() {
+    /**
+     * Verify that callers using the {@link Iterable} version of
+     * {@link ContentResolver#notifyChange} are correctly split and delivered to
+     * disjoint listeners.
+     */
+    public void testNotifyChange_MultipleSplit() {
         final MockContentObserver observer1 = new MockContentObserver();
         final MockContentObserver observer2 = new MockContentObserver();
 
@@ -1271,6 +1286,46 @@
         mContentResolver.unregisterContentObserver(observer2);
     }
 
+    /**
+     * Verify that callers using the {@link Iterable} version of
+     * {@link ContentResolver#notifyChange} are correctly grouped and delivered
+     * to overlapping listeners, including untouched flags.
+     */
+    public void testNotifyChange_MultipleFlags() {
+        final MockContentObserver observer1 = new MockContentObserver();
+        final MockContentObserver observer2 = new MockContentObserver();
+
+        mContentResolver.registerContentObserver(LEVEL1_URI, false, observer1);
+        mContentResolver.registerContentObserver(LEVEL2_URI, false, observer2);
+
+        mContentResolver.notifyChange(
+                Arrays.asList(LEVEL1_URI), null, 0);
+        mContentResolver.notifyChange(
+                Arrays.asList(LEVEL1_URI, LEVEL2_URI), null, NOTIFY_INSERT);
+        mContentResolver.notifyChange(
+                Arrays.asList(LEVEL2_URI), null, NOTIFY_UPDATE);
+
+        final List<Change> expected1 = Arrays.asList(
+                new Change(false, Arrays.asList(LEVEL1_URI), 0),
+                new Change(false, Arrays.asList(LEVEL1_URI), NOTIFY_INSERT));
+
+        final List<Change> expected2 = Arrays.asList(
+                new Change(false, Arrays.asList(LEVEL1_URI), 0),
+                new Change(false, Arrays.asList(LEVEL1_URI, LEVEL2_URI), NOTIFY_INSERT),
+                new Change(false, Arrays.asList(LEVEL2_URI), NOTIFY_UPDATE));
+
+        new PollingCheck() {
+            @Override
+            protected boolean check() {
+                return observer1.hadChanges(expected1)
+                        && observer2.hadChanges(expected2);
+            }
+        }.run();
+
+        mContentResolver.unregisterContentObserver(observer1);
+        mContentResolver.unregisterContentObserver(observer2);
+    }
+
     public void testStartCancelSync() {
         Bundle extras = new Bundle();
 
@@ -1411,8 +1466,55 @@
         assertNull(response);
     }
 
-    private class MockContentObserver extends ContentObserver {
+    public void testEncodeDecode() {
+        final Uri expected = Uri.parse("content://com.example/item/23");
+        final File file = ContentResolver.encodeToFile(expected);
+        assertNotNull(file);
+
+        final Uri actual = ContentResolver.decodeFromFile(file);
+        assertNotNull(actual);
+        assertEquals(expected, actual);
+    }
+
+    public static class Change {
+        public final boolean selfChange;
+        public final Iterable<Uri> uris;
+        public final int flags;
+
+        public Change(boolean selfChange, Iterable<Uri> uris, int flags) {
+            this.selfChange = selfChange;
+            this.uris = uris;
+            this.flags = flags;
+        }
+
+        @Override
+        public String toString() {
+            return String.format("onChange(%b, %s, %d)",
+                    selfChange, asSet(uris).toString(), flags);
+        }
+
+        @Override
+        public boolean equals(Object other) {
+            if (other instanceof Change) {
+                final Change change = (Change) other;
+                return change.selfChange == selfChange &&
+                        Objects.equals(asSet(change.uris), asSet(uris)) &&
+                        change.flags == flags;
+            } else {
+                return false;
+            }
+        }
+
+        private static Set<Uri> asSet(Iterable<Uri> uris) {
+            final Set<Uri> asSet = new HashSet<>();
+            uris.forEach(asSet::add);
+            return asSet;
+        }
+    }
+
+    private static class MockContentObserver extends ContentObserver {
         private boolean mHadOnChanged = false;
+        private List<Change> mChanges = new ArrayList<>();
 
         public MockContentObserver() {
             super(null);
@@ -1424,9 +1526,12 @@
         }
 
         @Override
-        public synchronized void onChange(boolean selfChange) {
-            super.onChange(selfChange);
+        public synchronized void onChange(boolean selfChange, Collection<Uri> uris, int flags) {
+            final Change change = new Change(selfChange, uris, flags);
+            Log.v(TAG, change.toString());
+
             mHadOnChanged = true;
+            mChanges.add(change);
         }
 
         public synchronized boolean hadOnChanged() {
@@ -1436,5 +1541,9 @@
         public synchronized void reset() {
             mHadOnChanged = false;
         }
+
+        public synchronized boolean hadChanges(Collection<Change> changes) {
+            return mChanges.containsAll(changes);
+        }
     }
 }
diff --git a/tests/tests/content/src/android/content/cts/ContextAccessTest.java b/tests/tests/content/src/android/content/cts/ContextAccessTest.java
new file mode 100644
index 0000000..9abd8d9
--- /dev/null
+++ b/tests/tests/content/src/android/content/cts/ContextAccessTest.java
@@ -0,0 +1,138 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.content.cts;
+
+import static android.view.Display.DEFAULT_DISPLAY;
+import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+
+import android.app.Activity;
+import android.app.Service;
+import android.content.Context;
+import android.content.ContextWrapper;
+import android.content.Intent;
+import android.hardware.display.DisplayManager;
+import android.os.Bundle;
+import android.os.IBinder;
+import android.platform.test.annotations.Presubmit;
+import android.view.Display;
+
+import androidx.test.core.app.ApplicationProvider;
+import androidx.test.filters.SmallTest;
+import androidx.test.rule.ActivityTestRule;
+import androidx.test.rule.ServiceTestRule;
+
+import org.junit.Rule;
+import org.junit.Test;
+
+import java.util.concurrent.TimeoutException;
+
+/**
+ * Test for {@link Context#getDisplay()}.
+ * <p>Test context type listed below:</p>
+ * <ul>
+ *     <li>{@link android.app.Application} - throw exception</li>
+ *     <li>{@link Service} - throw exception</li>
+ *     <li>{@link Activity} - get {@link Display} entity</li>
+ *     <li>Context via {@link Context#createWindowContext(int, Bundle)}
+ *     - get {@link Display} entity</li>
+ *     <li>Context via {@link Context#createDisplayContext(Display)}
+ *     - get {@link Display} entity</li>
+ *     <li>{@link ContextWrapper} with base display-associated {@link Context}
+ *     - get {@link Display} entity</li>
+ *     <li>{@link ContextWrapper} with base non-display-associated {@link Context}
+ *     - get {@link Display} entity</li>
+ * </ul>
+ *
+ * <p>Build/Install/Run:
+ *     atest CtsContentTestCases:ContextAccessTest
+ */
+@Presubmit
+@SmallTest
+public class ContextAccessTest {
+    private Context mContext = ApplicationProvider.getApplicationContext();
+
+    @Rule
+    public final ActivityTestRule<MockActivity> mActivityRule =
+            new ActivityTestRule<>(MockActivity.class);
+
+    @Test(expected = UnsupportedOperationException.class)
+    public void testGetDisplayFromApplication() {
+        mContext.getDisplay();
+    }
+
+    @Test(expected = UnsupportedOperationException.class)
+    public void testGetDisplayFromService() throws TimeoutException {
+        getTestService().getDisplay();
+    }
+
+    @Test
+    public void testGetDisplayFromActivity() throws Throwable {
+        final Display d = getTestActivity().getDisplay();
+
+        assertNotNull("Display must be accessible from visual components", d);
+    }
+
+    @Test
+    public void testGetDisplayFromDisplayContext() {
+        final Display display = mContext.getSystemService(DisplayManager.class)
+                .getDisplay(DEFAULT_DISPLAY);
+        Context displayContext = mContext.createDisplayContext(display);
+
+        assertEquals(display, displayContext.getDisplay());
+    }
+
+    @Test
+    public void testGetDisplayFromWindowContext() {
+        final Display display = mContext.getSystemService(DisplayManager.class)
+                .getDisplay(DEFAULT_DISPLAY);
+        Context windowContext =  mContext.createDisplayContext(display)
+                .createWindowContext(TYPE_APPLICATION_OVERLAY, null /*  options */);
+        assertEquals(display, windowContext.getDisplay());
+    }
+
+    @Test
+    public void testGetDisplayFromVisualWrapper() throws Throwable {
+        final Display d = new ContextWrapper(getTestActivity()).getDisplay();
+
+        assertNotNull("Display must be accessible from visual components", d);
+    }
+
+    @Test(expected = UnsupportedOperationException.class)
+    public void testGetDisplayFromNonVisualWrapper() {
+        ContextWrapper wrapper = new ContextWrapper(mContext);
+        wrapper.getDisplay();
+    }
+
+    private Activity getTestActivity() throws Throwable {
+        MockActivity[] activity = new MockActivity[1];
+        mActivityRule.runOnUiThread(() -> {
+            activity[0] = mActivityRule.getActivity();
+        });
+        return activity[0];
+    }
+
+    private Service getTestService() throws TimeoutException {
+        final Intent intent = new Intent(mContext.getApplicationContext(), MockService.class);
+        final ServiceTestRule serviceRule = new ServiceTestRule();
+        IBinder serviceToken;
+        serviceToken = serviceRule.bindService(intent);
+        return ((MockService.MockBinder) serviceToken).getService();
+    }
+}
diff --git a/tests/tests/content/src/android/content/cts/ContextTest.java b/tests/tests/content/src/android/content/cts/ContextTest.java
index 5a41584..f6f7cf5 100644
--- a/tests/tests/content/src/android/content/cts/ContextTest.java
+++ b/tests/tests/content/src/android/content/cts/ContextTest.java
@@ -1414,6 +1414,64 @@
         }.run();
     }
 
+    /** The receiver should get the broadcast if it has all the permissions. */
+    public void testSendBroadcastWithMultiplePermissions_receiverHasAllPermissions()
+            throws Exception {
+        final ResultReceiver receiver = new ResultReceiver();
+
+        registerBroadcastReceiver(receiver, new IntentFilter(ResultReceiver.MOCK_ACTION));
+
+        mContext.sendBroadcastWithMultiplePermissions(
+                new Intent(ResultReceiver.MOCK_ACTION),
+                new String[] { // this test APK has both these permissions
+                        android.Manifest.permission.ACCESS_WIFI_STATE,
+                        android.Manifest.permission.ACCESS_NETWORK_STATE,
+                });
+
+        new PollingCheck(BROADCAST_TIMEOUT) {
+            @Override
+            protected boolean check() {
+                return receiver.hasReceivedBroadCast();
+            }
+        }.run();
+    }
+
+    /** The receiver should not get the broadcast if it does not have all the permissions. */
+    public void testSendBroadcastWithMultiplePermissions_receiverHasSomePermissions()
+            throws Exception {
+        final ResultReceiver receiver = new ResultReceiver();
+
+        registerBroadcastReceiver(receiver, new IntentFilter(ResultReceiver.MOCK_ACTION));
+
+        mContext.sendBroadcastWithMultiplePermissions(
+                new Intent(ResultReceiver.MOCK_ACTION),
+                new String[] { // this test APK only has ACCESS_WIFI_STATE
+                        android.Manifest.permission.ACCESS_WIFI_STATE,
+                        android.Manifest.permission.NETWORK_STACK,
+                });
+
+        Thread.sleep(BROADCAST_TIMEOUT);
+        assertFalse(receiver.hasReceivedBroadCast());
+    }
+
+    /** The receiver should not get the broadcast if it has none of the permissions. */
+    public void testSendBroadcastWithMultiplePermissions_receiverHasNoPermissions()
+            throws Exception {
+        final ResultReceiver receiver = new ResultReceiver();
+
+        registerBroadcastReceiver(receiver, new IntentFilter(ResultReceiver.MOCK_ACTION));
+
+        mContext.sendBroadcastWithMultiplePermissions(
+                new Intent(ResultReceiver.MOCK_ACTION),
+                new String[] { // this test APK has neither of these permissions
+                        android.Manifest.permission.NETWORK_SETTINGS,
+                        android.Manifest.permission.NETWORK_STACK,
+                });
+
+        Thread.sleep(BROADCAST_TIMEOUT);
+        assertFalse(receiver.hasReceivedBroadCast());
+    }
+
     public void testEnforceCallingOrSelfUriPermission() {
         try {
             Uri uri = Uri.parse("content://ctstest");
diff --git a/tests/tests/content/src/android/content/cts/IntentFilterTest.java b/tests/tests/content/src/android/content/cts/IntentFilterTest.java
index 37d50bc..36e5788 100644
--- a/tests/tests/content/src/android/content/cts/IntentFilterTest.java
+++ b/tests/tests/content/src/android/content/cts/IntentFilterTest.java
@@ -16,7 +16,9 @@
 
 package android.content.cts;
 
+import static android.content.IntentFilter.MATCH_CATEGORY_HOST;
 import static android.content.IntentFilter.MATCH_CATEGORY_SCHEME_SPECIFIC_PART;
+import static android.content.IntentFilter.MATCH_CATEGORY_TYPE;
 import static android.os.PatternMatcher.PATTERN_LITERAL;
 import static android.os.PatternMatcher.PATTERN_PREFIX;
 import static android.os.PatternMatcher.PATTERN_SIMPLE_GLOB;
@@ -483,6 +485,24 @@
                 MatchCondition.data(IntentFilter.NO_MATCH_DATA, "scheme:a1b"));
     }
 
+    public void testSchemeSpecificPartsWithWildCards() throws Exception {
+        IntentFilter filter = new Match(null, null, null, new String[]{"scheme"},
+                null, null, null, null, new String[]{"ssp1"},
+                new int[]{PATTERN_LITERAL, PATTERN_LITERAL});
+        checkMatches(filter,
+                MatchCondition.data(IntentFilter.NO_MATCH_DATA, null, true),
+                MatchCondition.data(MATCH_CATEGORY_SCHEME_SPECIFIC_PART, "scheme:ssp1", true),
+                MatchCondition.data(MATCH_CATEGORY_SCHEME_SPECIFIC_PART, "*:ssp1", true),
+                MatchCondition.data(MATCH_CATEGORY_SCHEME_SPECIFIC_PART, "scheme:*", true),
+                MatchCondition.data(MATCH_CATEGORY_SCHEME_SPECIFIC_PART, "*:*", true),
+                MatchCondition.data(IntentFilter.NO_MATCH_DATA, "scheme:ssp12", true));
+
+        checkMatches(filter,
+                MatchCondition.data(IntentFilter.NO_MATCH_DATA, "*:ssp1", false),
+                MatchCondition.data(IntentFilter.NO_MATCH_DATA, "scheme:*", false),
+                MatchCondition.data(IntentFilter.NO_MATCH_DATA, "*:*", false));
+    }
+
     public void testAuthorities() {
         for (int i = 0; i < 10; i++) {
             mIntentFilter.addDataAuthority(HOST + i, String.valueOf(PORT + i));
@@ -535,6 +555,49 @@
                 MatchCondition.data(IntentFilter.NO_MATCH_DATA, "scheme1://authority1:200/"));
     }
 
+    public void testAuthoritiesWithWildcards() throws Exception {
+        IntentFilter filter = new Match(null, null, null, new String[]{"scheme1"},
+                new String[]{"authority1"}, new String[]{null});
+        checkMatches(filter,
+                MatchCondition.data(IntentFilter.NO_MATCH_DATA, null, true),
+                MatchCondition.data(IntentFilter.NO_MATCH_DATA, "scheme1:*", true),
+                MatchCondition.data(IntentFilter.MATCH_CATEGORY_HOST, "scheme1://*/", true),
+                MatchCondition.data(IntentFilter.MATCH_CATEGORY_HOST, "scheme1://*:100/", true),
+                MatchCondition.data(IntentFilter.NO_MATCH_DATA, "scheme1://*/", false),
+                MatchCondition.data(IntentFilter.NO_MATCH_DATA, "scheme1://*:100/", false));
+
+        filter = new Match(null, null, null, new String[]{"scheme1"},
+                new String[]{"authority1"}, new String[]{"100"});
+        checkMatches(filter,
+                MatchCondition.data(IntentFilter.NO_MATCH_DATA, null, true),
+                MatchCondition.data(IntentFilter.NO_MATCH_DATA, "scheme1:*", true),
+                MatchCondition.data(IntentFilter.NO_MATCH_DATA, "scheme1://*/", true),
+                MatchCondition.data(IntentFilter.MATCH_CATEGORY_PORT, "scheme1://*:100/", true),
+                MatchCondition.data(IntentFilter.NO_MATCH_DATA, "scheme1://*:200/", true),
+                MatchCondition.data(IntentFilter.NO_MATCH_DATA, "*:foo", true),
+                MatchCondition.data(IntentFilter.NO_MATCH_DATA, "*://authority1/", true),
+                MatchCondition.data(IntentFilter.MATCH_CATEGORY_PORT, "*://authority1:100/", true),
+                MatchCondition.data(IntentFilter.NO_MATCH_DATA, "*://authority1:200/", true),
+                MatchCondition.data(IntentFilter.NO_MATCH_DATA, "*:*", true),
+                MatchCondition.data(IntentFilter.NO_MATCH_DATA, "*://*/", true),
+                MatchCondition.data(IntentFilter.MATCH_CATEGORY_PORT, "*://*:100/", true),
+                MatchCondition.data(IntentFilter.NO_MATCH_DATA, "*://*:200/", true));
+
+        checkMatches(filter,
+                MatchCondition.data(IntentFilter.NO_MATCH_DATA, "scheme1://*/", false),
+                MatchCondition.data(IntentFilter.NO_MATCH_DATA, "scheme1://*:100/", false),
+                MatchCondition.data(IntentFilter.NO_MATCH_DATA, "*://authority1:100/", false),
+                MatchCondition.data(IntentFilter.NO_MATCH_DATA, "*://*/", false),
+                MatchCondition.data(IntentFilter.NO_MATCH_DATA, "*://*:100/", false));
+
+        filter = new Match(null, null, null, new String[]{"scheme1"},
+                new String[]{"*"}, null);
+        checkMatches(filter,
+                MatchCondition.data(IntentFilter.MATCH_CATEGORY_HOST, "scheme1://", true),
+                MatchCondition.data(IntentFilter.MATCH_CATEGORY_HOST, "scheme1://", false),
+                MatchCondition.data(IntentFilter.MATCH_CATEGORY_HOST, "scheme1://*", true));
+    }
+
     public void testDataTypes() throws MalformedMimeTypeException {
         for (int i = 0; i < 10; i++) {
             mIntentFilter.addDataType(DATA_STATIC_TYPE + i);
@@ -682,6 +745,129 @@
                 new MatchCondition(IntentFilter.NO_MATCH_ACTION, "action3", null, null, null));
     }
 
+    public void testActionWildCards() throws Exception {
+        IntentFilter filter = new Match(new String[]{"action1"}, null, null, null, null, null);
+        checkMatches(filter,
+                new MatchCondition(IntentFilter.MATCH_CATEGORY_EMPTY, null, null, null, null, true),
+                new MatchCondition(IntentFilter.MATCH_CATEGORY_EMPTY, "*", null, null, null, true),
+                new MatchCondition(
+                        IntentFilter.NO_MATCH_ACTION, "action3", null, null, null, true));
+
+        checkMatches(filter,
+                new MatchCondition(IntentFilter.NO_MATCH_ACTION, "*", null, null, null, false));
+
+    }
+
+    public void testAppEnumerationContactProviders() throws Exception {
+        // sample contact source
+        IntentFilter filter = new Match(new String[]{Intent.ACTION_VIEW},
+                new String[]{Intent.CATEGORY_DEFAULT},
+                new String[]{"vnd.android.cursor.item/vnd.com.someapp.profile"},
+                new String[]{"content"},
+                new String[]{"com.android.contacts"},
+                null /*ports*/);
+
+        // app that would like to match all contact sources
+        checkMatches(filter,
+                new MatchCondition(MATCH_CATEGORY_TYPE,
+                        Intent.ACTION_VIEW,
+                        null /*categories*/,
+                        "vnd.android.cursor.item/*",
+                        "content://com.android.contacts",
+                        true));
+    }
+
+    public void testAppEnumerationDocumentEditor() throws Exception {
+        // sample document editor
+        IntentFilter filter = new Match(
+                new String[]{
+                        Intent.ACTION_VIEW,
+                        Intent.ACTION_EDIT,
+                        "com.app.android.intent.action.APP_EDIT",
+                        "com.app.android.intent.action.APP_VIEW"},
+                new String[]{Intent.CATEGORY_DEFAULT},
+                new String[]{
+                        "application/msword",
+                        "application/vnd.oasis.opendocument.text",
+                        "application/rtf",
+                        "text/rtf",
+                        "text/plain",
+                        "application/pdf",
+                        "application/x-pdf",
+                        "application/docm"},
+                null /*schemes*/,
+                null /*authorities*/,
+                null /*ports*/);
+
+        // app that would like to match all doc editors
+        checkMatches(filter,
+                new MatchCondition(MATCH_CATEGORY_TYPE,
+                        Intent.ACTION_VIEW,
+                        new String[]{Intent.CATEGORY_DEFAULT},
+                        "*/*",
+                        "content://com.example.fileprovider",
+                        true));
+
+    }
+
+    public void testAppEnumerationDeepLinks() throws Exception {
+        // Sample app that supports deep-links
+        IntentFilter filter = new Match(
+                new String[]{Intent.ACTION_VIEW},
+                new String[]{
+                        Intent.CATEGORY_DEFAULT,
+                        Intent.CATEGORY_BROWSABLE},
+                null /*types*/,
+                new String[]{"http", "https"},
+                new String[]{"arbitrary-site.com"},
+                null /*ports*/);
+
+        // Browser that would like to see all deep-linkable http/s app, but not all apps
+        checkMatches(filter,
+                new MatchCondition(MATCH_CATEGORY_HOST,
+                        Intent.ACTION_VIEW,
+                        new String[]{Intent.CATEGORY_BROWSABLE},
+                        null,
+                        "https://*",
+                        true));
+        checkMatches(filter,
+                new MatchCondition(MATCH_CATEGORY_HOST,
+                        Intent.ACTION_VIEW,
+                        new String[]{Intent.CATEGORY_BROWSABLE},
+                        null,
+                        "http://*",
+                        true));
+    }
+
+    public void testAppEnumerationCustomShareSheet() throws Exception {
+        // Sample share target
+        IntentFilter filter = new Match(
+                new String[]{Intent.ACTION_SEND},
+                new String[]{Intent.CATEGORY_DEFAULT},
+                new String[]{"*/*"},
+                null /*schemes*/,
+                null /*authorities*/,
+                null /*ports*/);
+
+        // App with custom share sheet that would like to see all jpeg targets
+        checkMatches(filter,
+                new MatchCondition(MATCH_CATEGORY_TYPE,
+                        Intent.ACTION_SEND,
+                        null /*categories*/,
+                        "image/jpeg",
+                        "content://com.example.fileprovider",
+                        true));
+        // App with custom share sheet that would like to see all jpeg targets that don't specify
+        // a host
+        checkMatches(filter,
+                new MatchCondition(MATCH_CATEGORY_TYPE,
+                        Intent.ACTION_SEND,
+                        null /*categories*/,
+                        "image/jpeg",
+                        "content:",
+                        true));
+    }
+
     public void testWriteToXml() throws IllegalArgumentException, IllegalStateException,
             IOException, MalformedMimeTypeException, XmlPullParserException {
         XmlSerializer xml;
@@ -1102,18 +1288,27 @@
         public final String mimeType;
         public final Uri data;
         public final String[] categories;
+        public final boolean wildcardSupported;
 
         public static MatchCondition data(int result, String data) {
             return new MatchCondition(result, null, null, null, data);
         }
+        public static MatchCondition data(int result, String data, boolean wildcardSupported) {
+            return new MatchCondition(result, null, null, null, data, wildcardSupported);
+        }
 
         MatchCondition(int result, String action, String[] categories, String mimeType,
                 String data) {
+            this(result, action, categories, mimeType, data, false);
+        }
+        MatchCondition(int result, String action, String[] categories, String mimeType,
+                String data, boolean wildcardSupported) {
             this.result = result;
             this.action = action;
             this.mimeType = mimeType;
             this.data = data != null ? Uri.parse(data) : null;
             this.categories = categories;
+            this.wildcardSupported = wildcardSupported;
         }
     }
 
@@ -1130,7 +1325,7 @@
                 }
             }
             int result = filter.match(mc.action, mc.mimeType, mc.data != null ? mc.data.getScheme()
-                    : null, mc.data, categories, "test");
+                    : null, mc.data, categories, "test", mc.wildcardSupported);
             if ((result & IntentFilter.MATCH_CATEGORY_MASK) !=
                     (mc.result & IntentFilter.MATCH_CATEGORY_MASK)) {
                 StringBuilder msg = new StringBuilder();
@@ -1353,4 +1548,4 @@
             isPrintlnCalled = true;
         }
     }
-}
+}
\ No newline at end of file
diff --git a/tests/tests/content/src/android/content/pm/cts/PackageManagerShellCommandIncrementalTest.java b/tests/tests/content/src/android/content/pm/cts/PackageManagerShellCommandIncrementalTest.java
index fa55d18..a59f37d 100644
--- a/tests/tests/content/src/android/content/pm/cts/PackageManagerShellCommandIncrementalTest.java
+++ b/tests/tests/content/src/android/content/pm/cts/PackageManagerShellCommandIncrementalTest.java
@@ -31,6 +31,7 @@
 import org.junit.After;
 import org.junit.Assume;
 import org.junit.Before;
+import org.junit.Ignore;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 
@@ -120,6 +121,7 @@
         assertEquals(null, getSplits(TEST_APP_PACKAGE));
     }
 
+    @Ignore("TODO(b/150809360): Re-enable after SELinux rules are in.")
     @Test
     public void testInstallWithIdSig() throws Exception {
         final Context context = InstrumentationRegistry.getInstrumentation().getContext();
diff --git a/tests/tests/content/src/android/content/pm/cts/PackageManagerShellCommandTest.java b/tests/tests/content/src/android/content/pm/cts/PackageManagerShellCommandTest.java
index cae08f8..f26ca5a 100644
--- a/tests/tests/content/src/android/content/pm/cts/PackageManagerShellCommandTest.java
+++ b/tests/tests/content/src/android/content/pm/cts/PackageManagerShellCommandTest.java
@@ -51,7 +51,7 @@
 import java.util.stream.Collectors;
 
 @RunWith(Parameterized.class)
-@AppModeFull // TODO(Instant) Figure out which APIs should work.
+@AppModeFull
 public class PackageManagerShellCommandTest {
     private static final String TEST_APP_PACKAGE = "com.example.helloworld";
 
@@ -74,7 +74,9 @@
 
     @Parameters
     public static Iterable<Object> initParameters() {
-        return Arrays.asList(DATA_LOADER_TYPE_NONE, DATA_LOADER_TYPE_STREAMING);
+        return Arrays.asList(DATA_LOADER_TYPE_NONE, DATA_LOADER_TYPE_STREAMING/*,
+                             TODO(b/150809360): Re-enable after SELinux rules are in.
+                             DATA_LOADER_TYPE_INCREMENTAL*/);
     }
 
     private boolean mStreaming = false;
@@ -376,6 +378,18 @@
         assertEquals("base, config.mdpi, config.xxhdpi", getSplits(TEST_APP_PACKAGE));
     }
 
+    @Test
+    public void testAppInstallErrDuplicate() throws Exception {
+        if (!mStreaming) {
+            return;
+        }
+        String split = createApkPath(TEST_HW5);
+        String commandResult = executeShellCommand(
+                "pm " + mInstall + " -t -g " + split + " " + split);
+        assertEquals("Failure [failed to add file(s)]\n", commandResult);
+        assertFalse(isAppInstalled(TEST_APP_PACKAGE));
+    }
+
     private String createUpdateSession(String packageName) throws IOException {
         return createSession("-p " + packageName);
     }
diff --git a/tests/tests/database/src/android/database/cts/ContentObserverTest.java b/tests/tests/database/src/android/database/cts/ContentObserverTest.java
index 05fb60c..c924d9a 100644
--- a/tests/tests/database/src/android/database/cts/ContentObserverTest.java
+++ b/tests/tests/database/src/android/database/cts/ContentObserverTest.java
@@ -16,7 +16,6 @@
 
 package android.database.cts;
 
-
 import android.database.ContentObserver;
 import android.net.Uri;
 import android.os.Handler;
@@ -24,6 +23,9 @@
 import android.os.Looper;
 import android.test.InstrumentationTestCase;
 
+import java.util.Arrays;
+import java.util.Collection;
+
 public class ContentObserverTest extends InstrumentationTestCase {
     private static final Uri CONTENT_URI = Uri.parse("content://uri");
 
@@ -120,9 +122,37 @@
         assertFalse(contentObserver.deliverSelfNotifications());
     }
 
+    /**
+     * Verify that all incoming dispatch methods invoke all outgoing callbacks.
+     */
+    public void testDispatchChange_Completeness() {
+        final MyContentObserver observer = new MyContentObserver(null);
+
+        observer.resetStatus();
+        observer.dispatchChange(false, Arrays.asList(CONTENT_URI), 0);
+        assertEquals(4, observer.getChangeCount());
+
+        observer.resetStatus();
+        observer.dispatchChange(false, Arrays.asList(CONTENT_URI, CONTENT_URI), 0);
+        assertEquals(7, observer.getChangeCount());
+
+        observer.resetStatus();
+        observer.dispatchChange(false, CONTENT_URI, 0);
+        assertEquals(4, observer.getChangeCount());
+
+        observer.resetStatus();
+        observer.dispatchChange(false, CONTENT_URI);
+        assertEquals(4, observer.getChangeCount());
+
+        observer.resetStatus();
+        observer.dispatchChange(false);
+        assertEquals(4, observer.getChangeCount());
+    }
+
     private static class MyContentObserver extends ContentObserver {
         private boolean mHasChanged;
         private boolean mSelfChange;
+        private int mChangeCount = 0;
 
         public MyContentObserver(Handler handler) {
             super(handler);
@@ -134,10 +164,35 @@
             synchronized(this) {
                 mHasChanged = true;
                 mSelfChange = selfChange;
+                mChangeCount++;
                 notifyAll();
             }
         }
 
+        @Override
+        public void onChange(boolean selfChange, Uri uri) {
+            super.onChange(selfChange, uri);
+            synchronized (this) {
+                mChangeCount++;
+            }
+        }
+
+        @Override
+        public void onChange(boolean selfChange, Uri uri, int flags) {
+            super.onChange(selfChange, uri, flags);
+            synchronized (this) {
+                mChangeCount++;
+            }
+        }
+
+        @Override
+        public void onChange(boolean selfChange, Collection<Uri> uris, int flags) {
+            super.onChange(selfChange, uris, flags);
+            synchronized (this) {
+                mChangeCount++;
+            }
+        }
+
         protected synchronized boolean hasChanged(long timeout) throws InterruptedException {
             if (!mHasChanged) {
                 wait(timeout);
@@ -152,6 +207,7 @@
         protected void resetStatus() {
             mHasChanged = false;
             mSelfChange = false;
+            mChangeCount = 0;
         }
 
         protected boolean getSelfChangeState() {
@@ -161,6 +217,10 @@
         protected void setSelfChangeState(boolean state) {
             mSelfChange = state;
         }
+
+        protected int getChangeCount() {
+            return mChangeCount;
+        }
     }
 
     private static class MyContentObserverWithUri extends ContentObserver {
diff --git a/tests/tests/graphics/jni/android_graphics_cts_FrameRateCtsActivity.cpp b/tests/tests/graphics/jni/android_graphics_cts_FrameRateCtsActivity.cpp
index 2b4bef6..e33f7f6 100644
--- a/tests/tests/graphics/jni/android_graphics_cts_FrameRateCtsActivity.cpp
+++ b/tests/tests/graphics/jni/android_graphics_cts_FrameRateCtsActivity.cpp
@@ -219,8 +219,12 @@
     Surface* surface = reinterpret_cast<Surface*>(surfaceControlLong);
     ASurfaceControl* surfaceControl = surface->getSurfaceControl();
     // Android's Color.* values are represented as ARGB. Convert to RGBA.
-    int rgbaColor = ((argbColor >> 16) & 0xff) | ((argbColor >> 8) & 0xff) |
-            ((argbColor >> 0) & 0xff) | ((argbColor >> 24) & 0xff);
+    int32_t rgbaColor = 0;
+    int8_t* rgbaColorBytes = reinterpret_cast<int8_t*>(&rgbaColor);
+    rgbaColorBytes[0] = (argbColor >> 16) & 0xff;
+    rgbaColorBytes[1] = (argbColor >> 8) & 0xff;
+    rgbaColorBytes[2] = (argbColor >> 0) & 0xff;
+    rgbaColorBytes[3] = (argbColor >> 24) & 0xff;
 
     Buffer buffer(surface->getWidth(), surface->getHeight(), rgbaColor);
     if (!buffer.isValid()) {
diff --git a/tests/tests/graphics/src/android/graphics/cts/FrameRateCtsActivity.java b/tests/tests/graphics/src/android/graphics/cts/FrameRateCtsActivity.java
index 2cef070..5cf438b 100644
--- a/tests/tests/graphics/src/android/graphics/cts/FrameRateCtsActivity.java
+++ b/tests/tests/graphics/src/android/graphics/cts/FrameRateCtsActivity.java
@@ -251,6 +251,12 @@
                 mSurface = null;
             }
             if (mSurfaceControl != null) {
+                SurfaceControl.Transaction transaction = new SurfaceControl.Transaction();
+                try {
+                    transaction.reparent(mSurfaceControl, null).apply();
+                } finally {
+                    transaction.close();
+                }
                 mSurfaceControl.release();
                 mSurfaceControl = null;
             }
diff --git a/tests/tests/gwp-asan/OWNERS b/tests/tests/gwp-asan/OWNERS
new file mode 100644
index 0000000..9686261
--- /dev/null
+++ b/tests/tests/gwp-asan/OWNERS
@@ -0,0 +1,5 @@
+# Bug component: 14890
+eugenis@google.com
+pcc@google.com
+mitchp@google.com
+
diff --git a/tests/tests/gwp-asan/TEST_MAPPING b/tests/tests/gwp-asan/TEST_MAPPING
new file mode 100644
index 0000000..1976d66
--- /dev/null
+++ b/tests/tests/gwp-asan/TEST_MAPPING
@@ -0,0 +1,7 @@
+{
+  "presubmit": [
+    {
+      "name": "CtsGwpAsanTestCases"
+    }
+  ]
+}
diff --git a/tests/tests/jni_vendor/Android.bp b/tests/tests/gwp-asan/enabled/Android.bp
similarity index 66%
rename from tests/tests/jni_vendor/Android.bp
rename to tests/tests/gwp-asan/enabled/Android.bp
index 544257b..533330a 100644
--- a/tests/tests/jni_vendor/Android.bp
+++ b/tests/tests/gwp-asan/enabled/Android.bp
@@ -1,4 +1,4 @@
-// Copyright (C) 2017 The Android Open Source Project
+// Copyright (C) 2020 The Android Open Source Project
 //
 // Licensed under the Apache License, Version 2.0 (the "License");
 // you may not use this file except in compliance with the License.
@@ -13,20 +13,27 @@
 // limitations under the License.
 
 android_test {
-    name: "CtsVendorJniTestCases",
+    name: "CtsGwpAsanTestCases",
     defaults: ["cts_defaults"],
-
     compile_multilib: "both",
-    static_libs: [
-        "androidx.test.rules",
-        "ctstestrunner-axt",
+    // When built, explicitly put it in the data partition.
+    // Tag this module as a cts test artifact
+    test_suites: [
+        "cts",
+        "vts",
+        "general-tests",
     ],
-    jni_libs: ["libvendorjnitest"],
+    libs: [
+        "android.test.runner.stubs",
+        "android.test.base.stubs",
+    ],
+    static_libs: [
+        "ctstestrunner-axt",
+        "androidx.test.rules",
+        "androidx.test.core",
+        "androidx.test.ext.junit",
+    ],
     srcs: ["src/**/*.java"],
     sdk_version: "current",
-    // TODO(jiyong) make this really a part of CTS
-    // This can't be done right now since VNDK runtime restriction is optional
-    // at least for O-MR1.
-    // Tag this module as a cts test artifact
-    // test_suites: ["cts", "vts", "general-tests"],
+    use_embedded_native_libs: false,
 }
diff --git a/tests/tests/gwp-asan/enabled/AndroidManifest.xml b/tests/tests/gwp-asan/enabled/AndroidManifest.xml
new file mode 100644
index 0000000..afd8c9a
--- /dev/null
+++ b/tests/tests/gwp-asan/enabled/AndroidManifest.xml
@@ -0,0 +1,53 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2020 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+       package="android.gwpasan.cts"
+       android:targetSandboxVersion="2">
+
+  <application android:extractNativeLibs="true"
+               android:enableGwpAsan="true">
+    <processes>
+      <process />
+      <process android:process=":gwp_asan_enabled"
+               android:enableGwpAsan="true" />
+      <process android:process=":gwp_asan_disabled"
+               android:enableGwpAsan="false" />
+      <process android:process=":gwp_asan_default" />
+    </processes>
+    <uses-library android:name="android.test.runner" />
+    <activity android:name="android.gwpasan.GwpAsanTestActivity" />
+    <activity android:name="android.gwpasan.GwpAsanEnabledActivity"
+              android:process=":gwp_asan_enabled" />
+    <activity android:name="android.gwpasan.GwpAsanDisabledActivity"
+              android:process=":gwp_asan_disabled" />
+    <activity android:name="android.gwpasan.GwpAsanDefaultActivity"
+              android:process=":gwp_asan_default" />
+    <service android:name="android.gwpasan.GwpAsanEnabledService"
+             android:process=":gwp_asan_enabled" />
+    <service android:name="android.gwpasan.GwpAsanDisabledService"
+             android:process=":gwp_asan_disabled" />
+    <service android:name="android.gwpasan.GwpAsanDefaultService"
+             android:process=":gwp_asan_default" />
+  </application>
+
+  <instrumentation android:name="androidx.test.runner.AndroidJUnitRunner"
+                   android:targetPackage="android.gwpasan.cts"
+                   android:label="CTS tests of GWP-ASan">
+    <meta-data android:name="listener"
+               android:value="com.android.cts.runner.CtsTestRunListener" />
+  </instrumentation>
+</manifest>
diff --git a/tests/tests/jni_vendor/AndroidTest.xml b/tests/tests/gwp-asan/enabled/AndroidTest.xml
similarity index 66%
rename from tests/tests/jni_vendor/AndroidTest.xml
rename to tests/tests/gwp-asan/enabled/AndroidTest.xml
index b606559..61580ca 100644
--- a/tests/tests/jni_vendor/AndroidTest.xml
+++ b/tests/tests/gwp-asan/enabled/AndroidTest.xml
@@ -1,5 +1,5 @@
 <?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2017 The Android Open Source Project
+<!-- Copyright (C) 2020 The Android Open Source Project
 
      Licensed under the Apache License, Version 2.0 (the "License");
      you may not use this file except in compliance with the License.
@@ -13,15 +13,17 @@
      See the License for the specific language governing permissions and
      limitations under the License.
 -->
-<configuration description="Config for CTS Vendor's JNI test cases">
+<configuration description="Config for CTS GWP-ASan test cases">
     <option name="test-suite-tag" value="cts" />
     <option name="config-descriptor:metadata" key="component" value="art" />
+    <option name="config-descriptor:metadata" key="parameter" value="instant_app" />
+    <option name="config-descriptor:metadata" key="parameter" value="multi_abi" />
+    <option name="config-descriptor:metadata" key="parameter" value="secondary_user" />
     <target_preparer class="com.android.tradefed.targetprep.suite.SuiteApkInstaller">
         <option name="cleanup-apks" value="true" />
-        <option name="test-file-name" value="CtsVendorJniTestCases.apk" />
+        <option name="test-file-name" value="CtsGwpAsanTestCases.apk" />
     </target_preparer>
     <test class="com.android.tradefed.testtype.AndroidJUnitTest" >
-        <option name="package" value="android.jni.vendor.cts" />
-        <option name="runtime-hint" value="1m" />
+        <option name="package" value="android.gwpasan.cts" />
     </test>
 </configuration>
diff --git a/tests/tests/gwp-asan/enabled/src/android/gwpasan/GwpAsanDefaultActivity.java b/tests/tests/gwp-asan/enabled/src/android/gwpasan/GwpAsanDefaultActivity.java
new file mode 100644
index 0000000..9643fa2
--- /dev/null
+++ b/tests/tests/gwp-asan/enabled/src/android/gwpasan/GwpAsanDefaultActivity.java
@@ -0,0 +1,41 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.gwpasan;
+
+import android.app.Activity;
+import android.os.Bundle;
+import android.util.Log;
+
+import java.lang.Override;
+
+import android.gwpasan.Utils;
+
+public class GwpAsanDefaultActivity extends Activity {
+
+    @Override
+    public void onCreate(Bundle icicle) {
+        super.onCreate(icicle);
+        try {
+          boolean enabled = Utils.isGwpAsanEnabled();
+          setResult(RESULT_FIRST_USER + (enabled ? 1 : 0));
+        } catch (Exception e) {
+          setResult(RESULT_OK);
+        }
+        finish();
+    }
+
+}
diff --git a/tests/tests/gwp-asan/enabled/src/android/gwpasan/GwpAsanDefaultService.java b/tests/tests/gwp-asan/enabled/src/android/gwpasan/GwpAsanDefaultService.java
new file mode 100644
index 0000000..d7e9ccf
--- /dev/null
+++ b/tests/tests/gwp-asan/enabled/src/android/gwpasan/GwpAsanDefaultService.java
@@ -0,0 +1,52 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.gwpasan;
+
+import android.app.Service;
+import android.content.Intent;
+import android.os.Binder;
+import android.os.IBinder;
+import android.os.Parcel;
+import java.lang.Override;
+
+import android.gwpasan.Utils;
+
+public class GwpAsanDefaultService extends Service {
+
+    private final IBinder mBinder = new LocalBinder();
+
+    @Override
+    public IBinder onBind(Intent intent) {
+        return mBinder;
+    }
+
+    public class LocalBinder extends Binder {
+
+        @Override
+        public boolean onTransact(int code, Parcel data, Parcel reply, int flags) {
+            if (code == 42) {
+              try {
+                reply.writeInt(Utils.isGwpAsanEnabled() ? 1 : 0);
+              } catch (Exception e) {
+                reply.writeInt(-1);
+              }
+              return true;
+            }
+            return false;
+        }
+    }
+}
diff --git a/tests/tests/gwp-asan/enabled/src/android/gwpasan/GwpAsanDisabledActivity.java b/tests/tests/gwp-asan/enabled/src/android/gwpasan/GwpAsanDisabledActivity.java
new file mode 100644
index 0000000..4245820
--- /dev/null
+++ b/tests/tests/gwp-asan/enabled/src/android/gwpasan/GwpAsanDisabledActivity.java
@@ -0,0 +1,42 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.gwpasan;
+
+import android.app.Activity;
+import android.os.Bundle;
+import android.util.Log;
+
+
+import java.lang.Override;
+
+import android.gwpasan.Utils;
+
+public class GwpAsanDisabledActivity extends Activity {
+
+    @Override
+    public void onCreate(Bundle icicle) {
+        super.onCreate(icicle);
+        try {
+          boolean enabled = Utils.isGwpAsanEnabled();
+          setResult(RESULT_FIRST_USER + (enabled ? 1 : 0));
+        } catch (Exception e) {
+          setResult(RESULT_OK);
+        }
+        finish();
+    }
+
+}
diff --git a/tests/tests/gwp-asan/enabled/src/android/gwpasan/GwpAsanDisabledService.java b/tests/tests/gwp-asan/enabled/src/android/gwpasan/GwpAsanDisabledService.java
new file mode 100644
index 0000000..acc3c47
--- /dev/null
+++ b/tests/tests/gwp-asan/enabled/src/android/gwpasan/GwpAsanDisabledService.java
@@ -0,0 +1,52 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.gwpasan;
+
+import android.app.Service;
+import android.content.Intent;
+import android.os.Binder;
+import android.os.IBinder;
+import android.os.Parcel;
+import java.lang.Override;
+
+import android.gwpasan.Utils;
+
+public class GwpAsanDisabledService extends Service {
+
+    private final IBinder mBinder = new LocalBinder();
+
+    @Override
+    public IBinder onBind(Intent intent) {
+        return mBinder;
+    }
+
+    public class LocalBinder extends Binder {
+
+        @Override
+        public boolean onTransact(int code, Parcel data, Parcel reply, int flags) {
+            if (code == 42) {
+              try {
+                reply.writeInt(Utils.isGwpAsanEnabled() ? 1 : 0);
+              } catch (Exception e) {
+                reply.writeInt(-1);
+              }
+              return true;
+            }
+            return false;
+        }
+    }
+}
diff --git a/tests/tests/gwp-asan/enabled/src/android/gwpasan/GwpAsanEnabledActivity.java b/tests/tests/gwp-asan/enabled/src/android/gwpasan/GwpAsanEnabledActivity.java
new file mode 100644
index 0000000..93d49ad
--- /dev/null
+++ b/tests/tests/gwp-asan/enabled/src/android/gwpasan/GwpAsanEnabledActivity.java
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.gwpasan;
+
+import android.app.Activity;
+import android.os.Bundle;
+import android.util.Log;
+
+
+import java.lang.Override;
+
+import android.gwpasan.Utils;
+
+public class GwpAsanEnabledActivity extends Activity {
+    @Override
+    public void onCreate(Bundle icicle) {
+        super.onCreate(icicle);
+        try {
+          boolean enabled = Utils.isGwpAsanEnabled();
+          setResult(RESULT_FIRST_USER + (enabled ? 1 : 0));
+        } catch (Exception e) {
+          setResult(RESULT_OK);
+        }
+        finish();
+    }
+}
diff --git a/tests/tests/gwp-asan/enabled/src/android/gwpasan/GwpAsanEnabledService.java b/tests/tests/gwp-asan/enabled/src/android/gwpasan/GwpAsanEnabledService.java
new file mode 100644
index 0000000..489081f
--- /dev/null
+++ b/tests/tests/gwp-asan/enabled/src/android/gwpasan/GwpAsanEnabledService.java
@@ -0,0 +1,52 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.gwpasan;
+
+import android.app.Service;
+import android.content.Intent;
+import android.os.Binder;
+import android.os.IBinder;
+import android.os.Parcel;
+import java.lang.Override;
+
+import android.gwpasan.Utils;
+
+public class GwpAsanEnabledService extends Service {
+
+    private final IBinder mBinder = new LocalBinder();
+
+    @Override
+    public IBinder onBind(Intent intent) {
+        return mBinder;
+    }
+
+    public class LocalBinder extends Binder {
+
+        @Override
+        public boolean onTransact(int code, Parcel data, Parcel reply, int flags) {
+            if (code == 42) {
+              try {
+                reply.writeInt(Utils.isGwpAsanEnabled() ? 1 : 0);
+              } catch (Exception e) {
+                reply.writeInt(-1);
+              }
+              return true;
+            }
+            return false;
+        }
+    }
+}
diff --git a/tests/tests/gwp-asan/enabled/src/android/gwpasan/GwpAsanTestActivity.java b/tests/tests/gwp-asan/enabled/src/android/gwpasan/GwpAsanTestActivity.java
new file mode 100644
index 0000000..6cc1d43
--- /dev/null
+++ b/tests/tests/gwp-asan/enabled/src/android/gwpasan/GwpAsanTestActivity.java
@@ -0,0 +1,88 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.gwpasan;
+
+import android.app.Activity;
+import android.content.Intent;
+import android.content.Context;
+import android.os.Bundle;
+import android.util.Log;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.assertFalse;
+
+import java.lang.Override;
+
+import android.gwpasan.Utils;
+
+public class GwpAsanTestActivity extends Activity {
+    static final String TAG = "GwpAsanTestActivity";
+
+    private int mResult;
+    private final Object mFinishEvent = new Object();
+
+    @Override
+    public void onCreate(Bundle icicle) {
+        super.onCreate(icicle);
+    }
+
+    @Override
+    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
+        mResult = resultCode;
+        synchronized (mFinishEvent) {
+            mFinishEvent.notify();
+        }
+    }
+
+    protected boolean callActivity(Class<?> cls) throws Exception {
+        Thread thread = new Thread() {
+            @Override
+            public void run() {
+                try {
+                    Context context = getApplicationContext();
+                    Intent intent = new Intent(context, cls);
+                    startActivityForResult(intent, 0);
+
+                    synchronized (mFinishEvent) {
+                        mFinishEvent.wait();
+                    }
+                } catch(Exception e) {
+                    Log.d(TAG, "callActivity got an exception " + e.toString());
+                }
+            }
+        };
+        thread.start();
+        thread.join(20000 /* millis */);
+
+        if (mResult == RESULT_OK) {
+          throw new Exception();
+        }
+        return (mResult - RESULT_FIRST_USER) == 1;
+    }
+
+    public void testGwpAsanEnabledActivity() throws Exception {
+        assertTrue(callActivity(GwpAsanEnabledActivity.class));
+    }
+
+    public void testGwpAsanDisabledActivity() throws Exception {
+        assertFalse(callActivity(GwpAsanDisabledActivity.class));
+    }
+
+    public void testGwpAsanDefaultActivity() throws Exception {
+        // GwpAsanDefaultActivity inherits the application attribute.
+        assertTrue(callActivity(GwpAsanDefaultActivity.class));
+    }
+}
diff --git a/tests/tests/gwp-asan/enabled/src/android/gwpasan/Utils.java b/tests/tests/gwp-asan/enabled/src/android/gwpasan/Utils.java
new file mode 100644
index 0000000..395eea4
--- /dev/null
+++ b/tests/tests/gwp-asan/enabled/src/android/gwpasan/Utils.java
@@ -0,0 +1,19 @@
+package android.gwpasan;
+
+import java.io.BufferedReader;
+import java.io.FileReader;
+import java.io.IOException;
+
+public class Utils {
+
+    public static boolean isGwpAsanEnabled() throws IOException {
+      BufferedReader reader = new BufferedReader(new FileReader("proc/self/maps"));
+      String line;
+      while ((line = reader.readLine()) != null) {
+        if (line.contains("GWP-ASan Guard Page")) {
+          return true;
+        }
+      }
+      return false;
+    }
+}
diff --git a/tests/tests/gwp-asan/enabled/src/android/gwpasan/cts/GwpAsanActivityTest.java b/tests/tests/gwp-asan/enabled/src/android/gwpasan/cts/GwpAsanActivityTest.java
new file mode 100644
index 0000000..3d6d834
--- /dev/null
+++ b/tests/tests/gwp-asan/enabled/src/android/gwpasan/cts/GwpAsanActivityTest.java
@@ -0,0 +1,54 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.gwpasan.cts;
+
+import android.test.ActivityInstrumentationTestCase2;
+import static org.junit.Assert.assertTrue;
+import android.util.Log;
+import android.gwpasan.GwpAsanTestActivity;
+import android.gwpasan.Utils;
+
+public class GwpAsanActivityTest extends ActivityInstrumentationTestCase2<GwpAsanTestActivity> {
+
+    private GwpAsanTestActivity mActivity;
+
+    public GwpAsanActivityTest() {
+      super(GwpAsanTestActivity.class);
+    }
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+        mActivity = getActivity();
+    }
+
+    public void testGwpAsanEnabledApplication() throws Exception {
+        assertTrue(Utils.isGwpAsanEnabled());
+    }
+
+    public void testGwpAsanEnabledActivity() throws Exception {
+        mActivity.testGwpAsanEnabledActivity();
+    }
+
+    public void testGwpAsanDisabledActivity() throws Exception {
+        mActivity.testGwpAsanDisabledActivity();
+    }
+
+    public void testGwpAsanDefaultActivity() throws Exception {
+        mActivity.testGwpAsanDefaultActivity();
+    }
+}
diff --git a/tests/tests/gwp-asan/enabled/src/android/gwpasan/cts/GwpAsanServiceTest.java b/tests/tests/gwp-asan/enabled/src/android/gwpasan/cts/GwpAsanServiceTest.java
new file mode 100644
index 0000000..a7beaa4
--- /dev/null
+++ b/tests/tests/gwp-asan/enabled/src/android/gwpasan/cts/GwpAsanServiceTest.java
@@ -0,0 +1,74 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.gwpasan.cts;
+
+import android.content.Intent;
+import android.os.IBinder;
+import android.os.Parcel;
+import androidx.test.ext.junit.runners.AndroidJUnit4;
+import androidx.test.rule.ServiceTestRule;
+
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import java.util.concurrent.TimeoutException;
+
+import static androidx.test.core.app.ApplicationProvider.getApplicationContext;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.assertFalse;
+
+import android.gwpasan.GwpAsanEnabledService;
+import android.gwpasan.GwpAsanDisabledService;
+import android.gwpasan.GwpAsanDefaultService;
+
+@RunWith(AndroidJUnit4.class)
+public class GwpAsanServiceTest {
+    @Rule
+    public final ServiceTestRule mServiceRule = new ServiceTestRule();
+
+    private boolean isGwpAsanEnabledInService(Class<?> cls) throws Exception {
+        Intent serviceIntent = new Intent(getApplicationContext(), cls);
+        IBinder binder = mServiceRule.bindService(serviceIntent);
+        final Parcel request = Parcel.obtain();
+        final Parcel reply = Parcel.obtain();
+        if (!binder.transact(42, request, reply, 0)) {
+          throw new Exception();
+        }
+        int res = reply.readInt();
+        if (res < 0) {
+          throw new Exception();
+        }
+        return res != 0;
+    }
+
+    @Test
+    public void testEnabledService() throws Exception {
+        assertTrue(isGwpAsanEnabledInService(GwpAsanEnabledService.class));
+    }
+
+    @Test
+    public void testDisabledService() throws Exception {
+        assertFalse(isGwpAsanEnabledInService(GwpAsanDisabledService.class));
+    }
+
+    @Test
+    public void testDefaultService() throws Exception {
+        // GwpAsanDefaultService inherits the application attribute.
+        assertTrue(isGwpAsanEnabledInService(GwpAsanDefaultService.class));
+    }
+}
diff --git a/tests/tests/hardware/src/android/hardware/lights/cts/LightsManagerTest.java b/tests/tests/hardware/src/android/hardware/lights/cts/LightsManagerTest.java
index a30ca46..78455b1 100755
--- a/tests/tests/hardware/src/android/hardware/lights/cts/LightsManagerTest.java
+++ b/tests/tests/hardware/src/android/hardware/lights/cts/LightsManagerTest.java
@@ -44,8 +44,8 @@
 @SmallTest
 public class LightsManagerTest {
 
-    private static final @ColorInt int TAN = 0xffd2b48c;
-    private static final @ColorInt int RED = 0xffff0000;
+    private static final LightState ON_TAN = new LightState(0xffd2b48c);
+    private static final LightState ON_RED = new LightState(0xffff0000);
 
     private LightsManager mManager;
     private List<Light> mLights;
@@ -89,12 +89,12 @@
 
         try (LightsManager.LightsSession session = mManager.openSession()) {
             // When the session requests to turn a single light on:
-            session.setLights(new Builder()
-                    .setLight(mLights.get(0), new LightState(RED))
+            session.requestLights(new Builder()
+                    .setLight(mLights.get(0), ON_RED)
                     .build());
 
             // Then the light should turn on.
-            assertThat(mManager.getLightState(mLights.get(0)).getColor()).isEqualTo(RED);
+            assertThat(mManager.getLightState(mLights.get(0)).getColor()).isEqualTo(ON_RED);
         }
     }
 
@@ -104,7 +104,7 @@
 
         try (LightsManager.LightsSession session = mManager.openSession()) {
             // When the session requests to turn two of the lights on:
-            session.setLights(new Builder()
+            session.requestLights(new Builder()
                     .setLight(mLights.get(0), new LightState(0xffaaaaff))
                     .setLight(mLights.get(1), new LightState(0xffbbbbff))
                     .build());
@@ -129,9 +129,9 @@
 
         try (LightsManager.LightsSession session = mManager.openSession()) {
             // When a session commits changes:
-            session.setLights(new Builder().setLight(mLights.get(0), new LightState(TAN)).build());
+            session.requestLights(new Builder().setLight(mLights.get(0), ON_TAN).build());
             // Then the light should turn on.
-            assertThat(mManager.getLightState(mLights.get(0)).getColor()).isEqualTo(TAN);
+            assertThat(mManager.getLightState(mLights.get(0)).getColor()).isEqualTo(ON_TAN);
 
             // When the session goes away:
             session.close();
@@ -148,15 +148,15 @@
                 LightsManager.LightsSession session2 = mManager.openSession()) {
 
             // When session1 and session2 both request the same light:
-            session1.setLights(new Builder().setLight(mLights.get(0), new LightState(TAN)).build());
-            session2.setLights(new Builder().setLight(mLights.get(0), new LightState(RED)).build());
+            session1.requestLights(new Builder().setLight(mLights.get(0), ON_TAN).build());
+            session2.requestLights(new Builder().setLight(mLights.get(0), ON_RED).build());
             // Then session1 should win because it was created first.
-            assertThat(mManager.getLightState(mLights.get(0)).getColor()).isEqualTo(TAN);
+            assertThat(mManager.getLightState(mLights.get(0)).getColor()).isEqualTo(ON_TAN);
 
             // When session1 goes away:
             session1.close();
             // Then session2 should have its request go into effect.
-            assertThat(mManager.getLightState(mLights.get(0)).getColor()).isEqualTo(RED);
+            assertThat(mManager.getLightState(mLights.get(0)).getColor()).isEqualTo(ON_RED);
 
             // When session2 goes away:
             session2.close();
@@ -171,9 +171,9 @@
 
         try (LightsManager.LightsSession session = mManager.openSession()) {
             // When the session turns a light on:
-            session.setLights(new Builder().setLight(mLights.get(0), new LightState(RED)).build());
+            session.requestLights(new Builder().setLight(mLights.get(0), ON_RED).build());
             // And then the session clears it again:
-            session.setLights(new Builder().clearLight(mLights.get(0)).build());
+            session.requestLights(new Builder().clearLight(mLights.get(0)).build());
             // Then the light should turn back off.
             assertThat(mManager.getLightState(mLights.get(0)).getColor()).isEqualTo(0);
         }
diff --git a/tests/tests/identity/src/android/security/identity/cts/AttestationTest.java b/tests/tests/identity/src/android/security/identity/cts/AttestationTest.java
index 34b0cf2..d745da0 100644
--- a/tests/tests/identity/src/android/security/identity/cts/AttestationTest.java
+++ b/tests/tests/identity/src/android/security/identity/cts/AttestationTest.java
@@ -26,7 +26,6 @@
 import androidx.test.InstrumentationRegistry;
 
 import org.junit.Test;
-import org.junit.Ignore;
 
 import com.google.common.primitives.Bytes;
 
@@ -49,7 +48,6 @@
     public static final int KM_TAG_ATTESTATION_APPLICATION_ID = 709;
     public static final int KM_TAG_IDENTITY_CREDENTIAL_KEY = 721;
 
-    @Ignore("Not ready until SW implementation produces correct attestations")
     @Test
     public void attestationTest() throws Exception {
         Context appContext = InstrumentationRegistry.getTargetContext();
diff --git a/tests/tests/identity/src/android/security/identity/cts/ProvisioningTest.java b/tests/tests/identity/src/android/security/identity/cts/ProvisioningTest.java
index 48cc405..6a264ef 100644
--- a/tests/tests/identity/src/android/security/identity/cts/ProvisioningTest.java
+++ b/tests/tests/identity/src/android/security/identity/cts/ProvisioningTest.java
@@ -135,22 +135,22 @@
         PersonalizationData personalizationData =
                 new PersonalizationData.Builder()
                         .addAccessControlProfile(noAuthProfile)
-                        .setEntry(mdlNs, "First name", idsNoAuth, Util.cborEncodeString("Alan"))
-                        .setEntry(mdlNs, "Last name", idsNoAuth, Util.cborEncodeString("Turing"))
-                        .setEntry(mdlNs, "Home address", idsNoAuth,
+                        .putEntry(mdlNs, "First name", idsNoAuth, Util.cborEncodeString("Alan"))
+                        .putEntry(mdlNs, "Last name", idsNoAuth, Util.cborEncodeString("Turing"))
+                        .putEntry(mdlNs, "Home address", idsNoAuth,
                                 Util.cborEncodeString("Maida Vale, London, England"))
-                        .setEntry(mdlNs, "Birth date", idsNoAuth, Util.cborEncodeString("19120623"))
-                        .setEntry(mdlNs, "Cryptanalyst", idsNoAuth, Util.cborEncodeBoolean(true))
-                        .setEntry(mdlNs, "Portrait image", idsNoAuth, Util.cborEncodeBytestring(
+                        .putEntry(mdlNs, "Birth date", idsNoAuth, Util.cborEncodeString("19120623"))
+                        .putEntry(mdlNs, "Cryptanalyst", idsNoAuth, Util.cborEncodeBoolean(true))
+                        .putEntry(mdlNs, "Portrait image", idsNoAuth, Util.cborEncodeBytestring(
                             new byte[]{0x01, 0x02}))
-                        .setEntry(mdlNs, "Height", idsNoAuth, Util.cborEncodeInt(180))
-                        .setEntry(mdlNs, "Neg Item", idsNoAuth, Util.cborEncodeInt(-42))
-                        .setEntry(mdlNs, "Int Two Bytes", idsNoAuth, Util.cborEncodeInt(0x101))
-                        .setEntry(mdlNs, "Int Four Bytes", idsNoAuth, Util.cborEncodeInt(0x10001))
-                        .setEntry(mdlNs, "Int Eight Bytes", idsNoAuth,
+                        .putEntry(mdlNs, "Height", idsNoAuth, Util.cborEncodeInt(180))
+                        .putEntry(mdlNs, "Neg Item", idsNoAuth, Util.cborEncodeInt(-42))
+                        .putEntry(mdlNs, "Int Two Bytes", idsNoAuth, Util.cborEncodeInt(0x101))
+                        .putEntry(mdlNs, "Int Four Bytes", idsNoAuth, Util.cborEncodeInt(0x10001))
+                        .putEntry(mdlNs, "Int Eight Bytes", idsNoAuth,
                                 Util.cborEncodeInt(0x100000001L))
-                        .setEntry(mdlNs, "driving_privileges", idsNoAuth, drivingPrivileges)
-                        .setEntry(mdlNs, "No Access", idsNoAcp,
+                        .putEntry(mdlNs, "driving_privileges", idsNoAuth, drivingPrivileges)
+                        .putEntry(mdlNs, "No Access", idsNoAcp,
                                 Util.cborEncodeString("Cannot be retrieved"))
                         .build();
 
@@ -291,13 +291,13 @@
         PersonalizationData personalizationData =
                 new PersonalizationData.Builder()
                         .addAccessControlProfile(noAuthProfile)
-                        .setEntry("org.example.barfoo", "Bar", idsNoAuth,
+                        .putEntry("org.example.barfoo", "Bar", idsNoAuth,
                                 Util.cborEncodeString("Foo"))
-                        .setEntry("org.example.barfoo", "Foo", idsNoAuth,
+                        .putEntry("org.example.barfoo", "Foo", idsNoAuth,
                                 Util.cborEncodeString("Bar"))
-                        .setEntry("org.example.foobar", "Foo", idsNoAuth,
+                        .putEntry("org.example.foobar", "Foo", idsNoAuth,
                                 Util.cborEncodeString("Bar"))
-                        .setEntry("org.example.foobar", "Bar", idsNoAuth,
+                        .putEntry("org.example.foobar", "Bar", idsNoAuth,
                                 Util.cborEncodeString("Foo"))
                         .build();
 
@@ -480,7 +480,7 @@
                 null,
                 null);
 
-        Collection<String> resultNamespaces = rd.getNamespaceNames();
+        Collection<String> resultNamespaces = rd.getNamespaces();
         assertEquals(resultNamespaces.size(), 1);
         assertEquals("org.iso.18013-5.2019", resultNamespaces.iterator().next());
         assertEquals(12, rd.getEntryNames("org.iso.18013-5.2019").size());
@@ -628,7 +628,7 @@
                 null,
                 null);
 
-        Collection<String> resultNamespaces = rd.getNamespaceNames();
+        Collection<String> resultNamespaces = rd.getNamespaces();
         assertEquals(resultNamespaces.size(), 1);
         assertEquals("org.iso.18013-5.2019", resultNamespaces.iterator().next());
         assertEquals(6, rd.getEntryNames("org.iso.18013-5.2019").size());
@@ -667,7 +667,7 @@
                 null,
                 null);
 
-        Collection<String> resultNamespaces = rd.getNamespaceNames();
+        Collection<String> resultNamespaces = rd.getNamespaces();
         assertEquals(resultNamespaces.size(), 1);
         assertEquals("org.iso.18013-5.2019", resultNamespaces.iterator().next());
         assertEquals(1, rd.getEntryNames("org.iso.18013-5.2019").size());
@@ -724,7 +724,7 @@
                 null,
                 null);
 
-        Collection<String> resultNamespaces = rd.getNamespaceNames();
+        Collection<String> resultNamespaces = rd.getNamespaces();
         assertEquals(resultNamespaces.size(), 1);
         assertEquals("org.iso.18013-5.2019", resultNamespaces.iterator().next());
         assertEquals(7, rd.getEntryNames("org.iso.18013-5.2019").size());
@@ -769,7 +769,7 @@
                 null,
                 null);
 
-        Collection<String> resultNamespaces = rd.getNamespaceNames();
+        Collection<String> resultNamespaces = rd.getNamespaces();
         assertEquals(resultNamespaces.size(), 1);
         assertEquals("org.iso.18013-5.2019", resultNamespaces.iterator().next());
         assertEquals(3, rd.getEntryNames("org.iso.18013-5.2019").size());
@@ -821,7 +821,7 @@
         // that do not exist in the credential.
         //
         // Additionally, each namespace should have exactly the items requested, in the same order.
-        Collection<String> resultNamespaces = rd.getNamespaceNames();
+        Collection<String> resultNamespaces = rd.getNamespaces();
         assertEquals(resultNamespaces.size(), 3);
 
 
diff --git a/tests/tests/identity/src/android/security/identity/cts/ReaderAuthTest.java b/tests/tests/identity/src/android/security/identity/cts/ReaderAuthTest.java
index 1abc0ae..86c920a 100644
--- a/tests/tests/identity/src/android/security/identity/cts/ReaderAuthTest.java
+++ b/tests/tests/identity/src/android/security/identity/cts/ReaderAuthTest.java
@@ -202,13 +202,13 @@
                         .addAccessControlProfile(readerAProfile)
                         .addAccessControlProfile(readerBProfile)
                         .addAccessControlProfile(readerCProfile)
-                        .setEntry(mdlNs, "Accessible to A", idsReaderAuthA,
+                        .putEntry(mdlNs, "Accessible to A", idsReaderAuthA,
                                 Util.cborEncodeString("foo"))
-                        .setEntry(mdlNs, "Accessible to B", idsReaderAuthB,
+                        .putEntry(mdlNs, "Accessible to B", idsReaderAuthB,
                                 Util.cborEncodeString("bar"))
-                        .setEntry(mdlNs, "Accessible to A or B", idsReaderAuthAorB,
+                        .putEntry(mdlNs, "Accessible to A or B", idsReaderAuthAorB,
                                 Util.cborEncodeString("baz"))
-                        .setEntry(mdlNs, "Accessible to C", idsReaderAuthC,
+                        .putEntry(mdlNs, "Accessible to C", idsReaderAuthC,
                                 Util.cborEncodeString("bat"))
                         .build();
         byte[] proofOfProvisioningSignature = wc.personalize(personalizationData);
@@ -291,7 +291,7 @@
         //
         rd = retrieveForReader(credential, eKeyPair, readerKeyPairA, certChainForA, requestMessage,
                 entriesToRequest);
-        resultNamespaces = rd.getNamespaceNames();
+        resultNamespaces = rd.getNamespaces();
         assertEquals(1, resultNamespaces.size());
         assertEquals("org.iso.18013-5.2019", resultNamespaces.iterator().next());
         entryNames = rd.getRetrievedEntryNames("org.iso.18013-5.2019");
@@ -324,7 +324,7 @@
         eKeyPair = credential.createEphemeralKeyPair();
         rd = retrieveForReader(credential, eKeyPair, readerKeyPairA, certChainForA,
                 requestMessage2, entriesToRequest);
-        resultNamespaces = rd.getNamespaceNames();
+        resultNamespaces = rd.getNamespaces();
         assertEquals(1, resultNamespaces.size());
         assertEquals("org.iso.18013-5.2019", resultNamespaces.iterator().next());
         entryNames = rd.getRetrievedEntryNames("org.iso.18013-5.2019");
@@ -345,7 +345,7 @@
         eKeyPair = credential.createEphemeralKeyPair();
         rd = retrieveForReader(credential, eKeyPair, readerKeyPairA, certChainForAwithC,
                 requestMessage, entriesToRequest);
-        resultNamespaces = rd.getNamespaceNames();
+        resultNamespaces = rd.getNamespaces();
         assertEquals(1, resultNamespaces.size());
         assertEquals("org.iso.18013-5.2019", resultNamespaces.iterator().next());
         entryNames = rd.getRetrievedEntryNames("org.iso.18013-5.2019");
@@ -361,7 +361,7 @@
         eKeyPair = credential.createEphemeralKeyPair();
         rd = retrieveForReader(credential, eKeyPair, readerKeyPairB, certChainForB, requestMessage,
                 entriesToRequest);
-        resultNamespaces = rd.getNamespaceNames();
+        resultNamespaces = rd.getNamespaces();
         assertEquals(1, resultNamespaces.size());
         assertEquals("org.iso.18013-5.2019", resultNamespaces.iterator().next());
         entryNames = rd.getRetrievedEntryNames("org.iso.18013-5.2019");
@@ -376,7 +376,7 @@
         eKeyPair = credential.createEphemeralKeyPair();
         rd = retrieveForReader(credential, eKeyPair, readerKeyPairB, certChainForBwithC,
                 requestMessage, entriesToRequest);
-        resultNamespaces = rd.getNamespaceNames();
+        resultNamespaces = rd.getNamespaces();
         assertEquals(1, resultNamespaces.size());
         assertEquals("org.iso.18013-5.2019", resultNamespaces.iterator().next());
         entryNames = rd.getRetrievedEntryNames("org.iso.18013-5.2019");
@@ -412,7 +412,7 @@
             entriesToRequest,
             null,
             null);
-        resultNamespaces = rd.getNamespaceNames();
+        resultNamespaces = rd.getNamespaces();
         assertEquals(1, resultNamespaces.size());
         assertEquals("org.iso.18013-5.2019", resultNamespaces.iterator().next());
         entryNames = rd.getRetrievedEntryNames("org.iso.18013-5.2019");
diff --git a/tests/tests/identity/src/android/security/identity/cts/UserAuthTest.java b/tests/tests/identity/src/android/security/identity/cts/UserAuthTest.java
index d991938..e63c517 100644
--- a/tests/tests/identity/src/android/security/identity/cts/UserAuthTest.java
+++ b/tests/tests/identity/src/android/security/identity/cts/UserAuthTest.java
@@ -229,9 +229,9 @@
                 new PersonalizationData.Builder()
                         .addAccessControlProfile(authTenSecTimeoutProfile)
                         .addAccessControlProfile(freeForAllProfile)
-                        .setEntry(mdlNs, "Accessible to all (0)", idsProfile0,
+                        .putEntry(mdlNs, "Accessible to all (0)", idsProfile0,
                                 Util.cborEncodeString("foo0"))
-                        .setEntry(mdlNs, "Accessible to auth-with-10-sec-timeout (1)", idsProfile1,
+                        .putEntry(mdlNs, "Accessible to auth-with-10-sec-timeout (1)", idsProfile1,
                                 Util.cborEncodeString("foo1"))
                         .build();
         byte[] proofOfProvisioningSignature = wc.personalize(personalizationData);
@@ -301,7 +301,7 @@
             entriesToRequest,
             null,  // sessionTranscript
             null); // readerSignature
-        resultNamespaces = rd.getNamespaceNames();
+        resultNamespaces = rd.getNamespaces();
         assertEquals(1, resultNamespaces.size());
         assertEquals("org.iso.18013-5.2019", resultNamespaces.iterator().next());
         entryNames = rd.getEntryNames("org.iso.18013-5.2019");
@@ -334,7 +334,7 @@
                 entriesToRequest,
                 null,  // sessionTranscript
                 null); // readerSignature
-        resultNamespaces = rd.getNamespaceNames();
+        resultNamespaces = rd.getNamespaces();
         assertEquals(1, resultNamespaces.size());
         assertEquals("org.iso.18013-5.2019", resultNamespaces.iterator().next());
         entryNames = rd.getEntryNames("org.iso.18013-5.2019");
@@ -368,7 +368,7 @@
             entriesToRequest,
             null,  // sessionTranscript
             null); // readerSignature
-        resultNamespaces = rd.getNamespaceNames();
+        resultNamespaces = rd.getNamespaces();
         assertEquals(1, resultNamespaces.size());
         assertEquals("org.iso.18013-5.2019", resultNamespaces.iterator().next());
         entryNames = rd.getEntryNames("org.iso.18013-5.2019");
diff --git a/tests/tests/jni_vendor/libvendorjnitest/Android.bp b/tests/tests/jni_vendor/libvendorjnitest/Android.bp
deleted file mode 100644
index 0589010..0000000
--- a/tests/tests/jni_vendor/libvendorjnitest/Android.bp
+++ /dev/null
@@ -1,31 +0,0 @@
-// Copyright (C) 2017 The Android Open Source Project
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//      http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-//
-// This is the shared library included by the JNI test app.
-//
-
-cc_test_library {
-    name: "libvendorjnitest",
-    srcs: ["android_jni_vendor_cts_VendorJniTest.cpp"],
-    shared_libs: [
-        "libdl",
-        "liblog",
-    ],
-    sdk_version: "current",
-    stl: "c++_static",
-    cflags: ["-Wno-unused-parameter"],
-    vendor: true,
-    gtest: false,
-}
diff --git a/tests/tests/jni_vendor/libvendorjnitest/android_jni_vendor_cts_VendorJniTest.cpp b/tests/tests/jni_vendor/libvendorjnitest/android_jni_vendor_cts_VendorJniTest.cpp
deleted file mode 100644
index 42e740e..0000000
--- a/tests/tests/jni_vendor/libvendorjnitest/android_jni_vendor_cts_VendorJniTest.cpp
+++ /dev/null
@@ -1,33 +0,0 @@
-/*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include <jni.h>
-#include <dlfcn.h>
-
-extern "C" JNIEXPORT jstring JNICALL
-Java_android_jni_vendor_cts_VendorJniTest_dlopen(JNIEnv* env, jclass clazz, jstring name) {
-    const char* libname = env->GetStringUTFChars(name, nullptr);
-    jstring error_msg;
-    dlerror(); // clear any existing error
-    void* handle = dlopen(libname, RTLD_NOW);
-    env->ReleaseStringUTFChars(name, libname);
-    if (handle == nullptr) {
-        error_msg = env->NewStringUTF(dlerror());
-    } else {
-        error_msg = env->NewStringUTF("");
-    }
-    return error_msg;
-}
diff --git a/tests/tests/jni_vendor/src/android/jni/vendor/cts/VendorJniTest.java b/tests/tests/jni_vendor/src/android/jni/vendor/cts/VendorJniTest.java
deleted file mode 100644
index db970e1..0000000
--- a/tests/tests/jni_vendor/src/android/jni/vendor/cts/VendorJniTest.java
+++ /dev/null
@@ -1,117 +0,0 @@
-/*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.jni.vendor.cts;
-
-import java.io.File;
-import java.io.IOException;
-import java.nio.file.Files;
-import java.nio.file.FileSystems;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.List;
-
-import junit.framework.TestCase;
-
-import android.os.Process;
-
-public class VendorJniTest extends TestCase {
-    private List<String> llndkLibraries;
-    private List<String> publicLibraries;
-    private List<String> vndkspLibraries;
-    private List<String> vndkLibraries;
-    private List<String> frameworkOnlyLibraries;
-
-    protected void setUp() throws Exception {
-        llndkLibraries = Files.readAllLines(FileSystems.getDefault().getPath(
-                "/system/etc/llndk.libraries.txt"));
-        publicLibraries = Files.readAllLines(FileSystems.getDefault().getPath(
-                "/system/etc/public.libraries.txt"));
-        vndkspLibraries = Files.readAllLines(FileSystems.getDefault().getPath(
-                "/system/etc/vndksp.libraries.txt"));
-
-        String systemLibDir = Process.is64Bit() ? "/system/lib64" : "/system/lib";
-
-        vndkLibraries = new ArrayList<>();
-        for(File f : (new File(systemLibDir + "/vndk")).listFiles()) {
-            if (f.isFile()) {
-                String name = f.getName();
-                if (name.endsWith(".so")) {
-                    vndkLibraries.add(name);
-                }
-            }
-        }
-
-        frameworkOnlyLibraries = new ArrayList<>();
-        for(File f : (new File(systemLibDir)).listFiles()) {
-            if (f.isFile()) {
-                String name = f.getName();
-                if (name.endsWith(".so") && !llndkLibraries.contains(name)
-                        && !vndkspLibraries.contains(name)
-                        && !publicLibraries.contains(name)) {
-                    frameworkOnlyLibraries.add(name);
-                }
-            }
-        }
-
-        System.loadLibrary("vendorjnitest");
-    }
-
-    public static native String dlopen(String name);
-
-    /* test if llndk libraries are all accessible */
-    public void test_llndkLibraries() {
-        for(String lib : llndkLibraries) {
-            assertEquals("", dlopen(lib));
-        }
-    }
-
-    /* test if vndk-sp libs are accessible */
-    public void test_vndkSpLibraries() {
-        for(String lib : vndkspLibraries) {
-            String error = dlopen(lib);
-            if (lib.equals("android.hidl.memory@1.0-impl.so")) {
-                // This won't be accessible to vendor JNI. This lib is only accessible from the
-                // 'sphal' namespace which isn't linked to the vendor-classloader-namespace.
-                if (error.equals("")) {
-                    fail(lib + " must not be accessible to vendor apks, but was accessible.");
-                }
-                continue;
-            }
-            assertEquals("", error);
-        }
-    }
-
-    /* test if vndk libs are not accessible */
-    public void test_vndkLibraries() {
-        for(String lib : vndkLibraries) {
-            String error = dlopen(lib);
-            if (error.equals("")) {
-                fail(lib + " must not be accessible to vendor apks, but was accessible.");
-            }
-        }
-    }
-
-    /* test if framework-only libs are not accessible */
-    public void test_frameworkOnlyLibraries() {
-        for(String lib : frameworkOnlyLibraries) {
-            String error = dlopen(lib);
-            if (error.equals("")) {
-                fail(lib + " must not be accessible to vendor apks, but was accessible.");
-            }
-        }
-    }
-}
diff --git a/tests/tests/keystore/src/android/keystore/cts/KeyAttestationTest.java b/tests/tests/keystore/src/android/keystore/cts/KeyAttestationTest.java
index 46592ca..5cb08a1 100644
--- a/tests/tests/keystore/src/android/keystore/cts/KeyAttestationTest.java
+++ b/tests/tests/keystore/src/android/keystore/cts/KeyAttestationTest.java
@@ -53,6 +53,7 @@
 import static org.hamcrest.Matchers.greaterThanOrEqualTo;
 import static org.hamcrest.Matchers.hasItems;
 
+import android.content.pm.PackageManager;
 import android.content.pm.PackageManager.NameNotFoundException;
 import android.os.Build;
 import android.os.SystemProperties;
@@ -164,6 +165,10 @@
                 KM_PURPOSE_SIGN, KM_PURPOSE_VERIFY, KM_PURPOSE_SIGN | KM_PURPOSE_VERIFY
         };
 
+        // Skip the test if there is no secure lock screen
+        if (!hasSecureLockScreen()) {
+            return;
+        }
         for (int curveIndex = 0; curveIndex < curves.length; ++curveIndex) {
             for (int challengeIndex = 0; challengeIndex < challenges.length; ++challengeIndex) {
                 for (int purposeIndex = 0; purposeIndex < purposes.length; ++purposeIndex) {
@@ -326,6 +331,10 @@
                 },
         };
 
+        // Skip the test if there is no secure lock screen
+        if (!hasSecureLockScreen()) {
+            return;
+        }
         for (int keySize : keySizes) {
             for (byte[] challenge : challenges) {
                 for (int purpose : purposes) {
@@ -1145,4 +1154,15 @@
             }
         }
     }
+    /*
+     * Device that don't report android.software.device_admin doesn't have secure lock screen
+     * because device with secure lock screen MUST report android.software.device_admin .
+     *
+     * https://source.android.com/compatibility/7.0/android-7.0-cdd.html#3_9_device_administration
+     *
+     */
+    private boolean hasSecureLockScreen() {
+        PackageManager pm = getContext().getPackageManager();
+        return pm.hasSystemFeature(PackageManager.FEATURE_DEVICE_ADMIN);
+    }
 }
diff --git a/tests/tests/media/Android.bp b/tests/tests/media/Android.bp
index b0930a6..0414e7d 100644
--- a/tests/tests/media/Android.bp
+++ b/tests/tests/media/Android.bp
@@ -59,6 +59,7 @@
         "-0 .ts",
         "-0 .heic",
         "-0 .trp",
+        "-0 .ota",
     ],
     srcs: ["src/**/*.java"],
     // This test uses private APIs
@@ -77,4 +78,5 @@
         "mts",
     ],
     host_required: ["cts-dynamic-config"],
+    min_sdk_version: "29",
 }
diff --git a/tests/tests/media/AndroidManifest.xml b/tests/tests/media/AndroidManifest.xml
index 1bec10d..7a00734 100644
--- a/tests/tests/media/AndroidManifest.xml
+++ b/tests/tests/media/AndroidManifest.xml
@@ -152,6 +152,8 @@
        <receiver android:name="android.media.cts.MediaButtonReceiver" />
     </application>
 
+    <uses-sdk android:minSdkVersion="29"   android:targetSdkVersion="29" />
+
     <instrumentation android:name="androidx.test.runner.AndroidJUnitRunner"
                      android:targetPackage="android.media.cts"
                      android:label="CTS tests of android.media">
diff --git a/tests/tests/media/libaudiojni/Android.bp b/tests/tests/media/libaudiojni/Android.bp
index 44dab86..29603f0 100644
--- a/tests/tests/media/libaudiojni/Android.bp
+++ b/tests/tests/media/libaudiojni/Android.bp
@@ -18,6 +18,7 @@
     srcs: [
         "appendix-b-1-1-buffer-queue.cpp",
         "appendix-b-1-2-recording.cpp",
+        "audio-metadata-native.cpp",
         "audio-record-native.cpp",
         "audio-track-native.cpp",
         "sl-utils.cpp",
@@ -29,6 +30,9 @@
         "libnativehelper_compat_libc++",
         "libOpenSLES",
     ],
+    header_libs: [
+        "libaudioutils_headers",
+    ],
     stl: "libc++_static",
     cflags: [
         "-Werror",
diff --git a/tests/tests/media/libaudiojni/audio-metadata-native.cpp b/tests/tests/media/libaudiojni/audio-metadata-native.cpp
new file mode 100644
index 0000000..38f5047
--- /dev/null
+++ b/tests/tests/media/libaudiojni/audio-metadata-native.cpp
@@ -0,0 +1,80 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+//#define LOG_NDEBUG 0
+#define LOG_TAG "audio-metadata-native"
+
+#include <algorithm>
+#include <atomic>
+
+#include <audio_utils/Metadata.h>
+#include <nativehelper/scoped_local_ref.h>
+#include <nativehelper/scoped_utf_chars.h>
+#include <utils/Log.h>
+
+#include <jni.h>
+
+using namespace android;
+
+static jclass gByteBufferClass;
+static jmethodID gByteBufferAllocateDirect;
+
+static std::atomic<bool> gFieldsInitialized = false;
+
+static void initializeGlobalFields(JNIEnv *env)
+{
+    if (gFieldsInitialized) {
+        return;
+    }
+
+    ScopedLocalRef<jclass> byteBufferClass(env, env->FindClass("java/nio/ByteBuffer"));
+    gByteBufferClass = (jclass) env->NewGlobalRef(byteBufferClass.get());
+    gByteBufferAllocateDirect = env->GetStaticMethodID(
+            gByteBufferClass, "allocateDirect", "(I)Ljava/nio/ByteBuffer;");
+    gFieldsInitialized = true;
+}
+
+extern "C" jobject Java_android_media_cts_AudioMetadataTest_nativeGetByteBuffer(
+    JNIEnv *env, jclass /*clazz*/, jobject javaByteBuffer, jint sizeInBytes)
+{
+    initializeGlobalFields(env);
+
+    const uint8_t* bytes =
+            reinterpret_cast<const uint8_t*>(env->GetDirectBufferAddress(javaByteBuffer));
+    if (bytes == nullptr) {
+        ALOGE("Cannot get byte array");
+        return nullptr;
+    }
+    audio_utils::metadata::Data d = audio_utils::metadata::dataFromByteString(
+            audio_utils::metadata::ByteString(bytes, sizeInBytes));
+
+    audio_utils::metadata::ByteString bs = byteStringFromData(d);
+
+    jobject byteBuffer = env->CallStaticObjectMethod(
+            gByteBufferClass, gByteBufferAllocateDirect, (jint) bs.size());
+    if (env->ExceptionCheck()) {
+        env->ExceptionDescribe();
+        env->ExceptionClear();
+    }
+    if (byteBuffer == nullptr) {
+        ALOGE("Failed to allocate byte buffer");
+        return nullptr;
+    }
+
+    uint8_t* byteBufferAddr = (uint8_t*)env->GetDirectBufferAddress(byteBuffer);
+    std::copy(bs.begin(), bs.end(), byteBufferAddr);
+    return byteBuffer;
+}
diff --git a/tests/tests/media/libmediandkjni/native_media_encoder_jni.cpp b/tests/tests/media/libmediandkjni/native_media_encoder_jni.cpp
index fd7ddc5..2333ddd 100644
--- a/tests/tests/media/libmediandkjni/native_media_encoder_jni.cpp
+++ b/tests/tests/media/libmediandkjni/native_media_encoder_jni.cpp
@@ -213,7 +213,6 @@
     int32_t nFrameCount = 0;
 
     while (nFrameCount < framesToEncode) {
-
         // apply frame-specific settings
         for (;paramItr != dynamicParams.end()
                 && (*paramItr)->frameNum() <= nFrameCount; ++paramItr) {
@@ -228,7 +227,7 @@
         }
 
         AMediaCodecBufferInfo info;
-        int status = AMediaCodec_dequeueOutputBuffer(mEnc.get(), &info, 5000);
+        int status = AMediaCodec_dequeueOutputBuffer(mEnc.get(), &info, 5000000);
         if (status >= 0) {
             ALOGV("got encoded buffer[%d] of size=%d @%lld us flags=%x",
                     nFrameCount, info.size, (long long)info.presentationTimeUs, info.flags);
@@ -248,6 +247,8 @@
             mStats.setOutputFormat(format);
             ALOGV("format changed: %s", AMediaFormat_toString(format.get()));
         } else if (status == AMEDIACODEC_INFO_TRY_AGAIN_LATER) {
+            ALOGE("no frame in 5 seconds, assume stuck");
+            break;
         } else {
             ALOGV("Invalid status : %d", status);
         }
diff --git a/tests/tests/media/res/raw/testimy.imy b/tests/tests/media/res/raw/testimy.imy
new file mode 100644
index 0000000..d837815
--- /dev/null
+++ b/tests/tests/media/res/raw/testimy.imy
@@ -0,0 +1,10 @@
+BEGIN:IMELODY

+VERSION:1.2

+FORMAT:CLASS1.0

+NAME:Test

+COMPOSER:Android

+BEAT:120

+STYLE:S1

+VOLUME:V7

+MELODY:a1b2c3backoffa3.backon*4d3a3backoffg3.backon*5c4c1*5#f2*5#f2

+END:IMELODY

diff --git a/tests/tests/media/res/raw/testota.ota b/tests/tests/media/res/raw/testota.ota
new file mode 100644
index 0000000..7aa5f99
--- /dev/null
+++ b/tests/tests/media/res/raw/testota.ota
Binary files differ
diff --git a/tests/tests/media/res/raw/testrtttl.rtttl b/tests/tests/media/res/raw/testrtttl.rtttl
new file mode 100644
index 0000000..1f7e270
--- /dev/null
+++ b/tests/tests/media/res/raw/testrtttl.rtttl
@@ -0,0 +1 @@
+Test:d=2,o=6,b=120,l=2,s=n:a,b,c,d,e,4a,4b#,4c,4d,a4,b4,c4,d4
diff --git a/tests/tests/media/src/android/media/cts/AudioManagerTest.java b/tests/tests/media/src/android/media/cts/AudioManagerTest.java
index 7e475d1..6268466 100644
--- a/tests/tests/media/src/android/media/cts/AudioManagerTest.java
+++ b/tests/tests/media/src/android/media/cts/AudioManagerTest.java
@@ -617,6 +617,11 @@
         int maxMusicVolume = mAudioManager.getStreamMaxVolume(STREAM_MUSIC);
 
         for (int stream : streams) {
+
+            if (mIsSingleVolume && stream != AudioManager.STREAM_MUSIC) {
+                continue;
+            }
+
             // set ringer mode to back normal to not interfere with volume tests
             mAudioManager.setRingerMode(RINGER_MODE_NORMAL);
 
diff --git a/tests/tests/media/src/android/media/cts/AudioMetadataTest.java b/tests/tests/media/src/android/media/cts/AudioMetadataTest.java
index b4cec84..4272363 100755
--- a/tests/tests/media/src/android/media/cts/AudioMetadataTest.java
+++ b/tests/tests/media/src/android/media/cts/AudioMetadataTest.java
@@ -16,16 +16,18 @@
 
 package android.media.cts;
 
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.*;
 import static org.testng.Assert.assertThrows;
 
 import android.media.AudioMetadata;
+import android.util.Log;
 import androidx.test.runner.AndroidJUnit4;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 
+import java.nio.ByteBuffer;
+import java.nio.ByteOrder;
+
 @NonMediaMainlineTest
 @RunWith(AndroidJUnit4.class)
 public class AudioMetadataTest {
@@ -37,6 +39,14 @@
         KEY_NUMBER = AudioMetadata.createKey("number", Number.class);
     private static final AudioMetadata.Key<String>
         KEY_STRING = AudioMetadata.createKey("string", String.class);
+    private static final AudioMetadata.Key<Long>
+        KEY_LONG = AudioMetadata.createKey("long", Long.class);
+    private static final AudioMetadata.Key<Float>
+        KEY_FLOAT = AudioMetadata.createKey("float", Float.class);
+    private static final AudioMetadata.Key<Double>
+        KEY_DOUBLE = AudioMetadata.createKey("double", Double.class);
+    private static final AudioMetadata.Key<AudioMetadata.BaseMap>
+        KEY_BASE_MAP = AudioMetadata.createKey("data", AudioMetadata.BaseMap.class);
 
     @Test
     public void testKey() throws Exception {
@@ -101,4 +111,144 @@
             () -> { audioMetadata.set(KEY_NUMBER, null); }
         );
     }
+
+    // The byte buffer here is generated by audio_utils::metadata::byteStringFromData(Data).
+    // Data data = {
+    //     "integer": (int32_t) 1,
+    //     "long": (int64_t) 2,
+    //     "float": (float) 3.1f,
+    //     "double": (double) 4.11,
+    //     "data": (Data) {
+    //         "string": (std::string) "hello",
+    //     }
+    // }
+    // Use to test compatibility of packing/unpacking audio metadata.
+    // DO NOT CHANGE after R
+    private static final byte[] BYTE_BUFFER_REFERENCE = new byte[] {
+            // Number of items
+            0x05, 0x00, 0x00, 0x00,
+            // Length of 1st key
+            0x04, 0x00, 0x00, 0x00,
+            // Payload of 1st key
+            0x64, 0x61, 0x74, 0x61,
+            // Data type of 1st value
+            0x06, 0x00, 0x00, 0x00,
+            // Length of 1st value
+            0x1f, 0x00, 0x00, 0x00,
+            // Payload of 1st value
+            0x01, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00,
+            0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x05, 0x00,
+            0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x05, 0x00,
+            0x00, 0x00, 0x68, 0x65, 0x6c, 0x6c, 0x6f,
+            // Length of 2nd key
+            0x06, 0x00, 0x00, 0x00,
+            // Payload of 2nd key
+            0x64, 0x6f, 0x75, 0x62, 0x6c, 0x65,
+            // Data type of 2nd value
+            0x04, 0x00, 0x00, 0x00,
+            // Length of 2nd value
+            0x08, 0x00, 0x00, 0x00,
+            // Payload of 2nd value
+            0x71, 0x3d, 0x0a, (byte) 0xd7, (byte) 0xa3, 0x70, 0x10, 0x40,
+            // Length of 3rd key
+            0x05, 0x00, 0x00, 0x00,
+            // Payload of 3rd key
+            0x66, 0x6c, 0x6f, 0x61, 0x74,
+            // Data type of 3rd value
+            0x03, 0x00, 0x00, 0x00,
+            // Length of 3rd value
+            0x04, 0x00, 0x00, 0x00,
+            // Payload of 3rd value
+            0x66, 0x66, 0x46, 0x40,
+            // Length of 4th key
+            0x07, 0x00, 0x00, 0x00,
+            // Payload of 4th key
+            0x69, 0x6e, 0x74, 0x65, 0x67, 0x65, 0x72,
+            // Data type of 4th value
+            0x01, 0x00, 0x00, 0x00,
+            // Length of 4th value
+            0x04, 0x00, 0x00, 0x00,
+            // Payload of 4th value
+            0x01, 0x00, 0x00, 0x00,
+            // Length of 5th key
+            0x04, 0x00, 0x00, 0x00,
+            // Payload of 5th key
+            0x6c, 0x6f, 0x6e, 0x67,
+            // Data type of 5th value
+            0x02, 0x00, 0x00, 0x00,
+            // Length of 5th value
+            0x08, 0x00, 0x00, 0x00,
+            // Payload of 5th value
+            0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+    };
+    // AUDIO_METADATA_REFERENCE corresponds to BYTE_BUFFER_REFERENCE.
+    // DO NOT CHANGE after R
+    private static final AudioMetadata.BaseMap AUDIO_METADATA_REFERENCE =
+            new AudioMetadata.BaseMap() {{
+                set(KEY_INTEGER, 1);
+                set(KEY_LONG, (long) 2);
+                set(KEY_FLOAT, 3.1f);
+                set(KEY_DOUBLE, 4.11);
+                set(KEY_BASE_MAP, new AudioMetadata.BaseMap() {{
+                    set(KEY_STRING, "hello");
+                }});
+            }};
+
+    // Position of data type for first value in reference buffer.
+    // Will be used to set an invalid data type for test.
+    private static final int FIRST_VALUE_DATA_TYPE_POSITION_IN_REFERENCE = 12;
+    private static final byte INVALID_DATA_TYPE = (byte) 0xff;
+
+    @Test
+    public void testCompatibilityR() {
+        ByteBuffer bufferPackedAtJava = AudioMetadata.toByteBuffer(
+                AUDIO_METADATA_REFERENCE, ByteOrder.nativeOrder());
+        assertNotNull(bufferPackedAtJava);
+        ByteBuffer buffer = nativeGetByteBuffer(bufferPackedAtJava, bufferPackedAtJava.limit());
+        assertNotNull(buffer);
+        ByteBuffer refBuffer = ByteBuffer.allocate(BYTE_BUFFER_REFERENCE.length);
+        refBuffer.put(BYTE_BUFFER_REFERENCE);
+        refBuffer.position(0);
+        assertEquals(buffer, refBuffer);
+    }
+
+    @Test
+    public void testUnpackingByteBuffer() throws Exception {
+        ByteBuffer bufferPackedAtJava = AudioMetadata.toByteBuffer(
+                AUDIO_METADATA_REFERENCE, ByteOrder.nativeOrder());
+        assertNotNull(bufferPackedAtJava);
+        ByteBuffer buffer = nativeGetByteBuffer(bufferPackedAtJava, bufferPackedAtJava.limit());
+        assertNotNull(buffer);
+        buffer.order(ByteOrder.nativeOrder());
+
+        AudioMetadata.BaseMap metadataFromByteBuffer = AudioMetadata.fromByteBuffer(buffer);
+        assertNotNull(metadataFromByteBuffer);
+        assertEquals(metadataFromByteBuffer, AUDIO_METADATA_REFERENCE);
+    }
+
+    @Test
+    public void testUnpackingInvalidBuffer() throws Exception {
+        ByteBuffer buffer = ByteBuffer.allocate(BYTE_BUFFER_REFERENCE.length);
+        buffer.put(BYTE_BUFFER_REFERENCE);
+        buffer.order(ByteOrder.nativeOrder());
+
+        // Manually modify the buffer to create an invalid buffer with an invalid data type,
+        // a null should be returned when unpacking.
+        buffer.position(FIRST_VALUE_DATA_TYPE_POSITION_IN_REFERENCE);
+        buffer.put(INVALID_DATA_TYPE);
+        buffer.position(0);
+        AudioMetadata.BaseMap metadataFromByteBuffer = AudioMetadata.fromByteBuffer(buffer);
+        assertNull(metadataFromByteBuffer);
+    }
+
+    static {
+        System.loadLibrary("audio_jni");
+    }
+
+    /**
+     * Passing a ByteBuffer that contains audio metadata. In native, the buffer will be
+     * unpacked as native audio metadata and then reconstructed as ByteBuffer back to Java.
+     * This is aimed at testing round trip (un)packing logic.
+     */
+    private static native ByteBuffer nativeGetByteBuffer(ByteBuffer buffer, int sizeInBytes);
 }
diff --git a/tests/tests/media/src/android/media/cts/MediaPlayerTest.java b/tests/tests/media/src/android/media/cts/MediaPlayerTest.java
index 3e547bb..57cb6e0 100644
--- a/tests/tests/media/src/android/media/cts/MediaPlayerTest.java
+++ b/tests/tests/media/src/android/media/cts/MediaPlayerTest.java
@@ -403,8 +403,13 @@
     }
 
     public void testPlayMidi() throws Exception {
-        final int resid = R.raw.midi8sec;
-        final int midiDuration = 8000;
+        runMidiTest(R.raw.midi8sec, 8000 /* duration */);
+        runMidiTest(R.raw.testrtttl, 30000 /* duration */);
+        runMidiTest(R.raw.testimy, 5125 /* duration */);
+        runMidiTest(R.raw.testota, 5906 /* duration */);
+    }
+
+    private void runMidiTest(int resid, int midiDuration) throws Exception {
         final int tolerance = 70;
         final int seekDuration = 1000;
 
diff --git a/tests/tests/media/src/android/media/cts/MediaRoute2InfoTest.java b/tests/tests/media/src/android/media/cts/MediaRoute2InfoTest.java
index 31974df..d4be2a5 100644
--- a/tests/tests/media/src/android/media/cts/MediaRoute2InfoTest.java
+++ b/tests/tests/media/src/android/media/cts/MediaRoute2InfoTest.java
@@ -49,7 +49,6 @@
     public static final String TEST_NAME = "test_name";
     public static final String TEST_ROUTE_TYPE_0 = "test_route_type_0";
     public static final String TEST_ROUTE_TYPE_1 = "test_route_type_1";
-    public static final int TEST_DEVICE_TYPE = MediaRoute2Info.DEVICE_TYPE_REMOTE_SPEAKER;
     public static final Uri TEST_ICON_URI = Uri.parse("https://developer.android.com");
     public static final String TEST_DESCRIPTION = "test_description";
     public static final int TEST_CONNECTION_STATE = MediaRoute2Info.CONNECTION_STATE_CONNECTING;
@@ -113,7 +112,6 @@
         MediaRoute2Info routeInfo = new MediaRoute2Info.Builder(TEST_ID, TEST_NAME)
                 .addFeature(TEST_ROUTE_TYPE_0)
                 .addFeature(TEST_ROUTE_TYPE_1)
-                .setDeviceType(TEST_DEVICE_TYPE)
                 .setIconUri(TEST_ICON_URI)
                 .setDescription(TEST_DESCRIPTION)
                 .setConnectionState(TEST_CONNECTION_STATE)
@@ -131,7 +129,6 @@
         assertEquals(TEST_ROUTE_TYPE_0, routeInfo.getFeatures().get(0));
         assertEquals(TEST_ROUTE_TYPE_1, routeInfo.getFeatures().get(1));
 
-        assertEquals(TEST_DEVICE_TYPE, routeInfo.getDeviceType());
         assertEquals(TEST_ICON_URI, routeInfo.getIconUri());
         assertEquals(TEST_DESCRIPTION, routeInfo.getDescription());
         assertEquals(TEST_CONNECTION_STATE, routeInfo.getConnectionState());
@@ -184,38 +181,6 @@
     }
 
     @Test
-    public void testhasAnyFeaturesReturnsFalse() {
-        MediaRoute2Info routeInfo = new MediaRoute2Info.Builder(TEST_ID, TEST_NAME)
-                .addFeature(TEST_ROUTE_TYPE_0)
-                .addFeature(TEST_ROUTE_TYPE_1)
-                .build();
-
-        List<String> testRouteTypes = new ArrayList<>();
-        testRouteTypes.add("non_matching_route_type_1");
-        testRouteTypes.add("non_matching_route_type_2");
-        testRouteTypes.add("non_matching_route_type_3");
-        testRouteTypes.add("non_matching_route_type_4");
-
-        assertFalse(routeInfo.hasAnyFeatures(testRouteTypes));
-    }
-
-    @Test
-    public void testhasAnyFeaturesReturnsTrue() {
-        MediaRoute2Info routeInfo = new MediaRoute2Info.Builder(TEST_ID, TEST_NAME)
-                .addFeature(TEST_ROUTE_TYPE_0)
-                .addFeature(TEST_ROUTE_TYPE_1)
-                .build();
-
-        List<String> testRouteTypes = new ArrayList<>();
-        testRouteTypes.add("non_matching_route_type_1");
-        testRouteTypes.add("non_matching_route_type_2");
-        testRouteTypes.add("non_matching_route_type_3");
-        testRouteTypes.add(TEST_ROUTE_TYPE_1);
-
-        assertTrue(routeInfo.hasAnyFeatures(testRouteTypes));
-    }
-
-    @Test
     public void testEqualsCreatedWithSameArguments() {
         Bundle extras = new Bundle();
         extras.putString(TEST_KEY, TEST_VALUE);
@@ -223,7 +188,6 @@
         MediaRoute2Info routeInfo1 = new MediaRoute2Info.Builder(TEST_ID, TEST_NAME)
                 .addFeature(TEST_ROUTE_TYPE_0)
                 .addFeature(TEST_ROUTE_TYPE_1)
-                .setDeviceType(TEST_DEVICE_TYPE)
                 .setIconUri(TEST_ICON_URI)
                 .setDescription(TEST_DESCRIPTION)
                 .setConnectionState(TEST_CONNECTION_STATE)
@@ -237,7 +201,6 @@
         MediaRoute2Info routeInfo2 = new MediaRoute2Info.Builder(TEST_ID, TEST_NAME)
                 .addFeature(TEST_ROUTE_TYPE_0)
                 .addFeature(TEST_ROUTE_TYPE_1)
-                .setDeviceType(TEST_DEVICE_TYPE)
                 .setIconUri(TEST_ICON_URI)
                 .setDescription(TEST_DESCRIPTION)
                 .setConnectionState(TEST_CONNECTION_STATE)
@@ -260,7 +223,6 @@
         MediaRoute2Info routeInfo1 = new MediaRoute2Info.Builder(TEST_ID, TEST_NAME)
                 .addFeature(TEST_ROUTE_TYPE_0)
                 .addFeature(TEST_ROUTE_TYPE_1)
-                .setDeviceType(TEST_DEVICE_TYPE)
                 .setIconUri(TEST_ICON_URI)
                 .setDescription(TEST_DESCRIPTION)
                 .setConnectionState(TEST_CONNECTION_STATE)
@@ -285,7 +247,6 @@
         MediaRoute2Info routeInfo = new MediaRoute2Info.Builder(TEST_ID, TEST_NAME)
                 .addFeature(TEST_ROUTE_TYPE_0)
                 .addFeature(TEST_ROUTE_TYPE_1)
-                .setDeviceType(TEST_DEVICE_TYPE)
                 .setIconUri(TEST_ICON_URI)
                 .setDescription(TEST_DESCRIPTION)
                 .setConnectionState(TEST_CONNECTION_STATE)
@@ -301,9 +262,6 @@
                 .addFeature("randomRouteType")
                 .build());
         assertNotEquals(routeInfo, new MediaRoute2Info.Builder(routeInfo)
-                .setDeviceType(TEST_DEVICE_TYPE + 1)
-                .build());
-        assertNotEquals(routeInfo, new MediaRoute2Info.Builder(routeInfo)
                 .setIconUri(Uri.parse("randomUri"))
                 .build());
         assertNotEquals(routeInfo, new MediaRoute2Info.Builder(routeInfo)
@@ -335,7 +293,6 @@
         MediaRoute2Info routeInfo = new MediaRoute2Info.Builder(TEST_ID, TEST_NAME)
                 .addFeature(TEST_ROUTE_TYPE_0)
                 .addFeature(TEST_ROUTE_TYPE_1)
-                .setDeviceType(TEST_DEVICE_TYPE)
                 .setIconUri(TEST_ICON_URI)
                 .setDescription(TEST_DESCRIPTION)
                 .setConnectionState(TEST_CONNECTION_STATE)
@@ -372,7 +329,6 @@
         MediaRoute2Info routeInfo = new MediaRoute2Info.Builder(TEST_ID, TEST_NAME)
                 .addFeature(TEST_ROUTE_TYPE_0)
                 .addFeature(TEST_ROUTE_TYPE_1)
-                .setDeviceType(TEST_DEVICE_TYPE)
                 .setIconUri(TEST_ICON_URI)
                 .setDescription(TEST_DESCRIPTION)
                 .setConnectionState(TEST_CONNECTION_STATE)
diff --git a/tests/tests/media/src/android/media/cts/MediaRoute2ProviderServiceTest.java b/tests/tests/media/src/android/media/cts/MediaRoute2ProviderServiceTest.java
index 46c6dc4..e4c3ea1 100644
--- a/tests/tests/media/src/android/media/cts/MediaRoute2ProviderServiceTest.java
+++ b/tests/tests/media/src/android/media/cts/MediaRoute2ProviderServiceTest.java
@@ -121,7 +121,7 @@
                 SESSION_ID_1, "" /* clientPackageName */)
                 .addSelectedRoute(ROUTE_ID1)
                 .build();
-        mService.notifySessionCreated(sessionInfo1, MediaRoute2ProviderService.REQUEST_ID_NONE);
+        mService.notifySessionCreated(MediaRoute2ProviderService.REQUEST_ID_NONE, sessionInfo1);
         assertEquals(1, mService.getAllSessionInfo().size());
         assertEquals(sessionInfo1, mService.getAllSessionInfo().get(0));
         assertEquals(sessionInfo1, mService.getSessionInfo(SESSION_ID_1));
@@ -132,7 +132,7 @@
                 .addSelectedRoute(ROUTE_ID2)
                 .build();
         mService.notifySessionCreated(
-                sessionInfo2, MediaRoute2ProviderService.REQUEST_ID_NONE);
+                MediaRoute2ProviderService.REQUEST_ID_NONE, sessionInfo2);
         assertEquals(2, mService.getAllSessionInfo().size());
         assertEquals(sessionInfo2, mService.getSessionInfo(SESSION_ID_2));
 
@@ -302,7 +302,7 @@
                         .addSelectableRoute(ROUTE_ID4_TO_SELECT_AND_DESELECT)
                         .addTransferableRoute(ROUTE_ID5_TO_TRANSFER_TO)
                         .build();
-                mService.notifySessionCreated(info, requestId);
+                mService.notifySessionCreated(requestId, info);
                 onCreateSessionLatch.countDown();
             }
 
@@ -360,7 +360,7 @@
             }
         });
 
-        CountDownLatch onControllerCreatedLatch = new CountDownLatch(1);
+        CountDownLatch onTransferredLatch = new CountDownLatch(1);
         CountDownLatch onControllerUpdatedForSelectLatch = new CountDownLatch(1);
         CountDownLatch onControllerUpdatedForDeselectLatch = new CountDownLatch(1);
         CountDownLatch onControllerUpdatedForTransferLatch = new CountDownLatch(1);
@@ -370,9 +370,10 @@
             @Override
             public void onTransferred(RoutingController oldController,
                     RoutingController newController) {
-                if (newController != null && SESSION_ID_1.equals(newController.getOriginalId())) {
+                if (SESSION_ID_1.equals(newController.getOriginalId())) {
+                    assertEquals(mRouter2.getSystemController(), oldController);
                     controllers.add(newController);
-                    onControllerCreatedLatch.countDown();
+                    onTransferredLatch.countDown();
                 }
             }
         };
@@ -412,7 +413,7 @@
 
             mRouter2.transferTo(routeToCreateSession);
             assertTrue(onCreateSessionLatch.await(TIMEOUT_MS, TimeUnit.MILLISECONDS));
-            assertTrue(onControllerCreatedLatch.await(TIMEOUT_MS, TimeUnit.MILLISECONDS));
+            assertTrue(onTransferredLatch.await(TIMEOUT_MS, TimeUnit.MILLISECONDS));
             assertFalse(controllers.isEmpty());
 
             RoutingController controller = controllers.get(0);
@@ -467,31 +468,31 @@
                         .addSelectableRoute(ROUTE_ID4_TO_SELECT_AND_DESELECT)
                         .addTransferableRoute(ROUTE_ID5_TO_TRANSFER_TO)
                         .build();
-                mService.notifySessionCreated(info, requestId);
+                mService.notifySessionCreated(requestId, info);
                 onCreateSessionLatch.countDown();
             }
         });
 
 
-        CountDownLatch onControllerCreatedLatch = new CountDownLatch(1);
-        CountDownLatch onControllerReleasedLatch = new CountDownLatch(1);
+        CountDownLatch onTransferredLatch = new CountDownLatch(1);
+        CountDownLatch onStoppedLatch = new CountDownLatch(1);
         List<RoutingController> controllers = new ArrayList<>();
 
         TransferCallback transferCallback = new TransferCallback() {
             @Override
             public void onTransferred(RoutingController oldController,
                     RoutingController newController) {
-                if (newController != null) {
-                    if (SESSION_ID_1.equals(newController.getOriginalId())) {
-                        controllers.add(newController);
-                        onControllerCreatedLatch.countDown();
-                    }
-                } else {
-                    // newController == null means that the oldController is released
-                    if (SESSION_ID_1.equals(oldController.getOriginalId())) {
-                        assertTrue(oldController.isReleased());
-                        onControllerReleasedLatch.countDown();
-                    }
+                if (SESSION_ID_1.equals(newController.getOriginalId())) {
+                    assertEquals(mRouter2.getSystemController(), oldController);
+                    controllers.add(newController);
+                    onTransferredLatch.countDown();
+                }
+            }
+            @Override
+            public void onStopped(RoutingController controller){
+                if (SESSION_ID_1.equals(controller.getOriginalId())) {
+                    assertTrue(controller.isReleased());
+                    onStoppedLatch.countDown();
                 }
             }
         };
@@ -505,11 +506,11 @@
 
             mRouter2.transferTo(routeToCreateSession);
             assertTrue(onCreateSessionLatch.await(TIMEOUT_MS, TimeUnit.MILLISECONDS));
-            assertTrue(onControllerCreatedLatch.await(TIMEOUT_MS, TimeUnit.MILLISECONDS));
+            assertTrue(onTransferredLatch.await(TIMEOUT_MS, TimeUnit.MILLISECONDS));
             assertFalse(controllers.isEmpty());
 
             mService.notifySessionReleased(SESSION_ID_1);
-            assertTrue(onControllerReleasedLatch.await(TIMEOUT_MS, TimeUnit.MILLISECONDS));
+            assertTrue(onStoppedLatch.await(TIMEOUT_MS, TimeUnit.MILLISECONDS));
         } finally {
             mRouter2.unregisterRouteCallback(dummyCallback);
             mRouter2.unregisterTransferCallback(transferCallback);
diff --git a/tests/tests/media/src/android/media/cts/MediaRouter2Test.java b/tests/tests/media/src/android/media/cts/MediaRouter2Test.java
index 7fe6b90..71f83de 100644
--- a/tests/tests/media/src/android/media/cts/MediaRouter2Test.java
+++ b/tests/tests/media/src/android/media/cts/MediaRouter2Test.java
@@ -183,12 +183,11 @@
             @Override
             public void onTransferred(RoutingController oldController,
                     RoutingController newController) {
-                if (newController != null) {
-                    assertTrue(createRouteMap(newController.getSelectedRoutes()).containsKey(
-                            ROUTE_ID1));
-                    controllers.add(newController);
-                    successLatch.countDown();
-                }
+                assertEquals(mRouter2.getSystemController(), oldController);
+                assertTrue(createRouteMap(newController.getSelectedRoutes()).containsKey(
+                        ROUTE_ID1));
+                controllers.add(newController);
+                successLatch.countDown();
             }
 
             @Override
@@ -233,10 +232,8 @@
             @Override
             public void onTransferred(RoutingController oldController,
                     RoutingController newController) {
-                if (newController != null) {
-                    controllers.add(newController);
-                    successLatch.countDown();
-                }
+                controllers.add(newController);
+                successLatch.countDown();
             }
 
             @Override
@@ -279,13 +276,11 @@
             @Override
             public void onTransferred(RoutingController oldController,
                     RoutingController newController) {
-                if (newController != null) {
-                    createdControllers.add(newController);
-                    if (successLatch1.getCount() > 0) {
-                        successLatch1.countDown();
-                    } else {
-                        successLatch2.countDown();
-                    }
+                createdControllers.add(newController);
+                if (successLatch1.getCount() > 0) {
+                    successLatch1.countDown();
+                } else {
+                    successLatch2.countDown();
                 }
             }
 
@@ -358,20 +353,18 @@
             @Override
             public void onTransferred(RoutingController oldController,
                     RoutingController newController) {
-                if (newController != null) {
-                    assertTrue(createRouteMap(newController.getSelectedRoutes()).containsKey(
-                            ROUTE_ID1));
+                assertTrue(createRouteMap(newController.getSelectedRoutes())
+                        .containsKey(ROUTE_ID1));
 
-                    // The StubMediaRoute2ProviderService is supposed to set control hints
-                    // with the given controllerHints.
-                    Bundle controlHints = newController.getControlHints();
-                    assertNotNull(controlHints);
-                    assertTrue(controlHints.containsKey(TEST_KEY));
-                    assertEquals(TEST_VALUE, controlHints.getString(TEST_KEY));
+                // The StubMediaRoute2ProviderService is supposed to set control hints
+                // with the given controllerHints.
+                Bundle controlHints = newController.getControlHints();
+                assertNotNull(controlHints);
+                assertTrue(controlHints.containsKey(TEST_KEY));
+                assertEquals(TEST_VALUE, controlHints.getString(TEST_KEY));
 
-                    controllers.add(newController);
-                    successLatch.countDown();
-                }
+                controllers.add(newController);
+                successLatch.countDown();
             }
 
             @Override
@@ -421,10 +414,8 @@
             @Override
             public void onTransferred(RoutingController oldController,
                     RoutingController newController) {
-                if (newController != null) {
-                    controllers.add(newController);
-                    successLatch.countDown();
-                }
+                controllers.add(newController);
+                successLatch.countDown();
             }
         };
 
@@ -493,10 +484,8 @@
             @Override
             public void onTransferred(RoutingController oldController,
                     RoutingController newController) {
-                if (newController != null) {
-                    controllers.add(newController);
-                    successLatch.countDown();
-                }
+                controllers.add(newController);
+                successLatch.countDown();
             }
 
             @Override
@@ -547,12 +536,11 @@
             @Override
             public void onTransferred(RoutingController oldController,
                     RoutingController newController) {
-                if (newController != null) {
-                    assertTrue(getOriginalRouteIds(newController.getSelectedRoutes()).contains(
-                            ROUTE_ID1));
-                    controllers.add(newController);
-                    onTransferredLatch.countDown();
-                }
+                assertEquals(mRouter2.getSystemController(), oldController);
+                assertTrue(getOriginalRouteIds(newController.getSelectedRoutes()).contains(
+                        ROUTE_ID1));
+                controllers.add(newController);
+                onTransferredLatch.countDown();
             }
         };
 
@@ -645,12 +633,11 @@
             @Override
             public void onTransferred(RoutingController oldController,
                     RoutingController newController) {
-                if (newController != null) {
-                    assertTrue(getOriginalRouteIds(newController.getSelectedRoutes()).contains(
-                            ROUTE_ID1));
-                    controllers.add(newController);
-                    onTransferredLatch.countDown();
-                }
+                assertEquals(mRouter2.getSystemController(), oldController);
+                assertTrue(getOriginalRouteIds(newController.getSelectedRoutes()).contains(
+                        ROUTE_ID1));
+                controllers.add(newController);
+                onTransferredLatch.countDown();
             }
         };
 
@@ -715,12 +702,11 @@
             @Override
             public void onTransferred(RoutingController oldController,
                     RoutingController newController) {
-                if (newController != null) {
-                    assertTrue(getOriginalRouteIds(newController.getSelectedRoutes()).contains(
-                            ROUTE_ID1));
-                    controllers.add(newController);
-                    onTransferredLatch.countDown();
-                }
+                assertEquals(mRouter2.getSystemController(), oldController);
+                assertTrue(getOriginalRouteIds(newController.getSelectedRoutes()).contains(
+                        ROUTE_ID1));
+                controllers.add(newController);
+                onTransferredLatch.countDown();
             }
         };
         ControllerCallback controllerCallback = new ControllerCallback() {
@@ -766,7 +752,86 @@
         }
     }
 
-    // TODO: Add tests for onSessionReleased() when provider releases the session.
+    // TODO: Add tests for onStopped() when provider releases the session.
+    @Test
+    public void testStop() throws Exception {
+        final List<String> sampleRouteType = new ArrayList<>();
+        sampleRouteType.add(FEATURE_SAMPLE);
+
+        Map<String, MediaRoute2Info> routes = waitAndGetRoutes(sampleRouteType);
+        MediaRoute2Info routeTransferFrom = routes.get(ROUTE_ID1);
+        assertNotNull(routeTransferFrom);
+
+        final CountDownLatch onTransferredLatch = new CountDownLatch(1);
+        final CountDownLatch onControllerUpdatedLatch = new CountDownLatch(1);
+        final CountDownLatch onStoppedLatch = new CountDownLatch(1);
+        final List<RoutingController> controllers = new ArrayList<>();
+
+        TransferCallback transferCallback = new TransferCallback() {
+            @Override
+            public void onTransferred(RoutingController oldController,
+                    RoutingController newController) {
+                assertEquals(mRouter2.getSystemController(), oldController);
+                assertTrue(getOriginalRouteIds(newController.getSelectedRoutes()).contains(
+                        ROUTE_ID1));
+                controllers.add(newController);
+                onTransferredLatch.countDown();
+            }
+            @Override
+            public void onStopped(RoutingController controller) {
+                if (onTransferredLatch.getCount() != 0
+                        || !TextUtils.equals(
+                        controllers.get(0).getId(), controller.getId())) {
+                    return;
+                }
+                onStoppedLatch.countDown();
+            }
+        };
+
+        ControllerCallback controllerCallback = new ControllerCallback() {
+            @Override
+            public void onControllerUpdated(RoutingController controller) {
+                if (onTransferredLatch.getCount() != 0
+                        || !TextUtils.equals(controllers.get(0).getId(), controller.getId())) {
+                    return;
+                }
+                onControllerUpdatedLatch.countDown();
+            }
+        };
+
+        // TODO: Remove this once the MediaRouter2 becomes always connected to the service.
+        RouteCallback routeCallback = new RouteCallback() {};
+        mRouter2.registerRouteCallback(mExecutor, routeCallback, EMPTY_DISCOVERY_PREFERENCE);
+
+        try {
+            mRouter2.registerTransferCallback(mExecutor, transferCallback);
+            mRouter2.registerControllerCallback(mExecutor, controllerCallback);
+            mRouter2.transferTo(routeTransferFrom);
+            assertTrue(onTransferredLatch.await(TIMEOUT_MS, TimeUnit.MILLISECONDS));
+
+            assertEquals(1, controllers.size());
+            RoutingController controller = controllers.get(0);
+
+            mRouter2.stop();
+
+            // Select ROUTE_ID5_TO_TRANSFER_TO
+            MediaRoute2Info routeToSelect = routes.get(ROUTE_ID4_TO_SELECT_AND_DESELECT);
+            assertNotNull(routeToSelect);
+
+            // This call should be ignored.
+            // The onSessionInfoChanged() shouldn't be called.
+            controller.selectRoute(routeToSelect);
+            assertFalse(onControllerUpdatedLatch.await(WAIT_MS, TimeUnit.MILLISECONDS));
+
+            // onStopped should be called.
+            assertTrue(onStoppedLatch.await(TIMEOUT_MS, TimeUnit.MILLISECONDS));
+        } finally {
+            releaseControllers(controllers);
+            mRouter2.unregisterRouteCallback(routeCallback);
+            mRouter2.unregisterControllerCallback(controllerCallback);
+            mRouter2.unregisterTransferCallback(transferCallback);
+        }
+    }
 
     @Test
     public void testRoutingControllerRelease() throws Exception {
@@ -779,26 +844,27 @@
 
         final CountDownLatch onTransferredLatch = new CountDownLatch(1);
         final CountDownLatch onControllerUpdatedLatch = new CountDownLatch(1);
-        final CountDownLatch onControllerReleasedLatch = new CountDownLatch(1);
+        final CountDownLatch onStoppedLatch = new CountDownLatch(1);
         final List<RoutingController> controllers = new ArrayList<>();
 
         TransferCallback transferCallback = new TransferCallback() {
             @Override
             public void onTransferred(RoutingController oldController,
                     RoutingController newController) {
-                if (newController != null) {
-                    assertTrue(getOriginalRouteIds(newController.getSelectedRoutes()).contains(
-                            ROUTE_ID1));
-                    controllers.add(newController);
-                    onTransferredLatch.countDown();
-                } else {
-                    if (onTransferredLatch.getCount() != 0
-                            || !TextUtils.equals(
-                                    controllers.get(0).getId(), oldController.getId())) {
-                        return;
-                    }
-                    onControllerReleasedLatch.countDown();
+                assertEquals(mRouter2.getSystemController(), oldController);
+                assertTrue(getOriginalRouteIds(newController.getSelectedRoutes()).contains(
+                        ROUTE_ID1));
+                controllers.add(newController);
+                onTransferredLatch.countDown();
+            }
+            @Override
+            public void onStopped(RoutingController controller) {
+                if (onTransferredLatch.getCount() != 0
+                        || !TextUtils.equals(
+                                controllers.get(0).getId(), controller.getId())) {
+                    return;
                 }
+                onStoppedLatch.countDown();
             }
         };
 
@@ -838,8 +904,8 @@
             controller.selectRoute(routeToSelect);
             assertFalse(onControllerUpdatedLatch.await(WAIT_MS, TimeUnit.MILLISECONDS));
 
-            // onControllerReleased should be called.
-            assertTrue(onControllerReleasedLatch.await(TIMEOUT_MS, TimeUnit.MILLISECONDS));
+            // onStopped should be called.
+            assertTrue(onStoppedLatch.await(TIMEOUT_MS, TimeUnit.MILLISECONDS));
         } finally {
             releaseControllers(controllers);
             mRouter2.unregisterRouteCallback(routeCallback);
diff --git a/tests/tests/media/src/android/media/cts/StubMediaRoute2ProviderService.java b/tests/tests/media/src/android/media/cts/StubMediaRoute2ProviderService.java
index 326adb0..af02d16 100644
--- a/tests/tests/media/src/android/media/cts/StubMediaRoute2ProviderService.java
+++ b/tests/tests/media/src/android/media/cts/StubMediaRoute2ProviderService.java
@@ -16,8 +16,6 @@
 
 package android.media.cts;
 
-import static android.media.MediaRoute2Info.DEVICE_TYPE_REMOTE_SPEAKER;
-import static android.media.MediaRoute2Info.DEVICE_TYPE_REMOTE_TV;
 import static android.media.MediaRoute2Info.FEATURE_LIVE_AUDIO;
 import static android.media.MediaRoute2Info.PLAYBACK_VOLUME_VARIABLE;
 
@@ -94,11 +92,9 @@
     public void initializeRoutes() {
         MediaRoute2Info route1 = new MediaRoute2Info.Builder(ROUTE_ID1, ROUTE_NAME1)
                 .addFeature(FEATURE_SAMPLE)
-                .setDeviceType(DEVICE_TYPE_REMOTE_TV)
                 .build();
         MediaRoute2Info route2 = new MediaRoute2Info.Builder(ROUTE_ID2, ROUTE_NAME2)
                 .addFeature(FEATURE_SAMPLE)
-                .setDeviceType(DEVICE_TYPE_REMOTE_SPEAKER)
                 .build();
         MediaRoute2Info route3 = new MediaRoute2Info.Builder(
                 ROUTE_ID3_SESSION_CREATION_FAILED, ROUTE_NAME3)
@@ -218,8 +214,7 @@
 
         MediaRoute2Info route = mRoutes.get(routeId);
         if (route == null || TextUtils.equals(ROUTE_ID3_SESSION_CREATION_FAILED, routeId)) {
-            // Tell the router that session cannot be created by passing null as sessionInfo.
-            notifySessionCreationFailed(requestId);
+            notifyRequestFailed(requestId, REASON_UNKNOWN_ERROR);
             return;
         }
         maybeDeselectRoute(routeId, requestId);
@@ -242,7 +237,7 @@
                 // Set control hints with given sessionHints
                 .setControlHints(sessionHints)
                 .build();
-        notifySessionCreated(sessionInfo, requestId);
+        notifySessionCreated(requestId, sessionInfo);
         publishRoutes();
     }
 
diff --git a/tests/tests/mediaparser/src/android/media/mediaparser/cts/MediaParserTest.java b/tests/tests/mediaparser/src/android/media/mediaparser/cts/MediaParserTest.java
index 73abb28..624016d 100644
--- a/tests/tests/mediaparser/src/android/media/mediaparser/cts/MediaParserTest.java
+++ b/tests/tests/mediaparser/src/android/media/mediaparser/cts/MediaParserTest.java
@@ -37,6 +37,30 @@
 @RunWith(AndroidJUnit4.class)
 public class MediaParserTest {
 
+    @Test
+    public void testCreationByName() {
+        testCreationByName("exo.MatroskaParser");
+        testCreationByName("exo.FragmentedMp4Parser");
+        testCreationByName("exo.Mp4Parser");
+        testCreationByName("exo.Mp3Parser");
+        testCreationByName("exo.AdtsParser");
+        testCreationByName("exo.Ac3Parser");
+        testCreationByName("exo.TsParser");
+        testCreationByName("exo.FlvParser");
+        testCreationByName("exo.OggParser");
+        testCreationByName("exo.PsParser");
+        testCreationByName("exo.WavParser");
+        testCreationByName("exo.AmrParser");
+        testCreationByName("exo.Ac4Parser");
+        testCreationByName("exo.FlacParser");
+        try {
+            testCreationByName("exo.ExtractorThatDoesNotExist");
+            Assert.fail();
+        } catch (IllegalArgumentException e) {
+            // Expected.
+        }
+    }
+
     // OGG.
 
     @Test
@@ -340,6 +364,11 @@
         testExtractAsset("mp4/sample_fragmented.mp4");
     }
 
+    private static void testCreationByName(String name) {
+        MediaParser.createByName(
+                name, new MockMediaParserOutputConsumer(new FakeExtractorOutput()));
+    }
+
     private static void testSniffAsset(String assetPath, String expectedParserName)
             throws IOException, InterruptedException {
         extractAsset(assetPath, expectedParserName);
diff --git a/tests/tests/mediaparser/src/android/media/mediaparser/cts/MockMediaParserOutputConsumer.java b/tests/tests/mediaparser/src/android/media/mediaparser/cts/MockMediaParserOutputConsumer.java
index 6728c78..a8bcf34 100644
--- a/tests/tests/mediaparser/src/android/media/mediaparser/cts/MockMediaParserOutputConsumer.java
+++ b/tests/tests/mediaparser/src/android/media/mediaparser/cts/MockMediaParserOutputConsumer.java
@@ -47,7 +47,7 @@
     }
 
     @Override
-    public void onSeekMap(MediaParser.SeekMap seekMap) {
+    public void onSeekMapFound(MediaParser.SeekMap seekMap) {
         mFakeExtractorOutput.seekMap(
                 new SeekMap() {
                     @Override
@@ -57,7 +57,7 @@
 
                     @Override
                     public long getDurationUs() {
-                        return seekMap.getDurationUs();
+                        return seekMap.getDurationMicros();
                     }
 
                     @Override
@@ -68,12 +68,12 @@
     }
 
     @Override
-    public void onTracksFound(int numberOfTracks) {
+    public void onTrackCountFound(int numberOfTracks) {
         // Do nothing.
     }
 
     @Override
-    public void onTrackData(int trackIndex, MediaParser.TrackData trackData) {
+    public void onTrackDataFound(int trackIndex, MediaParser.TrackData trackData) {
         while (mTrackOutputs.size() <= trackIndex) {
             mTrackOutputs.add(mFakeExtractorOutput.track(trackIndex, C.TRACK_TYPE_UNKNOWN));
         }
@@ -81,7 +81,7 @@
     }
 
     @Override
-    public void onSampleData(int trackIndex, MediaParser.InputReader inputReader)
+    public void onSampleDataFound(int trackIndex, MediaParser.InputReader inputReader)
             throws IOException {
         try {
             mFakeExtractorOutput
@@ -115,7 +115,7 @@
     }
 
     private static SeekPoint toExoPlayerSeekPoint(MediaParser.SeekPoint seekPoint) {
-        return new SeekPoint(seekPoint.timeUs, seekPoint.position);
+        return new SeekPoint(seekPoint.timeMicros, seekPoint.position);
     }
 
     private static Format toExoPlayerFormat(MediaParser.TrackData trackData) {
diff --git a/tests/tests/mediastress/Android.bp b/tests/tests/mediastress/Android.bp
index e0878b6..8a112df 100644
--- a/tests/tests/mediastress/Android.bp
+++ b/tests/tests/mediastress/Android.bp
@@ -39,4 +39,5 @@
     srcs: ["src/**/*.java"],
     host_required: ["cts-dynamic-config"],
     sdk_version: "test_current",
+    min_sdk_version: "29",
 }
diff --git a/tests/tests/mediastress/AndroidManifest.xml b/tests/tests/mediastress/AndroidManifest.xml
index f6c750f..b847ff5 100644
--- a/tests/tests/mediastress/AndroidManifest.xml
+++ b/tests/tests/mediastress/AndroidManifest.xml
@@ -41,6 +41,9 @@
         <activity android:name="android.mediastress.cts.NativeMediaActivity"
                   android:label="NativeMedia" />
     </application>
+
+    <uses-sdk android:minSdkVersion="29"   android:targetSdkVersion="29" />
+
     <instrumentation android:name="androidx.test.runner.AndroidJUnitRunner"
             android:targetPackage="android.mediastress.cts"
             android:label="Media stress tests InstrumentationRunner" >
diff --git a/tests/tests/net/assets/OWNERS b/tests/tests/net/assets/OWNERS
new file mode 100644
index 0000000..14edd1d
--- /dev/null
+++ b/tests/tests/net/assets/OWNERS
@@ -0,0 +1,4 @@
+# Bug component: 31808
+etancohen@google.com
+lorenzo@google.com
+satk@google.com
diff --git a/tests/tests/net/assets/ValidPasspointProfile.base64 b/tests/tests/net/assets/ValidPasspointProfile.base64
new file mode 100644
index 0000000..3f60eb8
--- /dev/null
+++ b/tests/tests/net/assets/ValidPasspointProfile.base64
@@ -0,0 +1 @@
+Q29udGVudC1UeXBlOiBtdWx0aXBhcnQvbWl4ZWQ7IGJvdW5kYXJ5PXtib3VuZGFyeX0KQ29udGVudC1UcmFuc2Zlci1FbmNvZGluZzogYmFzZTY0CgotLXtib3VuZGFyeX0KQ29udGVudC1UeXBlOiBhcHBsaWNhdGlvbi94LXBhc3Nwb2ludC1wcm9maWxlCkNvbnRlbnQtVHJhbnNmZXItRW5jb2Rpbmc6IGJhc2U2NAoKUEUxbmJYUlVjbVZsSUhodGJHNXpQU0p6ZVc1amJXdzZaRzFrWkdZeExqSWlQZ29nSUR4V1pYSkVWRVErTVM0eVBDOVdaWEpFVkVRK0NpQWdQRTV2WkdVK0NpQWdJQ0E4VG05a1pVNWhiV1UrVUdWeVVISnZkbWxrWlhKVGRXSnpZM0pwY0hScGIyNDhMMDV2WkdWT1lXMWxQZ29nSUNBZ1BGSlVVSEp2Y0dWeWRHbGxjejRLSUNBZ0lDQWdQRlI1Y0dVK0NpQWdJQ0FnSUNBZ1BFUkVSazVoYldVK2RYSnVPbmRtWVRwdGJ6cG9iM1J6Y0c5ME1tUnZkREF0Y0dWeWNISnZkbWxrWlhKemRXSnpZM0pwY0hScGIyNDZNUzR3UEM5RVJFWk9ZVzFsUGdvZ0lDQWdJQ0E4TDFSNWNHVStDaUFnSUNBOEwxSlVVSEp2Y0dWeWRHbGxjejRLSUNBZ0lEeE9iMlJsUGdvZ0lDQWdJQ0E4VG05a1pVNWhiV1UrYVRBd01Ud3ZUbTlrWlU1aGJXVStDaUFnSUNBZ0lEeE9iMlJsUGdvZ0lDQWdJQ0FnSUR4T2IyUmxUbUZ0WlQ1SWIyMWxVMUE4TDA1dlpHVk9ZVzFsUGdvZ0lDQWdJQ0FnSUR4T2IyUmxQZ29nSUNBZ0lDQWdJQ0FnUEU1dlpHVk9ZVzFsUGtaeWFXVnVaR3g1VG1GdFpUd3ZUbTlrWlU1aGJXVStDaUFnSUNBZ0lDQWdJQ0E4Vm1Gc2RXVStRVlJVSUZCaGMzTndiMmx1ZER3dlZtRnNkV1UrQ2lBZ0lDQWdJQ0FnUEM5T2IyUmxQZ29nSUNBZ0lDQWdJRHhPYjJSbFBnb2dJQ0FnSUNBZ0lDQWdQRTV2WkdWT1lXMWxQa1pSUkU0OEwwNXZaR1ZPWVcxbFBnb2dJQ0FnSUNBZ0lDQWdQRlpoYkhWbFBtRjBkSGRwWm1rdVkyOXRQQzlXWVd4MVpUNEtJQ0FnSUNBZ0lDQThMMDV2WkdVK0NpQWdJQ0FnSUR3dlRtOWtaVDRLSUNBZ0lDQWdQRTV2WkdVK0NpQWdJQ0FnSUNBZ1BFNXZaR1ZPWVcxbFBrTnlaV1JsYm5ScFlXdzhMMDV2WkdWT1lXMWxQZ29nSUNBZ0lDQWdJRHhPYjJSbFBnb2dJQ0FnSUNBZ0lDQWdQRTV2WkdWT1lXMWxQbEpsWVd4dFBDOU9iMlJsVG1GdFpUNEtJQ0FnSUNBZ0lDQWdJRHhXWVd4MVpUNTNiR0Z1TG0xdVl6UXhNQzV0WTJNek1UQXVNMmR3Y0c1bGRIZHZjbXN1YjNKblBDOVdZV3gxWlQ0S0lDQWdJQ0FnSUNBOEwwNXZaR1UrQ2lBZ0lDQWdJQ0FnUEU1dlpHVStDaUFnSUNBZ0lDQWdJQ0E4VG05a1pVNWhiV1UrVTBsTlBDOU9iMlJsVG1GdFpUNEtJQ0FnSUNBZ0lDQWdJRHhPYjJSbFBnb2dJQ0FnSUNBZ0lDQWdJQ0E4VG05a1pVNWhiV1UrU1UxVFNUd3ZUbTlrWlU1aGJXVStDaUFnSUNBZ0lDQWdJQ0FnSUR4V1lXeDFaVDR6TVRBME1UQXFQQzlXWVd4MVpUNEtJQ0FnSUNBZ0lDQWdJRHd2VG05a1pUNEtJQ0FnSUNBZ0lDQWdJQ0FnUEU1dlpHVStDaUFnSUNBZ0lDQWdJQ0FnSUNBZ1BFNXZaR1ZPWVcxbFBrVkJVRlI1Y0dVOEwwNXZaR1ZPWVcxbFBnb2dJQ0FnSUNBZ0lDQWdJQ0FnSUR4V1lXeDFaVDR5TXp3dlZtRnNkV1UrQ2lBZ0lDQWdJQ0FnSUNBZ0lEd3ZUbTlrWlQ0S0lDQWdJQ0FnSUNBOEwwNXZaR1UrQ2lBZ0lDQWdJRHd2VG05a1pUNEtJQ0FnSUR3dlRtOWtaVDRLSUNBOEwwNXZaR1UrQ2p3dlRXZHRkRlJ5WldVKwotLXtib3VuZGFyeX0tLQo=
diff --git a/tests/tests/net/ipsec/OWNERS b/tests/tests/net/ipsec/OWNERS
new file mode 100644
index 0000000..26407ff
--- /dev/null
+++ b/tests/tests/net/ipsec/OWNERS
@@ -0,0 +1,3 @@
+lorenzo@google.com
+nharold@google.com
+satk@google.com
diff --git a/tests/tests/net/src/android/net/wifi/cts/ConcurrencyTest.java b/tests/tests/net/src/android/net/wifi/cts/ConcurrencyTest.java
index ba0832f..d91bce8 100644
--- a/tests/tests/net/src/android/net/wifi/cts/ConcurrencyTest.java
+++ b/tests/tests/net/src/android/net/wifi/cts/ConcurrencyTest.java
@@ -30,15 +30,23 @@
 import android.net.NetworkInfo;
 import android.net.NetworkRequest;
 import android.net.wifi.WifiManager;
+import android.net.wifi.p2p.WifiP2pDevice;
+import android.net.wifi.p2p.WifiP2pGroup;
+import android.net.wifi.p2p.WifiP2pGroupList;
+import android.net.wifi.p2p.WifiP2pInfo;
 import android.net.wifi.p2p.WifiP2pManager;
+import android.net.wifi.p2p.nsd.WifiP2pServiceInfo;
+import android.net.wifi.p2p.nsd.WifiP2pUpnpServiceInfo;
 import android.provider.Settings;
 import android.platform.test.annotations.AppModeFull;
 import android.test.AndroidTestCase;
 import android.util.Log;
 
+import com.android.compatibility.common.util.ShellIdentityUtils;
 import com.android.compatibility.common.util.SystemUtil;
 
 import java.util.Arrays;
+import java.util.ArrayList;
 import java.util.BitSet;
 import java.util.LinkedList;
 import java.util.List;
@@ -69,6 +77,10 @@
         public int p2pState;
         public int discoveryState;
         public NetworkInfo networkInfo;
+        public WifiP2pInfo p2pInfo;
+        public String deviceName;
+        public WifiP2pGroupList persistentGroups;
+        public WifiP2pGroup group = new WifiP2pGroup();
     }
 
     private WifiManager mWifiManager;
@@ -76,6 +88,7 @@
     private WifiP2pManager.Channel mWifiP2pChannel;
     private MySync mMySync = new MySync();
     private MyResponse mMyResponse = new MyResponse();
+    private boolean mWasVerboseLoggingEnabled;
 
     private static final String TAG = "ConcurrencyTest";
     private static final int TIMEOUT_MSEC = 6000;
@@ -119,6 +132,27 @@
         }
     };
 
+    private WifiP2pManager.ActionListener mActionListener = new WifiP2pManager.ActionListener() {
+        @Override
+        public void onSuccess() {
+            synchronized (mMyResponse) {
+                mMyResponse.valid = true;
+                mMyResponse.success = true;
+                mMyResponse.notify();
+            }
+        }
+
+        @Override
+        public void onFailure(int reason) {
+            synchronized (mMyResponse) {
+                Log.d(TAG, "failure reason: " + reason);
+                mMyResponse.valid = true;
+                mMyResponse.success = false;
+                mMyResponse.notify();
+            }
+        }
+    };
+
     @Override
     protected void setUp() throws Exception {
        super.setUp();
@@ -127,6 +161,7 @@
             // skip the test if WiFi && p2p are not supported
             return;
         }
+
         mIntentFilter = new IntentFilter();
         mIntentFilter.addAction(WifiManager.WIFI_STATE_CHANGED_ACTION);
         mIntentFilter.addAction(WifiP2pManager.WIFI_P2P_STATE_CHANGED_ACTION);
@@ -140,6 +175,13 @@
             SystemUtil.runShellCommand("svc wifi disable");
             Thread.sleep(DURATION);
         }
+
+        // turn on verbose logging for tests
+        mWasVerboseLoggingEnabled = ShellIdentityUtils.invokeWithShellPermissions(
+                () -> mWifiManager.isVerboseLoggingEnabled());
+        ShellIdentityUtils.invokeWithShellPermissions(
+                () -> mWifiManager.setVerboseLoggingEnabled(true));
+
         assertTrue(!mWifiManager.isWifiEnabled());
         mMySync.expectedWifiState = WifiManager.WIFI_STATE_DISABLED;
         mMySync.expectedP2pState = WifiP2pManager.WIFI_P2P_STATE_DISABLED;
@@ -157,6 +199,9 @@
         }
         mContext.unregisterReceiver(mReceiver);
 
+        ShellIdentityUtils.invokeWithShellPermissions(
+                () -> mWifiManager.setVerboseLoggingEnabled(mWasVerboseLoggingEnabled));
+
         enableWifi();
         super.tearDown();
     }
@@ -221,6 +266,10 @@
         synchronized (responseObj) {
             responseObj.valid = false;
             responseObj.networkInfo = null;
+            responseObj.p2pInfo = null;
+            responseObj.deviceName = null;
+            responseObj.persistentGroups = null;
+            responseObj.group = null;
         }
     }
 
@@ -344,26 +393,7 @@
         assertEquals(WifiP2pManager.WIFI_P2P_DISCOVERY_STOPPED, mMyResponse.discoveryState);
 
         resetResponse(mMyResponse);
-        mWifiP2pManager.discoverPeers(mWifiP2pChannel, new WifiP2pManager.ActionListener() {
-            @Override
-            public void onSuccess() {
-                synchronized (mMyResponse) {
-                    mMyResponse.valid = true;
-                    mMyResponse.success = true;
-                    mMyResponse.notify();
-                }
-            }
-
-            @Override
-            public void onFailure(int reason) {
-                synchronized (mMyResponse) {
-                    Log.d(TAG, "discoveryPeers failure reason: " + reason);
-                    mMyResponse.valid = true;
-                    mMyResponse.success = false;
-                    mMyResponse.notify();
-                }
-            }
-        });
+        mWifiP2pManager.discoverPeers(mWifiP2pChannel, mActionListener);
         assertTrue(waitForServiceResponse(mMyResponse));
         assertTrue(mMyResponse.success);
         assertTrue(waitForBroadcasts(MySync.DISCOVERY_STATE));
@@ -411,26 +441,7 @@
                 mMySync.expectedNetworkInfo.getDetailedState());
 
         resetResponse(mMyResponse);
-        mWifiP2pManager.createGroup(mWifiP2pChannel, new WifiP2pManager.ActionListener() {
-            @Override
-            public void onSuccess() {
-                synchronized (mMyResponse) {
-                    mMyResponse.valid = true;
-                    mMyResponse.success = true;
-                    mMyResponse.notify();
-                }
-            }
-
-            @Override
-            public void onFailure(int reason) {
-                synchronized (mMyResponse) {
-                    Log.d(TAG, "createGroup failure reason: " + reason);
-                    mMyResponse.valid = true;
-                    mMyResponse.success = false;
-                    mMyResponse.notify();
-                }
-            }
-        });
+        mWifiP2pManager.createGroup(mWifiP2pChannel, mActionListener);
         assertTrue(waitForServiceResponse(mMyResponse));
         assertTrue(mMyResponse.success);
         assertTrue(waitForBroadcasts(MySync.NETWORK_INFO));
@@ -455,7 +466,239 @@
         assertEquals(NetworkInfo.DetailedState.CONNECTED,
                 mMyResponse.networkInfo.getDetailedState());
 
-        mWifiP2pManager.removeGroup(mWifiP2pChannel, null);
+        resetResponse(mMyResponse);
+        mWifiP2pManager.requestConnectionInfo(mWifiP2pChannel,
+                new WifiP2pManager.ConnectionInfoListener() {
+                    @Override
+                    public void onConnectionInfoAvailable(WifiP2pInfo info) {
+                        synchronized (mMyResponse) {
+                            mMyResponse.valid = true;
+                            mMyResponse.p2pInfo = new WifiP2pInfo(info);
+                            mMyResponse.notify();
+                        }
+                    }
+                });
+        assertTrue(waitForServiceResponse(mMyResponse));
+        assertNotNull(mMyResponse.p2pInfo);
+        assertTrue(mMyResponse.p2pInfo.groupFormed);
+        assertTrue(mMyResponse.p2pInfo.isGroupOwner);
+
+        resetResponse(mMyResponse);
+        mWifiP2pManager.requestGroupInfo(mWifiP2pChannel,
+                new WifiP2pManager.GroupInfoListener() {
+                    @Override
+                    public void onGroupInfoAvailable(WifiP2pGroup group) {
+                        synchronized (mMyResponse) {
+                            mMyResponse.group = new WifiP2pGroup(group);
+                            mMyResponse.valid = true;
+                            mMyResponse.notify();
+                        }
+                    }
+                });
+        assertTrue(waitForServiceResponse(mMyResponse));
+        assertNotNull(mMyResponse.group);
+        assertNotEquals(0, mMyResponse.group.getFrequency());
+        assertTrue(mMyResponse.group.getNetworkId() >= 0);
+
+        resetResponse(mMyResponse);
+        mWifiP2pManager.removeGroup(mWifiP2pChannel, mActionListener);
+        assertTrue(waitForServiceResponse(mMyResponse));
+        assertTrue(mMyResponse.success);
     }
 
+    private String getDeviceName() {
+        resetResponse(mMyResponse);
+        mWifiP2pManager.requestDeviceInfo(mWifiP2pChannel,
+                new WifiP2pManager.DeviceInfoListener() {
+                    @Override
+                    public void onDeviceInfoAvailable(WifiP2pDevice wifiP2pDevice) {
+                        synchronized (mMyResponse) {
+                            mMyResponse.deviceName = wifiP2pDevice.deviceName;
+                            mMyResponse.valid = true;
+                            mMyResponse.notify();
+                        }
+                    }
+                });
+        assertTrue(waitForServiceResponse(mMyResponse));
+        return mMyResponse.deviceName;
+    }
+
+    public void testSetDeviceName() {
+        if (!setupWifiP2p()) {
+            return;
+        }
+
+        String testDeviceName = "test";
+        String originalDeviceName = getDeviceName();
+        assertNotNull(originalDeviceName);
+
+        ShellIdentityUtils.invokeWithShellPermissions(() -> {
+            mWifiP2pManager.setDeviceName(
+                    mWifiP2pChannel, testDeviceName, mActionListener);
+            assertTrue(waitForServiceResponse(mMyResponse));
+            assertTrue(mMyResponse.success);
+        });
+
+        String currentDeviceName = getDeviceName();
+        assertEquals(testDeviceName, currentDeviceName);
+
+        // restore the device name at the end
+        ShellIdentityUtils.invokeWithShellPermissions(() -> {
+            mWifiP2pManager.setDeviceName(
+                    mWifiP2pChannel, originalDeviceName, mActionListener);
+            assertTrue(waitForServiceResponse(mMyResponse));
+            assertTrue(mMyResponse.success);
+        });
+    }
+
+    private WifiP2pGroupList getPersistentGroups() {
+        resetResponse(mMyResponse);
+        ShellIdentityUtils.invokeWithShellPermissions(() -> {
+            mWifiP2pManager.requestPersistentGroupInfo(mWifiP2pChannel,
+                    new WifiP2pManager.PersistentGroupInfoListener() {
+                        @Override
+                        public void onPersistentGroupInfoAvailable(WifiP2pGroupList groups) {
+                            synchronized (mMyResponse) {
+                                mMyResponse.persistentGroups = groups;
+                                mMyResponse.valid = true;
+                                mMyResponse.notify();
+                            }
+                        }
+                    });
+            assertTrue(waitForServiceResponse(mMyResponse));
+        });
+        return mMyResponse.persistentGroups;
+    }
+
+    public void testPersistentGroupOperation() {
+        if (!setupWifiP2p()) {
+            return;
+        }
+
+        resetResponse(mMyResponse);
+        mWifiP2pManager.createGroup(mWifiP2pChannel, mActionListener);
+        assertTrue(waitForServiceResponse(mMyResponse));
+        assertTrue(mMyResponse.success);
+        assertTrue(waitForBroadcasts(MySync.NETWORK_INFO));
+        assertNotNull(mMySync.expectedNetworkInfo);
+        assertEquals(NetworkInfo.DetailedState.CONNECTED,
+                mMySync.expectedNetworkInfo.getDetailedState());
+
+        resetResponse(mMyResponse);
+        mWifiP2pManager.removeGroup(mWifiP2pChannel, mActionListener);
+        assertTrue(waitForServiceResponse(mMyResponse));
+        assertTrue(mMyResponse.success);
+
+        WifiP2pGroupList persistentGroups = getPersistentGroups();
+        assertNotNull(persistentGroups);
+        assertEquals(1, persistentGroups.getGroupList().size());
+
+        resetResponse(mMyResponse);
+        final int firstNetworkId = persistentGroups.getGroupList().get(0).getNetworkId();
+        ShellIdentityUtils.invokeWithShellPermissions(() -> {
+            mWifiP2pManager.deletePersistentGroup(mWifiP2pChannel,
+                    firstNetworkId,
+                    mActionListener);
+            assertTrue(waitForServiceResponse(mMyResponse));
+            assertTrue(mMyResponse.success);
+        });
+
+        persistentGroups = getPersistentGroups();
+        assertNotNull(persistentGroups);
+        assertEquals(0, persistentGroups.getGroupList().size());
+
+        resetResponse(mMyResponse);
+        mWifiP2pManager.createGroup(mWifiP2pChannel, mActionListener);
+        assertTrue(waitForServiceResponse(mMyResponse));
+        assertTrue(mMyResponse.success);
+        assertTrue(waitForBroadcasts(MySync.NETWORK_INFO));
+        assertNotNull(mMySync.expectedNetworkInfo);
+        assertEquals(NetworkInfo.DetailedState.CONNECTED,
+                mMySync.expectedNetworkInfo.getDetailedState());
+
+        resetResponse(mMyResponse);
+        mWifiP2pManager.removeGroup(mWifiP2pChannel, mActionListener);
+        assertTrue(waitForServiceResponse(mMyResponse));
+        assertTrue(mMyResponse.success);
+
+        resetResponse(mMyResponse);
+        ShellIdentityUtils.invokeWithShellPermissions(() -> {
+            mWifiP2pManager.factoryReset(mWifiP2pChannel, mActionListener);
+            assertTrue(waitForServiceResponse(mMyResponse));
+            assertTrue(mMyResponse.success);
+        });
+
+        persistentGroups = getPersistentGroups();
+        assertNotNull(persistentGroups);
+        assertEquals(0, persistentGroups.getGroupList().size());
+    }
+
+    public void testP2pListening() {
+        if (!setupWifiP2p()) {
+            return;
+        }
+
+        resetResponse(mMyResponse);
+        ShellIdentityUtils.invokeWithShellPermissions(() -> {
+            mWifiP2pManager.setWifiP2pChannels(mWifiP2pChannel, 6, 11, mActionListener);
+            assertTrue(waitForServiceResponse(mMyResponse));
+            assertTrue(mMyResponse.success);
+        });
+
+        resetResponse(mMyResponse);
+        ShellIdentityUtils.invokeWithShellPermissions(() -> {
+            mWifiP2pManager.startListening(mWifiP2pChannel, mActionListener);
+            assertTrue(waitForServiceResponse(mMyResponse));
+            assertTrue(mMyResponse.success);
+        });
+
+        resetResponse(mMyResponse);
+        ShellIdentityUtils.invokeWithShellPermissions(() -> {
+            mWifiP2pManager.stopListening(mWifiP2pChannel, mActionListener);
+            assertTrue(waitForServiceResponse(mMyResponse));
+            assertTrue(mMyResponse.success);
+        });
+    }
+
+    public void testP2pService() {
+        if (!setupWifiP2p()) {
+            return;
+        }
+
+        // This only store the listener to the WifiP2pManager internal variable, nothing to fail.
+        mWifiP2pManager.setServiceResponseListener(mWifiP2pChannel,
+                new WifiP2pManager.ServiceResponseListener() {
+                    @Override
+                    public void onServiceAvailable(
+                            int protocolType, byte[] responseData, WifiP2pDevice srcDevice) {
+                    }
+                });
+
+        resetResponse(mMyResponse);
+        List<String> services = new ArrayList<String>();
+        services.add("urn:schemas-upnp-org:service:AVTransport:1");
+        services.add("urn:schemas-upnp-org:service:ConnectionManager:1");
+        WifiP2pServiceInfo rendererService = WifiP2pUpnpServiceInfo.newInstance(
+                "6859dede-8574-59ab-9332-123456789011",
+                "urn:schemas-upnp-org:device:MediaRenderer:1",
+                services);
+        mWifiP2pManager.addLocalService(mWifiP2pChannel,
+                rendererService,
+                mActionListener);
+        assertTrue(waitForServiceResponse(mMyResponse));
+        assertTrue(mMyResponse.success);
+
+        resetResponse(mMyResponse);
+        mWifiP2pManager.removeLocalService(mWifiP2pChannel,
+                rendererService,
+                mActionListener);
+        assertTrue(waitForServiceResponse(mMyResponse));
+        assertTrue(mMyResponse.success);
+
+        resetResponse(mMyResponse);
+        mWifiP2pManager.clearLocalServices(mWifiP2pChannel,
+                mActionListener);
+        assertTrue(waitForServiceResponse(mMyResponse));
+        assertTrue(mMyResponse.success);
+    }
 }
diff --git a/tests/tests/net/src/android/net/wifi/cts/EasyConnectStatusCallbackTest.java b/tests/tests/net/src/android/net/wifi/cts/EasyConnectStatusCallbackTest.java
new file mode 100644
index 0000000..eef50a0
--- /dev/null
+++ b/tests/tests/net/src/android/net/wifi/cts/EasyConnectStatusCallbackTest.java
@@ -0,0 +1,170 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.net.wifi.cts;
+
+import static android.net.wifi.EasyConnectStatusCallback.EASY_CONNECT_EVENT_FAILURE_TIMEOUT;
+import static android.net.wifi.WifiConfiguration.SECURITY_TYPE_PSK;
+import static android.net.wifi.WifiManager.EASY_CONNECT_NETWORK_ROLE_STA;
+
+import android.app.UiAutomation;
+import android.content.Context;
+import android.net.wifi.EasyConnectStatusCallback;
+import android.net.wifi.WifiConfiguration;
+import android.net.wifi.WifiManager;
+import android.os.Handler;
+import android.os.HandlerExecutor;
+import android.os.HandlerThread;
+import android.test.AndroidTestCase;
+import android.util.SparseArray;
+import androidx.test.platform.app.InstrumentationRegistry;
+
+import java.util.concurrent.Executor;
+
+public class EasyConnectStatusCallbackTest extends AndroidTestCase {
+    private static final String TEST_SSID = "\"testSsid\"";
+    private static final String TEST_PASSPHRASE = "\"testPassword\"";
+    private static final int TEST_WAIT_DURATION_MS = 12_000; // Long delay is necessary, see below
+    private WifiManager mWifiManager;
+    private static final String TEST_DPP_URI =
+            "DPP:C:81/1;I:Easy_Connect_Demo;M:000102030405;"
+                    + "K:MDkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDIgACDmtXD1Sz6/5B4YRdmTkbkkFLDwk8f0yRnfm1Go"
+                    + "kpx/0=;;";
+    private final HandlerThread mHandlerThread = new HandlerThread("EasyConnectTest");
+    protected final Executor mExecutor;
+    {
+        mHandlerThread.start();
+        mExecutor = new HandlerExecutor(new Handler(mHandlerThread.getLooper()));
+    }
+    private final Object mLock = new Object();
+    private boolean mOnFailureCallback = false;
+    private int mErrorCode;
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+        if (!WifiFeature.isWifiSupported(getContext())) {
+            // skip the test if WiFi is not supported
+            return;
+        }
+
+        mWifiManager = (WifiManager) getContext().getSystemService(Context.WIFI_SERVICE);
+    }
+
+    @Override
+    protected void tearDown() throws Exception {
+        super.tearDown();
+    }
+
+    private EasyConnectStatusCallback mEasyConnectStatusCallback = new EasyConnectStatusCallback() {
+        @Override
+        public void onEnrolleeSuccess(int newNetworkId) {
+
+        }
+
+        @Override
+        public void onConfiguratorSuccess(int code) {
+
+        }
+
+        @Override
+        public void onProgress(int code) {
+
+        }
+
+        @Override
+        public void onFailure(int code) {
+            synchronized (mLock) {
+                mOnFailureCallback = true;
+                mErrorCode = code;
+                mLock.notify();
+            }
+        }
+
+        public void onFailure(int code, String ssid, SparseArray<int[]> channelListArray,
+                int[] operatingClassArray) {
+            synchronized (mLock) {
+                mOnFailureCallback = true;
+                mErrorCode = code;
+                mLock.notify();
+            }
+        }
+    };
+
+    /**
+     * Tests {@link android.net.wifi.EasyConnectStatusCallback} class.
+     *
+     * Since Easy Connect requires 2 devices, start Easy Connect session and expect an error.
+     */
+    public void testConfiguratorInitiatorOnFailure() throws Exception {
+        if (!WifiFeature.isWifiSupported(getContext())) {
+            // skip the test if WiFi is not supported
+            return;
+        }
+        UiAutomation uiAutomation = InstrumentationRegistry.getInstrumentation().getUiAutomation();
+        try {
+            uiAutomation.adoptShellPermissionIdentity();
+            WifiConfiguration config;
+            config = new WifiConfiguration();
+            config.SSID = TEST_SSID;
+            config.preSharedKey = TEST_PASSPHRASE;
+            config.setSecurityParams(SECURITY_TYPE_PSK);
+            int networkId = mWifiManager.addNetwork(config);
+            assertFalse(networkId == -1);
+            synchronized (mLock) {
+                mWifiManager.startEasyConnectAsConfiguratorInitiator(TEST_DPP_URI, networkId,
+                        EASY_CONNECT_NETWORK_ROLE_STA, mExecutor, mEasyConnectStatusCallback);
+                // Note: A long delay is necessary because there is no enrollee, and the system
+                // tries to discover it. We will wait for a timeout error to occur.
+                mLock.wait(TEST_WAIT_DURATION_MS);
+            }
+            mWifiManager.removeNetwork(networkId);
+            assertTrue(mOnFailureCallback);
+            assertEquals(EASY_CONNECT_EVENT_FAILURE_TIMEOUT, mErrorCode);
+            mWifiManager.stopEasyConnectSession();
+        } finally {
+            uiAutomation.dropShellPermissionIdentity();
+        }
+    }
+
+    /**
+     * Tests {@link android.net.wifi.EasyConnectStatusCallback} class.
+     *
+     * Since Easy Connect requires 2 devices, start Easy Connect session and expect an error.
+     */
+    public void testEnrolleeInitiatorOnFailure() throws Exception {
+        if (!WifiFeature.isWifiSupported(getContext())) {
+            // skip the test if WiFi is not supported
+            return;
+        }
+        UiAutomation uiAutomation = InstrumentationRegistry.getInstrumentation().getUiAutomation();
+        try {
+            uiAutomation.adoptShellPermissionIdentity();
+            synchronized (mLock) {
+                mWifiManager.startEasyConnectAsEnrolleeInitiator(TEST_DPP_URI, mExecutor,
+                        mEasyConnectStatusCallback);
+                // Note: A long delay is necessary because there is no configurator, and the system
+                // tries to discover it. We will wait for a timeout error to occur.
+                mLock.wait(TEST_WAIT_DURATION_MS);
+            }
+            assertTrue(mOnFailureCallback);
+            assertEquals(EASY_CONNECT_EVENT_FAILURE_TIMEOUT, mErrorCode);
+            mWifiManager.stopEasyConnectSession();
+        } finally {
+            uiAutomation.dropShellPermissionIdentity();
+        }
+    }
+}
diff --git a/tests/tests/net/src/android/net/wifi/cts/WifiFeature.java b/tests/tests/net/src/android/net/wifi/cts/WifiFeature.java
index 63fa1dd..3e9fef4 100644
--- a/tests/tests/net/src/android/net/wifi/cts/WifiFeature.java
+++ b/tests/tests/net/src/android/net/wifi/cts/WifiFeature.java
@@ -20,12 +20,12 @@
 import android.content.pm.PackageManager;
 
 public class WifiFeature {
-    static boolean isWifiSupported(Context context) {
+    public static boolean isWifiSupported(Context context) {
         PackageManager packageManager = context.getPackageManager();
         return packageManager.hasSystemFeature(PackageManager.FEATURE_WIFI);
     }
 
-    static boolean isP2pSupported(Context context) {
+    public static boolean isP2pSupported(Context context) {
         PackageManager packageManager = context.getPackageManager();
         return packageManager.hasSystemFeature(PackageManager.FEATURE_WIFI_DIRECT);
     }
diff --git a/tests/tests/net/src/android/net/wifi/cts/WifiHotspot2Test.java b/tests/tests/net/src/android/net/wifi/cts/WifiHotspot2Test.java
new file mode 100644
index 0000000..a05b81b
--- /dev/null
+++ b/tests/tests/net/src/android/net/wifi/cts/WifiHotspot2Test.java
@@ -0,0 +1,488 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.net.wifi.cts;
+
+import static android.net.wifi.WifiConfiguration.METERED_OVERRIDE_NONE;
+
+import android.net.Uri;
+import android.net.wifi.hotspot2.OsuProvider;
+import android.net.wifi.hotspot2.PasspointConfiguration;
+import android.net.wifi.hotspot2.pps.Credential;
+import android.net.wifi.hotspot2.pps.HomeSp;
+import android.test.AndroidTestCase;
+import android.text.TextUtils;
+
+import java.lang.reflect.Constructor;
+import java.security.MessageDigest;
+import java.security.NoSuchAlgorithmException;
+import java.security.PrivateKey;
+import java.security.cert.CertificateEncodingException;
+import java.security.cert.X509Certificate;
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Locale;
+import java.util.Map;
+
+public class WifiHotspot2Test extends AndroidTestCase {
+    static final int SIM_CREDENTIAL = 0;
+    static final int USER_CREDENTIAL = 1;
+    static final int CERT_CREDENTIAL = 2;
+    private static final String TEST_SSID = "TEST SSID";
+    private static final String TEST_FRIENDLY_NAME = "Friendly Name";
+    private static final Map<String, String> TEST_FRIENDLY_NAMES =
+            new HashMap<String, String>() {
+                {
+                    put("en", TEST_FRIENDLY_NAME);
+                    put("kr", TEST_FRIENDLY_NAME + 2);
+                    put("jp", TEST_FRIENDLY_NAME + 3);
+                }
+            };
+    private static final String TEST_SERVICE_DESCRIPTION = "Dummy Service";
+    private static final Uri TEST_SERVER_URI = Uri.parse("https://test.com");
+    private static final String TEST_NAI = "test.access.com";
+    private static final List<Integer> TEST_METHOD_LIST =
+            Arrays.asList(1 /* METHOD_SOAP_XML_SPP */);
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+        if (!WifiFeature.isWifiSupported(getContext())) {
+            // skip the test if WiFi is not supported
+            return;
+        }
+    }
+
+    @Override
+    protected void tearDown() throws Exception {
+        super.tearDown();
+    }
+
+    /**
+     * Tests {@link PasspointConfiguration#getMeteredOverride()} method.
+     * <p>
+     * Test default value
+     */
+    public void testGetMeteredOverride() throws Exception {
+        if (!WifiFeature.isWifiSupported(getContext())) {
+            // skip the test if WiFi is not supported
+            return;
+        }
+        PasspointConfiguration passpointConfiguration = new PasspointConfiguration();
+        assertEquals(METERED_OVERRIDE_NONE, passpointConfiguration.getMeteredOverride());
+    }
+
+    /**
+     * Tests {@link PasspointConfiguration#getSubscriptionExpirationTimeMillis()} method.
+     * <p>
+     * Test default value
+     */
+    public void testGetSubscriptionExpirationTimeMillis() throws Exception {
+        if (!WifiFeature.isWifiSupported(getContext())) {
+            // skip the test if WiFi is not supported
+            return;
+        }
+        PasspointConfiguration passpointConfiguration = new PasspointConfiguration();
+        assertEquals(Long.MIN_VALUE,
+                passpointConfiguration.getSubscriptionExpirationTimeMillis());
+    }
+
+    /**
+     * Tests {@link PasspointConfiguration#getUniqueId()} method.
+     * <p>
+     * Test unique identifier is not null
+     */
+    public void testGetUniqueId() throws Exception {
+        if (!WifiFeature.isWifiSupported(getContext())) {
+            // skip the test if WiFi is not supported
+            return;
+        }
+
+        // Create a configuration and make sure the unique ID is not null
+        PasspointConfiguration passpointConfiguration1 = createConfig(SIM_CREDENTIAL, "123456*",
+                18 /* EAP_SIM */);
+        String uniqueId1 = passpointConfiguration1.getUniqueId();
+        assertNotNull(uniqueId1);
+
+        // Create another configuration and make sure the unique ID is not null
+        PasspointConfiguration passpointConfiguration2 = createConfig(SIM_CREDENTIAL, "567890*",
+                23 /* EAP_AKA */);
+        String uniqueId2 = passpointConfiguration2.getUniqueId();
+        assertNotNull(uniqueId2);
+
+        // Make sure the IDs are not equal
+        assertFalse(uniqueId1.equals(uniqueId2));
+
+        passpointConfiguration2 = createConfig(USER_CREDENTIAL);
+        assertFalse(uniqueId1.equals(passpointConfiguration2.getUniqueId()));
+
+        passpointConfiguration2 = createConfig(CERT_CREDENTIAL);
+        assertFalse(uniqueId1.equals(passpointConfiguration2.getUniqueId()));
+    }
+
+    /**
+     * Tests {@link PasspointConfiguration#isAutojoinEnabled()} method.
+     * <p>
+     * Test default value
+     */
+    public void testIsAutojoinEnabled() throws Exception {
+        if (!WifiFeature.isWifiSupported(getContext())) {
+            // skip the test if WiFi is not supported
+            return;
+        }
+        PasspointConfiguration passpointConfiguration = new PasspointConfiguration();
+        assertTrue(passpointConfiguration.isAutojoinEnabled());
+    }
+
+    /**
+     * Tests {@link PasspointConfiguration#isMacRandomizationEnabled()} method.
+     * <p>
+     * Test default value
+     */
+    public void testIsMacRandomizationEnabled() throws Exception {
+        if (!WifiFeature.isWifiSupported(getContext())) {
+            // skip the test if WiFi is not supported
+            return;
+        }
+        PasspointConfiguration passpointConfiguration = new PasspointConfiguration();
+        assertTrue(passpointConfiguration.isMacRandomizationEnabled());
+    }
+
+    /**
+     * Tests {@link PasspointConfiguration#isOsuProvisioned()} method.
+     * <p>
+     * Test default value
+     */
+    public void testIsOsuProvisioned() throws Exception {
+        if (!WifiFeature.isWifiSupported(getContext())) {
+            // skip the test if WiFi is not supported
+            return;
+        }
+        PasspointConfiguration passpointConfiguration = createConfig(USER_CREDENTIAL);
+        assertFalse(passpointConfiguration.isOsuProvisioned());
+    }
+
+    /**
+     * Tests {@link PasspointConfiguration#PasspointConfiguration(PasspointConfiguration)} method.
+     * <p>
+     * Test the PasspointConfiguration copy constructor
+     */
+    public void testPasspointConfigurationCopyConstructor() throws Exception {
+        if (!WifiFeature.isWifiSupported(getContext())) {
+            // skip the test if WiFi is not supported
+            return;
+        }
+        PasspointConfiguration passpointConfiguration = createConfig(USER_CREDENTIAL);
+        PasspointConfiguration copyOfPasspointConfiguration =
+                new PasspointConfiguration(passpointConfiguration);
+        assertEquals(passpointConfiguration, copyOfPasspointConfiguration);
+    }
+
+    /**
+     * Tests {@link HomeSp#HomeSp(HomeSp)} method.
+     * <p>
+     * Test the HomeSp copy constructor
+     */
+    public void testHomeSpCopyConstructor() throws Exception {
+        if (!WifiFeature.isWifiSupported(getContext())) {
+            // skip the test if WiFi is not supported
+            return;
+        }
+        HomeSp homeSp = createHomeSp();
+        HomeSp copyOfHomeSp = new HomeSp(homeSp);
+        assertEquals(copyOfHomeSp, homeSp);
+    }
+
+    /**
+     * Tests {@link Credential#Credential(Credential)} method.
+     * <p>
+     * Test the Credential copy constructor
+     */
+    public void testCredentialCopyConstructor() throws Exception {
+        if (!WifiFeature.isWifiSupported(getContext())) {
+            // skip the test if WiFi is not supported
+            return;
+        }
+        Credential credential = createCredentialWithSimCredential("123456*", 18 /* EAP_SIM */);
+        Credential copyOfCredential = new Credential(credential);
+        assertEquals(copyOfCredential, credential);
+    }
+
+    /**
+     * Tests {@link Credential.UserCredential#UserCredential(Credential.UserCredential)} method.
+     * <p>
+     * Test the Credential.UserCredential copy constructor
+     */
+    public void testUserCredentialCopyConstructor() throws Exception {
+        if (!WifiFeature.isWifiSupported(getContext())) {
+            // skip the test if WiFi is not supported
+            return;
+        }
+        Credential.UserCredential userCredential = new Credential.UserCredential();
+        userCredential.setUsername("username");
+        userCredential.setPassword("password");
+        userCredential.setEapType(21 /* EAP_TTLS */);
+        userCredential.setNonEapInnerMethod("MS-CHAP");
+
+        Credential.UserCredential copyOfUserCredential =
+                new Credential.UserCredential(userCredential);
+        assertEquals(copyOfUserCredential, userCredential);
+    }
+
+    /**
+     * Tests
+     * {@link Credential.CertificateCredential#CertificateCredential(Credential.CertificateCredential)}
+     * method.
+     * <p>
+     * Test the Credential.CertificateCredential copy constructor
+     */
+    public void testCertCredentialCopyConstructor() throws Exception {
+        if (!WifiFeature.isWifiSupported(getContext())) {
+            // skip the test if WiFi is not supported
+            return;
+        }
+        Credential.CertificateCredential certCredential = new Credential.CertificateCredential();
+        certCredential.setCertType("x509v3");
+
+        Credential.CertificateCredential copyOfCertificateCredential =
+                new Credential.CertificateCredential(certCredential);
+        assertEquals(copyOfCertificateCredential, certCredential);
+    }
+
+    /**
+     * Tests {@link Credential.SimCredential#SimCredential(Credential.SimCredential)} method.
+     * <p>
+     * Test the Credential.SimCredential copy constructor
+     */
+    public void testSimCredentialCopyConstructor() throws Exception {
+        if (!WifiFeature.isWifiSupported(getContext())) {
+            // skip the test if WiFi is not supported
+            return;
+        }
+        Credential.SimCredential simCredential = new Credential.SimCredential();
+        simCredential.setImsi("1234*");
+        simCredential.setEapType(18/* EAP_SIM */);
+
+        Credential.SimCredential copyOfSimCredential = new Credential.SimCredential(simCredential);
+        assertEquals(copyOfSimCredential, simCredential);
+    }
+
+    /**
+     * Tests {@link Credential#getCaCertificate()}  method.
+     * <p>
+     * Test that getting a set certificate produces the same value
+     */
+    public void testCredentialGetCertificate() throws Exception {
+        if (!WifiFeature.isWifiSupported(getContext())) {
+            // skip the test if WiFi is not supported
+            return;
+        }
+        Credential credential = new Credential();
+        credential.setCaCertificate(FakeKeys.CA_CERT0);
+
+        assertEquals(FakeKeys.CA_CERT0, credential.getCaCertificate());
+    }
+
+    /**
+     * Tests {@link Credential#getClientCertificateChain()} and {@link
+     * Credential#setCaCertificates(X509Certificate[])} methods.
+     * <p>
+     * Test that getting a set client certificate chain produces the same value
+     */
+    public void testCredentialClientCertificateChain() throws Exception {
+        if (!WifiFeature.isWifiSupported(getContext())) {
+            // skip the test if WiFi is not supported
+            return;
+        }
+        Credential credential = new Credential();
+        X509Certificate[] certificates = new X509Certificate[]{FakeKeys.CLIENT_CERT};
+        credential.setClientCertificateChain(certificates);
+
+        assertTrue(Arrays.equals(certificates, credential.getClientCertificateChain()));
+    }
+
+    /**
+     * Tests {@link Credential#getClientPrivateKey()} and
+     * {@link Credential#setClientPrivateKey(PrivateKey)}
+     * methods.
+     * <p>
+     * Test that getting a set client private key produces the same value
+     */
+    public void testCredentialSetGetClientPrivateKey() throws Exception {
+        if (!WifiFeature.isWifiSupported(getContext())) {
+            // skip the test if WiFi is not supported
+            return;
+        }
+        Credential credential = new Credential();
+        credential.setClientPrivateKey(FakeKeys.RSA_KEY1);
+
+        assertEquals(FakeKeys.RSA_KEY1, credential.getClientPrivateKey());
+    }
+
+    /**
+     * Tests {@link Credential#getClientPrivateKey()} and
+     * {@link Credential#setClientPrivateKey(PrivateKey)}
+     * methods.
+     * <p>
+     * Test that getting a set client private key produces the same value
+     */
+    public void testCredentialGetClientPrivateKey() throws Exception {
+        if (!WifiFeature.isWifiSupported(getContext())) {
+            // skip the test if WiFi is not supported
+            return;
+        }
+        Credential credential = new Credential();
+        credential.setClientPrivateKey(FakeKeys.RSA_KEY1);
+
+        assertEquals(FakeKeys.RSA_KEY1, credential.getClientPrivateKey());
+    }
+
+    private static PasspointConfiguration createConfig(int type) throws Exception {
+        return createConfig(type, "123456*", 18 /* EAP_SIM */);
+    }
+
+    private static PasspointConfiguration createConfig(int type, String imsi, int eapType)
+            throws Exception {
+        PasspointConfiguration config = new PasspointConfiguration();
+        config.setHomeSp(createHomeSp());
+        switch (type) {
+            default:
+            case SIM_CREDENTIAL:
+                config.setCredential(
+                        createCredentialWithSimCredential(imsi, eapType));
+                break;
+            case USER_CREDENTIAL:
+                config.setCredential(createCredentialWithUserCredential());
+                break;
+            case CERT_CREDENTIAL:
+                config.setCredential(createCredentialWithCertificateCredential());
+                break;
+        }
+
+        return config;
+    }
+
+    /**
+     * Helper function for generating HomeSp for testing.
+     *
+     * @return {@link HomeSp}
+     */
+    private static HomeSp createHomeSp() {
+        HomeSp homeSp = new HomeSp();
+        homeSp.setFqdn("test.com");
+        homeSp.setFriendlyName("friendly name");
+        homeSp.setRoamingConsortiumOis(new long[]{0x55, 0x66});
+        return homeSp;
+    }
+
+    /**
+     * Helper function for generating Credential for testing.
+     *
+     * @param userCred               Instance of UserCredential
+     * @param certCred               Instance of CertificateCredential
+     * @param simCred                Instance of SimCredential
+     * @param clientCertificateChain Chain of client certificates
+     * @param clientPrivateKey       Client private key
+     * @param caCerts                CA certificates
+     * @return {@link Credential}
+     */
+    private static Credential createCredential(Credential.UserCredential userCred,
+            Credential.CertificateCredential certCred,
+            Credential.SimCredential simCred,
+            X509Certificate[] clientCertificateChain, PrivateKey clientPrivateKey,
+            X509Certificate... caCerts) {
+        Credential cred = new Credential();
+        cred.setRealm("realm");
+        cred.setUserCredential(userCred);
+        cred.setCertCredential(certCred);
+        cred.setSimCredential(simCred);
+        return cred;
+    }
+
+    /**
+     * Helper function for generating certificate credential for testing.
+     *
+     * @return {@link Credential}
+     */
+    private static Credential createCredentialWithCertificateCredential()
+            throws NoSuchAlgorithmException, CertificateEncodingException {
+        Credential.CertificateCredential certCred = new Credential.CertificateCredential();
+        certCred.setCertType("x509v3");
+        certCred.setCertSha256Fingerprint(
+                MessageDigest.getInstance("SHA-256").digest(
+                        FakeKeys.CLIENT_CERT.getEncoded()));
+        return createCredential(null, certCred, null, new X509Certificate[]{
+                        FakeKeys.CLIENT_CERT},
+                FakeKeys.RSA_KEY1, FakeKeys.CA_CERT0,
+                FakeKeys.CA_CERT1);
+    }
+
+    /**
+     * Helper function for generating SIM credential for testing.
+     *
+     * @return {@link Credential}
+     */
+    private static Credential createCredentialWithSimCredential(String imsi, int eapType) {
+        Credential.SimCredential simCred = new Credential.SimCredential();
+        simCred.setImsi(imsi);
+        simCred.setEapType(eapType);
+        return createCredential(null, null, simCred, null, null, (X509Certificate[]) null);
+    }
+
+    /**
+     * Helper function for generating user credential for testing.
+     *
+     * @return {@link Credential}
+     */
+    private static Credential createCredentialWithUserCredential() {
+        Credential.UserCredential userCred = new Credential.UserCredential();
+        userCred.setUsername("username");
+        userCred.setPassword("password");
+        userCred.setEapType(21 /* EAP_TTLS */);
+        userCred.setNonEapInnerMethod("MS-CHAP");
+        return createCredential(userCred, null, null, null, null,
+                FakeKeys.CA_CERT0);
+    }
+
+    /**
+     * Tests {@link OsuProvider#getFriendlyName()} and {@link OsuProvider#getServerUri()} methods.
+     * <p>
+     * Test that getting a set friendly name and server URI produces the same value
+     */
+    public void testOsuProviderGetters() throws Exception {
+        if (!WifiFeature.isWifiSupported(getContext())) {
+            // skip the test if WiFi is not supported
+            return;
+        }
+
+        // Using Java reflection to construct an OsuProvider instance because its constructor is
+        // hidden and not available to apps.
+        Class<?> osuProviderClass = Class.forName("android.net.wifi.hotspot2.OsuProvider");
+        Constructor<?> osuProviderClassConstructor = osuProviderClass.getConstructor(String.class,
+                Map.class, String.class, Uri.class, String.class, List.class);
+
+        OsuProvider osuProvider = (OsuProvider) osuProviderClassConstructor.newInstance(TEST_SSID,
+                TEST_FRIENDLY_NAMES, TEST_SERVICE_DESCRIPTION, TEST_SERVER_URI, TEST_NAI,
+                TEST_METHOD_LIST);
+        String lang = Locale.getDefault().getLanguage();
+        String friendlyName = TEST_FRIENDLY_NAMES.get(lang);
+        if (TextUtils.isEmpty(friendlyName)) {
+            friendlyName = TEST_FRIENDLY_NAMES.get("en");
+        }
+        assertEquals(friendlyName, osuProvider.getFriendlyName());
+        assertEquals(TEST_SERVER_URI, osuProvider.getServerUri());
+    }
+}
diff --git a/tests/tests/net/src/android/net/wifi/cts/WifiLockTest.java b/tests/tests/net/src/android/net/wifi/cts/WifiLockTest.java
index 6ac92d4..fee9ef0 100644
--- a/tests/tests/net/src/android/net/wifi/cts/WifiLockTest.java
+++ b/tests/tests/net/src/android/net/wifi/cts/WifiLockTest.java
@@ -19,6 +19,7 @@
 import android.content.Context;
 import android.net.wifi.WifiManager;
 import android.net.wifi.WifiManager.WifiLock;
+import android.os.WorkSource;
 import android.platform.test.annotations.AppModeFull;
 import android.test.AndroidTestCase;
 
@@ -50,6 +51,7 @@
         WifiLock wl = wm.createWifiLock(lockType, WIFI_TAG);
 
         wl.setReferenceCounted(true);
+        wl.setWorkSource(new WorkSource());
         assertFalse(wl.isHeld());
         wl.acquire();
         assertTrue(wl.isHeld());
diff --git a/tests/tests/net/src/android/net/wifi/cts/WifiManagerTest.java b/tests/tests/net/src/android/net/wifi/cts/WifiManagerTest.java
index 9d36493..51a4f32 100644
--- a/tests/tests/net/src/android/net/wifi/cts/WifiManagerTest.java
+++ b/tests/tests/net/src/android/net/wifi/cts/WifiManagerTest.java
@@ -32,6 +32,7 @@
 import android.content.pm.PackageInfo;
 import android.content.pm.PackageManager;
 import android.content.pm.ResolveInfo;
+import android.net.util.MacAddressUtils;
 import android.net.ConnectivityManager;
 import android.net.LinkProperties;
 import android.net.MacAddress;
@@ -39,11 +40,21 @@
 import android.net.NetworkCapabilities;
 import android.net.NetworkInfo;
 import android.net.NetworkRequest;
+import android.net.TetheringManager;
 import android.net.wifi.ScanResult;
+import android.net.wifi.SoftApCapability;
 import android.net.wifi.SoftApConfiguration;
+import android.net.wifi.SoftApInfo;
+import android.net.wifi.WifiClient;
 import android.net.wifi.WifiConfiguration;
+import android.net.wifi.WifiInfo;
 import android.net.wifi.WifiManager;
 import android.net.wifi.WifiManager.WifiLock;
+import android.net.wifi.WifiNetworkConnectionStatistics;
+import android.net.wifi.hotspot2.ConfigParser;
+import android.net.wifi.hotspot2.PasspointConfiguration;
+import android.net.wifi.hotspot2.pps.Credential;
+import android.net.wifi.hotspot2.pps.HomeSp;
 import android.os.Process;
 import android.os.SystemClock;
 import android.os.UserHandle;
@@ -61,12 +72,19 @@
 import com.android.compatibility.common.util.PollingCheck;
 import com.android.compatibility.common.util.ShellIdentityUtils;
 import com.android.compatibility.common.util.SystemUtil;
+import com.android.compatibility.common.util.ThrowingRunnable;
 
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
 import java.net.HttpURLConnection;
 import java.net.URL;
+import java.util.ArrayList;
 import java.util.List;
 import java.util.Locale;
 import java.util.Objects;
+import java.util.concurrent.Callable;
 import java.util.concurrent.ConcurrentLinkedQueue;
 import java.util.concurrent.Executor;
 import java.util.concurrent.Executors;
@@ -81,6 +99,7 @@
 
     private WifiManager mWifiManager;
     private ConnectivityManager mConnectivityManager;
+    private TetheringManager mTetheringManager;
     private WifiLock mWifiLock;
     private static MySync mMySync;
     private List<ScanResult> mScanResults = null;
@@ -88,6 +107,7 @@
     private final Object mLock = new Object();
     private UiDevice mUiDevice;
     private boolean mWasVerboseLoggingEnabled;
+    private SoftApConfiguration mOriginalSoftApConfig = null;
 
     // Please refer to WifiManager
     private static final int MIN_RSSI = -100;
@@ -124,6 +144,9 @@
     private static final String TEST_SSID_UNQUOTED = "testSsid1";
     private static final MacAddress TEST_MAC = MacAddress.fromString("aa:bb:cc:dd:ee:ff");
     private static final String TEST_PASSPHRASE = "passphrase";
+    private static final String PASSPOINT_INSTALLATION_FILE_WITH_CA_CERT =
+            "assets/ValidPasspointProfile.base64";
+    private static final String TYPE_WIFI_CONFIG = "application/x-wifi-config";
 
     private IntentFilter mIntentFilter;
     private final BroadcastReceiver mReceiver = new BroadcastReceiver() {
@@ -187,7 +210,9 @@
         mContext.registerReceiver(mReceiver, mIntentFilter);
         mWifiManager = (WifiManager) getContext().getSystemService(Context.WIFI_SERVICE);
         mConnectivityManager = getContext().getSystemService(ConnectivityManager.class);
+        mTetheringManager = getContext().getSystemService(TetheringManager.class);
         assertNotNull(mWifiManager);
+        assertNotNull(mTetheringManager);
 
         // turn on verbose logging for tests
         mWasVerboseLoggingEnabled = ShellIdentityUtils.invokeWithShellPermissions(
@@ -210,6 +235,10 @@
         List<WifiConfiguration> savedNetworks = ShellIdentityUtils.invokeWithShellPermissions(
                 mWifiManager::getConfiguredNetworks);
         assertFalse("Need at least one saved network", savedNetworks.isEmpty());
+
+        // Get original config for restore
+        mOriginalSoftApConfig = ShellIdentityUtils.invokeWithShellPermissions(
+                mWifiManager::getSoftApConfiguration);
     }
 
     @Override
@@ -225,6 +254,9 @@
         mContext.unregisterReceiver(mReceiver);
         ShellIdentityUtils.invokeWithShellPermissions(
                 () -> mWifiManager.setVerboseLoggingEnabled(mWasVerboseLoggingEnabled));
+        // restore original softap config
+        ShellIdentityUtils.invokeWithShellPermissions(
+                () -> mWifiManager.setSoftApConfiguration(mOriginalSoftApConfig));
         Thread.sleep(DURATION);
         super.tearDown();
     }
@@ -494,6 +526,140 @@
         }
     }
 
+    public class TestSoftApCallback implements WifiManager.SoftApCallback {
+        Object softApLock;
+        int currentState;
+        int currentFailureReason;
+        List<WifiClient> currentClientList;
+        SoftApInfo currentSoftApInfo;
+        SoftApCapability currentSoftApCapability;
+        MacAddress lastBlockedClientMacAddress;
+        int lastBlockedClientReason;
+        boolean onStateChangedCalled = false;
+        boolean onSoftapInfoChangedCalled = false;
+        boolean onSoftApCapabilityChangedCalled = false;
+        boolean onConnectedClientCalled = false;
+        boolean onBlockedClientConnectingCalled = false;
+
+        TestSoftApCallback(Object lock) {
+            softApLock = lock;
+        }
+
+        public boolean getOnStateChangedCalled() {
+            synchronized(softApLock) {
+                return onStateChangedCalled;
+            }
+        }
+
+        public boolean getOnSoftapInfoChangedCalled() {
+            synchronized(softApLock) {
+                return onSoftapInfoChangedCalled;
+            }
+        }
+
+        public boolean getOnSoftApCapabilityChangedCalled() {
+            synchronized(softApLock) {
+                return onSoftApCapabilityChangedCalled;
+            }
+        }
+
+        public boolean getOnConnectedClientCalled() {
+            synchronized(softApLock) {
+                return onConnectedClientCalled;
+            }
+        }
+
+        public boolean getOnBlockedClientConnectingCalled() {
+            synchronized(softApLock) {
+                return onBlockedClientConnectingCalled;
+            }
+        }
+
+        public int getCurrentState() {
+            synchronized(softApLock) {
+                return currentState;
+            }
+        }
+
+        public int getCurrentStateFailureReason() {
+            synchronized(softApLock) {
+                return currentFailureReason;
+            }
+        }
+
+        public List<WifiClient> getCurrentClientList() {
+            synchronized(softApLock) {
+                return currentClientList;
+            }
+        }
+
+        public SoftApInfo getCurrentSoftApInfo() {
+            synchronized(softApLock) {
+                return currentSoftApInfo;
+            }
+        }
+
+        public SoftApCapability getCurrentSoftApCapability() {
+            synchronized(softApLock) {
+                return currentSoftApCapability;
+            }
+        }
+
+        public MacAddress getLastBlockedClientMacAddress() {
+            synchronized(softApLock) {
+                return lastBlockedClientMacAddress;
+            }
+        }
+
+        public int getLastBlockedClientReason() {
+            synchronized(softApLock) {
+                return lastBlockedClientReason;
+            }
+        }
+
+        @Override
+        public void onStateChanged(int state, int failureReason) {
+            synchronized(softApLock) {
+                currentState = state;
+                currentFailureReason = failureReason;
+                onStateChangedCalled = true;
+            }
+        }
+
+        @Override
+        public void onConnectedClientsChanged(List<WifiClient> clients) {
+            synchronized(softApLock) {
+                currentClientList = new ArrayList<>(clients);
+                onConnectedClientCalled = true;
+            }
+        }
+
+        @Override
+        public void onInfoChanged(SoftApInfo softApInfo) {
+            synchronized(softApLock) {
+                currentSoftApInfo = softApInfo;
+                onSoftapInfoChangedCalled = true;
+            }
+        }
+
+        @Override
+        public void onCapabilityChanged(SoftApCapability softApCapability) {
+            synchronized(softApLock) {
+                currentSoftApCapability = softApCapability;
+                onSoftApCapabilityChangedCalled = true;
+            }
+        }
+
+        @Override
+        public void onBlockedClientConnecting(WifiClient client, int blockedReason) {
+            synchronized(softApLock) {
+                lastBlockedClientMacAddress = client.getMacAddress();
+                lastBlockedClientReason = blockedReason;
+                onBlockedClientConnectingCalled = true;
+            }
+        }
+    }
+
     private static class TestLocalOnlyHotspotCallback extends WifiManager.LocalOnlyHotspotCallback {
         Object hotspotLock;
         WifiManager.LocalOnlyHotspotReservation reservation = null;
@@ -549,7 +715,10 @@
             }
             // check if we got the callback
             assertTrue(callback.onStartedCalled);
-            assertNotNull(callback.reservation.getSoftApConfiguration());
+
+            SoftApConfiguration softApConfig = callback.reservation.getSoftApConfiguration();
+            assertNotNull(softApConfig);
+            assertNotNull(softApConfig.toWifiConfiguration());
             if (!hasAutomotiveFeature()) {
                 assertEquals(
                         SoftApConfiguration.BAND_2GHZ,
@@ -742,6 +911,51 @@
     }
 
     /**
+     * Read the content of the given resource file into a String.
+     *
+     * @param filename String name of the file
+     * @return String
+     * @throws IOException
+     */
+    private String loadResourceFile(String filename) throws IOException {
+        InputStream in = getClass().getClassLoader().getResourceAsStream(filename);
+        BufferedReader reader = new BufferedReader(new InputStreamReader(in));
+        StringBuilder builder = new StringBuilder();
+        String line;
+        while ((line = reader.readLine()) != null) {
+            builder.append(line).append("\n");
+        }
+        return builder.toString();
+    }
+
+    /**
+     * Verify that changing the mac randomization setting of a Passpoint configuration.
+     */
+    public void testMacRandomizationSettingPasspoint() throws Exception {
+        String configStr = loadResourceFile(PASSPOINT_INSTALLATION_FILE_WITH_CA_CERT);
+        PasspointConfiguration config =
+                ConfigParser.parsePasspointConfig(TYPE_WIFI_CONFIG, configStr.getBytes());
+        UiAutomation uiAutomation = InstrumentationRegistry.getInstrumentation().getUiAutomation();
+        try {
+            uiAutomation.adoptShellPermissionIdentity();
+
+            mWifiManager.addOrUpdatePasspointConfiguration(config);
+            List<PasspointConfiguration> passpointConfigs =
+                    mWifiManager.getPasspointConfigurations();
+            PasspointConfiguration passpointConfig = passpointConfigs.get(0);
+            assertEquals(1, passpointConfigs.size());
+            assertTrue("Mac randomization should be enabled for passpoint networks by default.",
+                    passpointConfig.isMacRandomizationEnabled());
+
+            String fqdn = passpointConfig.getHomeSp().getFqdn();
+            mWifiManager.setMacRandomizationSettingPasspointEnabled(fqdn, false);
+            assertFalse("Mac randomization should be disabled by the API call.",
+                    mWifiManager.getPasspointConfigurations().get(0).isMacRandomizationEnabled());
+        } finally {
+            uiAutomation.dropShellPermissionIdentity();
+        }
+    }
+    /**
      * Verify that the {@link android.Manifest.permission#NETWORK_STACK} permission is never held by
      * any package.
      * <p>
@@ -1010,6 +1224,23 @@
         }
     }
 
+    private void runWithScanningEnabled(ThrowingRunnable r) throws Exception {
+        boolean wasScanEnabledForTest = false;
+        if (!mWifiManager.isScanAlwaysAvailable()) {
+            ShellIdentityUtils.invokeWithShellPermissions(
+                    () -> mWifiManager.setScanAlwaysAvailable(true));
+            wasScanEnabledForTest = true;
+        }
+        try {
+            r.run();
+        } finally {
+            if (wasScanEnabledForTest) {
+                ShellIdentityUtils.invokeWithShellPermissions(
+                        () -> mWifiManager.setScanAlwaysAvailable(false));
+            }
+        }
+    }
+
     /**
      * Verify that Wi-Fi scanning is not turned off when the screen turns off while wifi is disabled
      * but location is on.
@@ -1028,17 +1259,16 @@
             fail("Please enable location for this test - since Marshmallow WiFi scan results are"
                     + " empty when location is disabled!");
         }
-        if(!mWifiManager.isScanAlwaysAvailable()) {
-            fail("Please enable Wi-Fi scanning for this test!");
-        }
-        setWifiEnabled(false);
-        turnScreenOn();
-        assertWifiScanningIsOn();
-        // Toggle screen and verify Wi-Fi scanning is still on.
-        turnScreenOff();
-        assertWifiScanningIsOn();
-        turnScreenOn();
-        assertWifiScanningIsOn();
+        runWithScanningEnabled(() -> {
+            setWifiEnabled(false);
+            turnScreenOn();
+            assertWifiScanningIsOn();
+            // Toggle screen and verify Wi-Fi scanning is still on.
+            turnScreenOff();
+            assertWifiScanningIsOn();
+            turnScreenOn();
+            assertWifiScanningIsOn();
+        });
     }
 
     /**
@@ -1058,17 +1288,16 @@
             fail("Please enable location for this test - since Marshmallow WiFi scan results are"
                     + " empty when location is disabled!");
         }
-        if(!mWifiManager.isScanAlwaysAvailable()) {
-            fail("Please enable Wi-Fi scanning for this test!");
-        }
-        setWifiEnabled(true);
-        turnScreenOn();
-        assertWifiScanningIsOn();
-        // Toggle screen and verify Wi-Fi scanning is still on.
-        turnScreenOff();
-        assertWifiScanningIsOn();
-        turnScreenOn();
-        assertWifiScanningIsOn();
+        runWithScanningEnabled(() -> {
+            setWifiEnabled(true);
+            turnScreenOn();
+            assertWifiScanningIsOn();
+            // Toggle screen and verify Wi-Fi scanning is still on.
+            turnScreenOff();
+            assertWifiScanningIsOn();
+            turnScreenOn();
+            assertWifiScanningIsOn();
+        });
     }
 
     /**
@@ -1084,6 +1313,178 @@
                 > ENFORCED_NUM_NETWORK_SUGGESTIONS_PER_APP);
     }
 
+    private void verifyRegisterSoftApCallback(TestExecutor executor, TestSoftApCallback callback)
+            throws Exception{
+        // Register callback to get SoftApCapability
+        mWifiManager.registerSoftApCallback(executor, callback);
+        PollingCheck.check(
+                "SoftAp register failed!", 1_000,
+                () -> { executor.runAll();
+                // Verify callback is run on the supplied executor and called
+                return callback.getOnStateChangedCalled() &&
+                callback.getOnSoftapInfoChangedCalled() &&
+                callback.getOnSoftApCapabilityChangedCalled() &&
+                callback.getOnConnectedClientCalled();
+                });
+    }
+
+    private void verifySetGetSoftApConfig(SoftApConfiguration targetConfig) {
+        mWifiManager.setSoftApConfiguration(targetConfig);
+        // Bssid set dodesn't support for tethered hotspot
+        SoftApConfiguration currentConfig = mWifiManager.getSoftApConfiguration();
+        assertNull(currentConfig.getBssid());
+        compareSoftApConfiguration(targetConfig, currentConfig);
+    }
+
+    private void compareSoftApConfiguration(SoftApConfiguration currentConfig,
+        SoftApConfiguration testSoftApConfig) {
+        assertEquals(currentConfig.getSsid(), testSoftApConfig.getSsid());
+        assertEquals(currentConfig.getSecurityType(), testSoftApConfig.getSecurityType());
+        assertEquals(currentConfig.getPassphrase(), testSoftApConfig.getPassphrase());
+        assertEquals(currentConfig.isHiddenSsid(), testSoftApConfig.isHiddenSsid());
+        assertEquals(currentConfig.getBand(), testSoftApConfig.getBand());
+        assertEquals(currentConfig.getChannel(), testSoftApConfig.getChannel());
+        assertEquals(currentConfig.getMaxNumberOfClients(),
+                testSoftApConfig.getMaxNumberOfClients());
+        assertEquals(currentConfig.isAutoShutdownEnabled(),
+                testSoftApConfig.isAutoShutdownEnabled());
+        assertEquals(currentConfig.getShutdownTimeoutMillis(),
+                testSoftApConfig.getShutdownTimeoutMillis());
+        assertEquals(currentConfig.isClientControlByUserEnabled(),
+                testSoftApConfig.isClientControlByUserEnabled());
+        assertEquals(currentConfig.getAllowedClientList(),
+                testSoftApConfig.getAllowedClientList());
+        assertEquals(currentConfig.getBlockedClientList(),
+                testSoftApConfig.getBlockedClientList());
+    }
+
+    private void turnOffWifiAndTetheredHotspotIfEnabled() throws Exception {
+        if (mWifiManager.isWifiEnabled()) {
+            Log.d(TAG, "Turn off WiFi");
+            mWifiManager.setWifiEnabled(false);
+            PollingCheck.check(
+                "Wifi turn off failed!", 2_000,
+                () -> mWifiManager.isWifiEnabled() == false);
+        }
+        if (mWifiManager.isWifiApEnabled()) {
+            mTetheringManager.stopTethering(ConnectivityManager.TETHERING_WIFI);
+            Log.d(TAG, "Turn off tethered Hotspot");
+            PollingCheck.check(
+                "SoftAp turn off failed!", 2_000,
+                () -> mWifiManager.isWifiApEnabled() == false);
+            mTetheringManager.stopTethering(ConnectivityManager.TETHERING_WIFI);
+        }
+    }
+
+    /**
+     * Verify that the configuration from getSoftApConfiguration is same as the configuration which
+     * set by setSoftApConfiguration. And depends softap capability callback to test different
+     * configuration.
+     * @throws Exception
+     */
+    public void testSetGetSoftApConfigurationAndSoftApCapabilityCallback() throws Exception {
+        UiAutomation uiAutomation = InstrumentationRegistry.getInstrumentation().getUiAutomation();
+        try {
+            uiAutomation.adoptShellPermissionIdentity();
+            turnOffWifiAndTetheredHotspotIfEnabled();
+            TestExecutor executor = new TestExecutor();
+            TestSoftApCallback callback = new TestSoftApCallback(mLock);
+            verifyRegisterSoftApCallback(executor, callback);
+
+            SoftApConfiguration.Builder softApConfigBuilder = new SoftApConfiguration.Builder()
+                    .setSsid(TEST_SSID_UNQUOTED)
+                    .setBssid(TEST_MAC)
+                    .setPassphrase(TEST_PASSPHRASE, SoftApConfiguration.SECURITY_TYPE_WPA2_PSK)
+                    .setAutoShutdownEnabled(true)
+                    .setShutdownTimeoutMillis(100000)
+                    .setBand(SoftApConfiguration.BAND_2GHZ | SoftApConfiguration.BAND_5GHZ)
+                    .setHiddenSsid(false);
+
+            // Test SoftApConfiguration set and get
+            verifySetGetSoftApConfig(softApConfigBuilder.build());
+
+            // Test CLIENT_FORCE_DISCONNECT supported config.
+            if (callback.getCurrentSoftApCapability()
+                    .areFeaturesSupported(
+                    SoftApCapability.SOFTAP_FEATURE_CLIENT_FORCE_DISCONNECT)) {
+                softApConfigBuilder.setMaxNumberOfClients(10);
+                softApConfigBuilder.setClientControlByUserEnabled(true);
+                softApConfigBuilder.setBlockedClientList(new ArrayList<>());
+                softApConfigBuilder.setAllowedClientList(new ArrayList<>());
+                verifySetGetSoftApConfig(softApConfigBuilder.build());
+            }
+
+            // Test SAE config
+            if (callback.getCurrentSoftApCapability()
+                    .areFeaturesSupported(SoftApCapability.SOFTAP_FEATURE_WPA3_SAE)) {
+                softApConfigBuilder
+                        .setPassphrase(TEST_PASSPHRASE,
+                          SoftApConfiguration.SECURITY_TYPE_WPA3_SAE_TRANSITION);
+                verifySetGetSoftApConfig(softApConfigBuilder.build());
+                softApConfigBuilder
+                        .setPassphrase(TEST_PASSPHRASE,
+                        SoftApConfiguration.SECURITY_TYPE_WPA3_SAE);
+                verifySetGetSoftApConfig(softApConfigBuilder.build());
+            }
+        } finally {
+            uiAutomation.dropShellPermissionIdentity();
+        }
+    }
+
+    /**
+     * Verify that startTetheredHotspot with specific channel config.
+     * @throws Exception
+     */
+    public void testStartTetheredHotspotWithChannelConfigAndSoftApStateAndInfoCallback()
+            throws Exception {
+        UiAutomation uiAutomation = InstrumentationRegistry.getInstrumentation().getUiAutomation();
+        try {
+            uiAutomation.adoptShellPermissionIdentity();
+            turnOffWifiAndTetheredHotspotIfEnabled();
+            TestExecutor executor = new TestExecutor();
+            TestSoftApCallback callback = new TestSoftApCallback(mLock);
+            verifyRegisterSoftApCallback(executor, callback);
+
+            SoftApConfiguration testSoftApConfig = new SoftApConfiguration.Builder()
+                    .setSsid(TEST_SSID_UNQUOTED)
+                    .setPassphrase(TEST_PASSPHRASE, SoftApConfiguration.SECURITY_TYPE_WPA2_PSK)
+                    .setChannel(11, SoftApConfiguration.BAND_2GHZ) // Channel 11 = Freq 2462
+                    .build();
+
+            mWifiManager.setSoftApConfiguration(testSoftApConfig);
+
+            // start tethering which used to verify startTetheredHotspot
+            mTetheringManager.startTethering(ConnectivityManager.TETHERING_WIFI, executor,
+                new TetheringManager.StartTetheringCallback() {
+                    @Override
+                    public void onTetheringFailed(final int result) {
+                    }
+                });
+
+            // Verify state and info callback value as expected
+            PollingCheck.check(
+                    "SoftAp channel and state mismatch!!!", 5_000,
+                    () -> { executor.runAll();
+                    return WifiManager.WIFI_AP_STATE_ENABLED == callback.getCurrentState() &&
+                    2462 == callback.getCurrentSoftApInfo().getFrequency();
+                    });
+
+            // stop tethering which used to verify stopSoftAp
+            mTetheringManager.stopTethering(ConnectivityManager.TETHERING_WIFI);
+
+            // Verify clean up
+            PollingCheck.check(
+                    "Stop Softap failed", 2_000,
+                    () -> { executor.runAll();
+                    return WifiManager.WIFI_AP_STATE_DISABLED == callback.getCurrentState() &&
+                    0 == callback.getCurrentSoftApInfo().getBandwidth() &&
+                    0 == callback.getCurrentSoftApInfo().getFrequency();
+                    });
+        } finally {
+            uiAutomation.dropShellPermissionIdentity();
+        }
+    }
+
     private static class TestActionListener implements WifiManager.ActionListener {
         private final Object mLock;
         public boolean onSuccessCalled = false;
@@ -1337,6 +1738,106 @@
         }
     }
 
+    /**
+     * Tests {@link WifiManager#getFactoryMacAddresses()} returns at least one valid MAC address.
+     */
+    public void testGetFactoryMacAddresses() throws Exception {
+        if (!WifiFeature.isWifiSupported(getContext())) {
+            // skip the test if WiFi is not supported
+            return;
+        }
+        TestActionListener actionListener = new TestActionListener(mLock);
+        UiAutomation uiAutomation = InstrumentationRegistry.getInstrumentation().getUiAutomation();
+        int newNetworkId = INVALID_NETWORK_ID;
+        try {
+            uiAutomation.adoptShellPermissionIdentity();
+            // Obtain the factory MAC address
+            String[] macAddresses = mWifiManager.getFactoryMacAddresses();
+            assertTrue("At list one MAC address should be returned.", macAddresses.length > 0);
+            try {
+                MacAddress mac = MacAddress.fromString(macAddresses[0]);
+                assertNotEquals(WifiInfo.DEFAULT_MAC_ADDRESS, mac);
+                assertFalse(MacAddressUtils.isMulticastAddress(mac));
+            } catch (IllegalArgumentException e) {
+                fail("Factory MAC address is invalid");
+            }
+        } finally {
+            uiAutomation.dropShellPermissionIdentity();
+        }
+    }
+
+    /**
+     * Tests {@link WifiManager#isApMacRandomizationSupported()} does not crash.
+     */
+    public void testIsApMacRandomizationSupported() throws Exception {
+        if (!WifiFeature.isWifiSupported(getContext())) {
+            // skip the test if WiFi is not supported
+            return;
+        }
+        mWifiManager.isApMacRandomizationSupported();
+    }
+
+    /**
+     * Tests {@link WifiManager#isConnectedMacRandomizationSupported()} does not crash.
+     */
+    public void testIsConnectedMacRandomizationSupported() throws Exception {
+        if (!WifiFeature.isWifiSupported(getContext())) {
+            // skip the test if WiFi is not supported
+            return;
+        }
+        mWifiManager.isConnectedMacRandomizationSupported();
+    }
+
+    /**
+     * Tests {@link WifiManager#isPreferredNetworkOffloadSupported()} does not crash.
+     */
+    public void testIsPreferredNetworkOffloadSupported() throws Exception {
+        if (!WifiFeature.isWifiSupported(getContext())) {
+            // skip the test if WiFi is not supported
+            return;
+        }
+        mWifiManager.isPreferredNetworkOffloadSupported();
+    }
+
+    /**
+     * Tests {@link WifiManager#isTdlsSupported()} does not crash.
+     */
+    public void testIsTdlsSupported() throws Exception {
+        if (!WifiFeature.isWifiSupported(getContext())) {
+            // skip the test if WiFi is not supported
+            return;
+        }
+        mWifiManager.isTdlsSupported();
+    }
+
+    /**
+     * Tests {@link WifiManager#isStaApConcurrencySupported().
+     */
+    public void testIsStaApConcurrencySupported() throws Exception {
+        if (!WifiFeature.isWifiSupported(getContext())) {
+            // skip the test if WiFi is not supported
+            return;
+        }
+        // check that softap mode is supported by the device
+        if (!mWifiManager.isPortableHotspotSupported()) {
+            return;
+        }
+        assertTrue(mWifiManager.isWifiEnabled());
+
+        boolean isStaApConcurrencySupported = mWifiManager.isStaApConcurrencySupported();
+        // start local only hotspot.
+        TestLocalOnlyHotspotCallback callback = startLocalOnlyHotspot();
+        if (isStaApConcurrencySupported) {
+            assertTrue(mWifiManager.isWifiEnabled());
+        } else {
+            // no concurrency, wifi should be disabled.
+            assertFalse(mWifiManager.isWifiEnabled());
+        }
+        stopLocalOnlyHotspot(callback, true);
+
+        assertTrue(mWifiManager.isWifiEnabled());
+    }
+
     private static class TestTrafficStateCallback implements WifiManager.TrafficStateCallback {
         private final Object mLock;
         public boolean onStateChangedCalled = false;
@@ -1559,6 +2060,16 @@
     }
 
     /**
+     * Test {@link WifiNetworkConnectionStatistics} does not crash.
+     * TODO(b/150891569): deprecate it in Android S, this API is not used anywhere.
+     */
+    public void testWifiNetworkConnectionStatistics() {
+        new WifiNetworkConnectionStatistics();
+        WifiNetworkConnectionStatistics stats = new WifiNetworkConnectionStatistics(0, 0);
+        new WifiNetworkConnectionStatistics(stats);
+    }
+
+    /**
      * Test that the wifi country code is either null, or a length-2 string.
      */
     public void testGetCountryCode() throws Exception {
@@ -1631,4 +2142,210 @@
 
         assertNull(ShellIdentityUtils.invokeWithShellPermissions(mWifiManager::getCurrentNetwork));
     }
+
+    /**
+     * Tests {@link WifiManager#isWpa3SaeSupported()} does not crash.
+     */
+    public void testIsWpa3SaeSupported() throws Exception {
+        if (!WifiFeature.isWifiSupported(getContext())) {
+            // skip the test if WiFi is not supported
+            return;
+        }
+        mWifiManager.isWpa3SaeSupported();
+    }
+
+    /**
+     * Tests {@link WifiManager#isWpa3SuiteBSupported()} does not crash.
+     */
+    public void testIsWpa3SuiteBSupported() throws Exception {
+        if (!WifiFeature.isWifiSupported(getContext())) {
+            // skip the test if WiFi is not supported
+            return;
+        }
+        mWifiManager.isWpa3SuiteBSupported();
+    }
+
+    /**
+     * Tests {@link WifiManager#isEnhancedOpenSupported()} does not crash.
+     */
+    public void testIsEnhancedOpenSupported() throws Exception {
+        if (!WifiFeature.isWifiSupported(getContext())) {
+            // skip the test if WiFi is not supported
+            return;
+        }
+        mWifiManager.isEnhancedOpenSupported();
+    }
+
+    /**
+     * Test that {@link WifiManager#is5GHzBandSupported()} returns successfully in
+     * both WiFi enabled/disabled states.
+     * Note that the response depends on device support and hence both true/false
+     * are valid responses.
+     */
+    public void testIs5GhzBandSupported() throws Exception {
+        if (!WifiFeature.isWifiSupported(getContext())) {
+            // skip the test if WiFi is not supported
+            return;
+        }
+
+        // Check for 5GHz support with wifi enabled
+        setWifiEnabled(true);
+        PollingCheck.check(
+                "Wifi not enabled!",
+                20000,
+                () -> mWifiManager.isWifiEnabled());
+        boolean isSupportedEnabled = mWifiManager.is5GHzBandSupported();
+
+        // Check for 5GHz support with wifi disabled
+        setWifiEnabled(false);
+        PollingCheck.check(
+                "Wifi not disabled!",
+                20000,
+                () -> !mWifiManager.isWifiEnabled());
+        boolean isSupportedDisabled = mWifiManager.is5GHzBandSupported();
+
+        // If Support is true when WiFi is disable, then it has to be true when it is enabled.
+        // Note, the reverse is a valid case.
+        if (isSupportedDisabled) {
+            assertTrue(isSupportedEnabled);
+        }
+    }
+
+    /**
+     * Test that {@link WifiManager#is6GHzBandSupported()} returns successfully in
+     * both Wifi enabled/disabled states.
+     * Note that the response depends on device support and hence both true/false
+     * are valid responses.
+     */
+    public void testIs6GhzBandSupported() throws Exception {
+        if (!WifiFeature.isWifiSupported(getContext())) {
+            // skip the test if WiFi is not supported
+            return;
+        }
+
+        // Check for 6GHz support with wifi enabled
+        setWifiEnabled(true);
+        PollingCheck.check(
+                "Wifi not enabled!",
+                20000,
+                () -> mWifiManager.isWifiEnabled());
+        boolean isSupportedEnabled = mWifiManager.is6GHzBandSupported();
+
+        // Check for 6GHz support with wifi disabled
+        setWifiEnabled(false);
+        PollingCheck.check(
+                "Wifi not disabled!",
+                20000,
+                () -> !mWifiManager.isWifiEnabled());
+        boolean isSupportedDisabled = mWifiManager.is6GHzBandSupported();
+
+        // If Support is true when WiFi is disable, then it has to be true when it is enabled.
+        // Note, the reverse is a valid case.
+        if (isSupportedDisabled) {
+            assertTrue(isSupportedEnabled);
+        }
+    }
+
+    /**
+     * Test that {@link WifiManager#isWifiStandardSupported()} returns successfully in
+     * both Wifi enabled/disabled states. The test is to be performed on
+     * {@link WifiAnnotations}'s {@code WIFI_STANDARD_}
+     * Note that the response depends on device support and hence both true/false
+     * are valid responses.
+     */
+    public void testIsWifiStandardsSupported() throws Exception {
+        if (!WifiFeature.isWifiSupported(getContext())) {
+            // skip the test if WiFi is not supported
+            return;
+        }
+
+        // Check for WiFi standards support with wifi enabled
+        setWifiEnabled(true);
+        PollingCheck.check(
+                "Wifi not enabled!",
+                20000,
+                () -> mWifiManager.isWifiEnabled());
+        boolean isLegacySupportedEnabled =
+                mWifiManager.isWifiStandardSupported(ScanResult.WIFI_STANDARD_LEGACY);
+        boolean is11nSupporedEnabled =
+                mWifiManager.isWifiStandardSupported(ScanResult.WIFI_STANDARD_11N);
+        boolean is11acSupportedEnabled =
+                mWifiManager.isWifiStandardSupported(ScanResult.WIFI_STANDARD_11AC);
+        boolean is11axSupportedEnabled =
+                mWifiManager.isWifiStandardSupported(ScanResult.WIFI_STANDARD_11AX);
+
+        // Check for WiFi standards support with wifi disabled
+        setWifiEnabled(false);
+        PollingCheck.check(
+                "Wifi not disabled!",
+                20000,
+                () -> !mWifiManager.isWifiEnabled());
+
+        boolean isLegacySupportedDisabled =
+                mWifiManager.isWifiStandardSupported(ScanResult.WIFI_STANDARD_LEGACY);
+        boolean is11nSupportedDisabled =
+                mWifiManager.isWifiStandardSupported(ScanResult.WIFI_STANDARD_11N);
+        boolean is11acSupportedDisabled =
+                mWifiManager.isWifiStandardSupported(ScanResult.WIFI_STANDARD_11AC);
+        boolean is11axSupportedDisabled =
+                mWifiManager.isWifiStandardSupported(ScanResult.WIFI_STANDARD_11AX);
+
+        if (isLegacySupportedDisabled) {
+            assertTrue(isLegacySupportedEnabled);
+        }
+
+        if (is11nSupportedDisabled) {
+            assertTrue(is11nSupporedEnabled);
+        }
+
+        if (is11acSupportedDisabled) {
+            assertTrue(is11acSupportedEnabled);
+        }
+
+        if (is11axSupportedDisabled) {
+            assertTrue(is11axSupportedEnabled);
+        }
+    }
+
+    private static PasspointConfiguration createPasspointConfiguration() {
+        PasspointConfiguration config = new PasspointConfiguration();
+        HomeSp homeSp = new HomeSp();
+        homeSp.setFqdn("test.com");
+        homeSp.setFriendlyName("friendly name");
+        homeSp.setRoamingConsortiumOis(new long[]{0x55, 0x66});
+        config.setHomeSp(homeSp);
+        Credential.SimCredential simCred = new Credential.SimCredential();
+        simCred.setImsi("123456*");
+        simCred.setEapType(23 /* EAP_AKA */);
+        Credential cred = new Credential();
+        cred.setRealm("realm");
+        cred.setSimCredential(simCred);
+        config.setCredential(cred);
+
+        return config;
+    }
+
+    /**
+     * Tests {@link WifiManager#addOrUpdatePasspointConfiguration(PasspointConfiguration)}
+     * adds a Passpoint configuration correctly by getting it once it is added, and comparing it
+     * to the local copy of the configuration.
+     */
+    public void testAddOrUpdatePasspointConfiguration() throws Exception {
+        if (!WifiFeature.isWifiSupported(getContext())) {
+            // skip the test if WiFi is not supported
+            return;
+        }
+
+        // Create and install a Passpoint configuration
+        PasspointConfiguration passpointConfiguration = createPasspointConfiguration();
+        mWifiManager.addOrUpdatePasspointConfiguration(passpointConfiguration);
+
+        // Compare configurations
+        List<PasspointConfiguration> configurations = mWifiManager.getPasspointConfigurations();
+        assertNotNull(configurations);
+        assertEquals(passpointConfiguration, configurations.get(0));
+
+        // Clean up
+        mWifiManager.removePasspointConfiguration(passpointConfiguration.getHomeSp().getFqdn());
+    }
 }
diff --git a/tests/tests/net/src/android/net/wifi/cts/WifiMigrationTest.java b/tests/tests/net/src/android/net/wifi/cts/WifiMigrationTest.java
index 6e19a21..ea59f00 100644
--- a/tests/tests/net/src/android/net/wifi/cts/WifiMigrationTest.java
+++ b/tests/tests/net/src/android/net/wifi/cts/WifiMigrationTest.java
@@ -51,41 +51,6 @@
     /**
      * Tests {@link android.net.wifi.WifiMigration.ConfigStoreMigrationData} class.
      */
-    public void testWifiMigrationConfigStoreDataBuilder() throws Exception {
-        if (!WifiFeature.isWifiSupported(getContext())) {
-            // skip the test if WiFi is not supported
-            return;
-        }
-        WifiConfiguration savedNetwork1 = new WifiConfiguration();
-        savedNetwork1.SSID = "\"test1\"";
-        WifiConfiguration savedNetwork2 = new WifiConfiguration();
-        savedNetwork1.SSID = "\"test2\"";
-        List<WifiConfiguration> savedNetworks = Arrays.asList(savedNetwork1, savedNetwork2);
-
-        SoftApConfiguration softApConfiguration = new SoftApConfiguration.Builder()
-                .setSsid("\"test3\"")
-                .build();
-
-        WifiMigration.ConfigStoreMigrationData migrationData =
-                new WifiMigration.ConfigStoreMigrationData.Builder()
-                        .setUserSavedNetworkConfigurations(savedNetworks)
-                        .setUserSoftApConfiguration(softApConfiguration)
-                        .build();
-
-        assertNotNull(migrationData);
-        assertEquals(savedNetworks.size(),
-                migrationData.getUserSavedNetworkConfigurations().size());
-        assertEquals(savedNetwork1.SSID,
-                migrationData.getUserSavedNetworkConfigurations().get(0).SSID);
-        assertEquals(savedNetwork2.SSID,
-                migrationData.getUserSavedNetworkConfigurations().get(1).SSID);
-        assertEquals(softApConfiguration.getSsid(),
-                migrationData.getUserSoftApConfiguration().getSsid());
-    }
-
-    /**
-     * Tests {@link android.net.wifi.WifiMigration.ConfigStoreMigrationData} class.
-     */
     public void testWifiMigrationSettingsDataBuilder() throws Exception {
         if (!WifiFeature.isWifiSupported(getContext())) {
             // skip the test if WiFi is not supported
diff --git a/tests/tests/net/src/android/net/wifi/cts/WifiNetworkSpecifierTest.java b/tests/tests/net/src/android/net/wifi/cts/WifiNetworkSpecifierTest.java
index 96cf45f..2065bb0 100644
--- a/tests/tests/net/src/android/net/wifi/cts/WifiNetworkSpecifierTest.java
+++ b/tests/tests/net/src/android/net/wifi/cts/WifiNetworkSpecifierTest.java
@@ -31,6 +31,7 @@
 import android.net.NetworkRequest;
 import android.net.wifi.ScanResult;
 import android.net.wifi.WifiConfiguration;
+import android.net.wifi.WifiEnterpriseConfig;
 import android.net.wifi.WifiInfo;
 import android.net.wifi.WifiManager;
 import android.net.wifi.WifiManager.NetworkRequestMatchCallback;
@@ -506,4 +507,44 @@
                 .build();
         testUserRejectionWithSpecifier(specifier);
     }
+
+    /**
+     * Tests the builder for WPA2 enterprise networks.
+     * Note: Can't do end to end tests for such networks in CTS environment.
+     */
+    public void testBuilderForWpa2Enterprise() {
+        if (!WifiFeature.isWifiSupported(getContext())) {
+            // skip the test if WiFi is not supported
+            return;
+        }
+        WifiNetworkSpecifier specifier1 = new WifiNetworkSpecifier.Builder()
+                .setSsid(WifiInfo.sanitizeSsid(mTestNetwork.SSID))
+                .setWpa2EnterpriseConfig(new WifiEnterpriseConfig())
+                .build();
+        WifiNetworkSpecifier specifier2 = new WifiNetworkSpecifier.Builder()
+                .setSsid(WifiInfo.sanitizeSsid(mTestNetwork.SSID))
+                .setWpa2EnterpriseConfig(new WifiEnterpriseConfig())
+                .build();
+        assertThat(specifier1.satisfiedBy(specifier2)).isTrue();
+    }
+
+    /**
+     * Tests the builder for WPA3 enterprise networks.
+     * Note: Can't do end to end tests for such networks in CTS environment.
+     */
+    public void testBuilderForWpa3Enterprise() {
+        if (!WifiFeature.isWifiSupported(getContext())) {
+            // skip the test if WiFi is not supported
+            return;
+        }
+        WifiNetworkSpecifier specifier1 = new WifiNetworkSpecifier.Builder()
+                .setSsid(WifiInfo.sanitizeSsid(mTestNetwork.SSID))
+                .setWpa3EnterpriseConfig(new WifiEnterpriseConfig())
+                .build();
+        WifiNetworkSpecifier specifier2 = new WifiNetworkSpecifier.Builder()
+                .setSsid(WifiInfo.sanitizeSsid(mTestNetwork.SSID))
+                .setWpa3EnterpriseConfig(new WifiEnterpriseConfig())
+                .build();
+        assertThat(specifier1.satisfiedBy(specifier2)).isTrue();
+    }
 }
diff --git a/tests/tests/net/src/android/net/wifi/cts/WifiNetworkSuggestionTest.java b/tests/tests/net/src/android/net/wifi/cts/WifiNetworkSuggestionTest.java
index 994b6c9..e73abb8 100644
--- a/tests/tests/net/src/android/net/wifi/cts/WifiNetworkSuggestionTest.java
+++ b/tests/tests/net/src/android/net/wifi/cts/WifiNetworkSuggestionTest.java
@@ -17,6 +17,7 @@
 package android.net.wifi.cts;
 
 import static android.net.wifi.WifiEnterpriseConfig.Eap.AKA;
+import static android.net.wifi.WifiEnterpriseConfig.Eap.WAPI_CERT;
 
 import android.net.MacAddress;
 import android.net.wifi.WifiEnterpriseConfig;
@@ -199,6 +200,28 @@
     }
 
     /**
+     * Tests {@link android.net.wifi.WifiNetworkSuggestion.Builder} class.
+     */
+    public void testBuilderWithWapiEnterprise() throws Exception {
+        if (!WifiFeature.isWifiSupported(getContext())) {
+            // skip the test if WiFi is not supported
+            return;
+        }
+        WifiEnterpriseConfig enterpriseConfig = new WifiEnterpriseConfig();
+        enterpriseConfig.setEapMethod(WAPI_CERT);
+        WifiNetworkSuggestion suggestion =
+                createBuilderWithCommonParams()
+                        .setWapiEnterpriseConfig(enterpriseConfig)
+                        .build();
+        validateCommonParams(suggestion);
+        assertNull(suggestion.getPassphrase());
+        assertNotNull(suggestion.getEnterpriseConfig());
+        assertEquals(enterpriseConfig.getEapMethod(),
+                suggestion.getEnterpriseConfig().getEapMethod());
+        assertNull(suggestion.getPasspointConfig());
+    }
+
+    /**
      * Helper function for creating a {@link PasspointConfiguration} for testing.
      *
      * @return {@link PasspointConfiguration}
diff --git a/tests/tests/net/src/android/net/wifi/nl80211/cts/DeviceWiphyCapabilitiesTest.java b/tests/tests/net/src/android/net/wifi/nl80211/cts/DeviceWiphyCapabilitiesTest.java
new file mode 100644
index 0000000..d8f5e57
--- /dev/null
+++ b/tests/tests/net/src/android/net/wifi/nl80211/cts/DeviceWiphyCapabilitiesTest.java
@@ -0,0 +1,99 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.net.wifi.nl80211.cts;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import static org.junit.Assume.assumeTrue;
+
+import android.content.Context;
+import android.net.wifi.ScanResult;
+import android.net.wifi.cts.WifiFeature;
+import android.net.wifi.nl80211.DeviceWiphyCapabilities;
+import android.os.Parcel;
+
+import androidx.test.filters.SmallTest;
+import androidx.test.platform.app.InstrumentationRegistry;
+import androidx.test.runner.AndroidJUnit4;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+/** CTS tests for {@link DeviceWiphyCapabilities}. */
+@SmallTest
+@RunWith(AndroidJUnit4.class)
+public class DeviceWiphyCapabilitiesTest {
+
+    @Before
+    public void setUp() {
+        Context context = InstrumentationRegistry.getInstrumentation().getContext();
+        // skip tests if Wifi is not supported
+        assumeTrue(WifiFeature.isWifiSupported(context));
+    }
+
+    /**
+     *  Test that a {@link DeviceWiphyCapabilities} object can be serialized and deserialized,
+     *  while keeping its values unchanged.
+     */
+    @Test
+    public void canSerializeAndDeserialize() {
+        DeviceWiphyCapabilities capa = new DeviceWiphyCapabilities();
+
+        capa.setWifiStandardSupport(ScanResult.WIFI_STANDARD_11N, true);
+        capa.setWifiStandardSupport(ScanResult.WIFI_STANDARD_11AC, true);
+        capa.setWifiStandardSupport(ScanResult.WIFI_STANDARD_11AX, false);
+
+        Parcel parcel = Parcel.obtain();
+        capa.writeToParcel(parcel, 0);
+        // Rewind the pointer to the head of the parcel.
+        parcel.setDataPosition(0);
+        DeviceWiphyCapabilities capaDeserialized =
+                DeviceWiphyCapabilities.CREATOR.createFromParcel(parcel);
+
+        assertThat(capaDeserialized.isWifiStandardSupported(ScanResult.WIFI_STANDARD_11N)).isTrue();
+        assertThat(capaDeserialized.isWifiStandardSupported(ScanResult.WIFI_STANDARD_11AC))
+                .isTrue();
+        assertThat(capaDeserialized.isWifiStandardSupported(ScanResult.WIFI_STANDARD_11AX))
+                .isFalse();
+        assertThat(capaDeserialized).isEqualTo(capa);
+        assertThat(capaDeserialized.hashCode()).isEqualTo(capa.hashCode());
+    }
+
+    /** Test mapping wifi standard support into channel width support */
+    @Test
+    public void testMappingWifiStandardIntoChannelWidthSupport() {
+        DeviceWiphyCapabilities capa = new DeviceWiphyCapabilities();
+
+        capa.setWifiStandardSupport(ScanResult.WIFI_STANDARD_11N, false);
+        capa.setWifiStandardSupport(ScanResult.WIFI_STANDARD_11AC, false);
+        capa.setWifiStandardSupport(ScanResult.WIFI_STANDARD_11AX, false);
+        assertThat(capa.isChannelWidthSupported(ScanResult.CHANNEL_WIDTH_20MHZ)).isTrue();
+        assertThat(capa.isChannelWidthSupported(ScanResult.CHANNEL_WIDTH_40MHZ)).isFalse();
+        assertThat(capa.isChannelWidthSupported(ScanResult.CHANNEL_WIDTH_80MHZ)).isFalse();
+
+        capa.setWifiStandardSupport(ScanResult.WIFI_STANDARD_11N, true);
+        assertThat(capa.isChannelWidthSupported(ScanResult.CHANNEL_WIDTH_20MHZ)).isTrue();
+        assertThat(capa.isChannelWidthSupported(ScanResult.CHANNEL_WIDTH_40MHZ)).isTrue();
+        assertThat(capa.isChannelWidthSupported(ScanResult.CHANNEL_WIDTH_80MHZ)).isFalse();
+
+        capa.setWifiStandardSupport(ScanResult.WIFI_STANDARD_11AC, true);
+        assertThat(capa.isChannelWidthSupported(ScanResult.CHANNEL_WIDTH_20MHZ)).isTrue();
+        assertThat(capa.isChannelWidthSupported(ScanResult.CHANNEL_WIDTH_40MHZ)).isTrue();
+        assertThat(capa.isChannelWidthSupported(ScanResult.CHANNEL_WIDTH_80MHZ)).isTrue();
+    }
+}
diff --git a/tests/tests/net/src/android/net/wifi/nl80211/cts/NativeWifiClientTest.java b/tests/tests/net/src/android/net/wifi/nl80211/cts/NativeWifiClientTest.java
new file mode 100644
index 0000000..3149b54
--- /dev/null
+++ b/tests/tests/net/src/android/net/wifi/nl80211/cts/NativeWifiClientTest.java
@@ -0,0 +1,81 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.net.wifi.nl80211.cts;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import static org.junit.Assume.assumeTrue;
+
+import android.content.Context;
+import android.net.MacAddress;
+import android.net.wifi.cts.WifiFeature;
+import android.net.wifi.nl80211.NativeWifiClient;
+import android.os.Parcel;
+
+import androidx.test.filters.SmallTest;
+import androidx.test.platform.app.InstrumentationRegistry;
+import androidx.test.runner.AndroidJUnit4;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+/** CTS tests for {@link NativeWifiClient}. */
+@SmallTest
+@RunWith(AndroidJUnit4.class)
+public class NativeWifiClientTest {
+
+    private static final byte[] TEST_MAC = { 1, 2, 3, 4, 5, 6 };
+
+    @Before
+    public void setUp() {
+        Context context = InstrumentationRegistry.getInstrumentation().getContext();
+        // skip tests if Wifi is not supported
+        assumeTrue(WifiFeature.isWifiSupported(context));
+    }
+
+    @Test
+    public void testGetters() {
+        NativeWifiClient client = new NativeWifiClient(MacAddress.fromBytes(TEST_MAC));
+
+        assertThat(client.getMacAddress().toByteArray()).isEqualTo(TEST_MAC);
+    }
+
+    @Test
+    public void canSerializeAndDeserialize() {
+        NativeWifiClient client = new NativeWifiClient(MacAddress.fromBytes(TEST_MAC));
+
+        Parcel parcel = Parcel.obtain();
+        client.writeToParcel(parcel, 0);
+        // Rewind the pointer to the head of the parcel.
+        parcel.setDataPosition(0);
+        NativeWifiClient clientDeserialized = NativeWifiClient.CREATOR.createFromParcel(parcel);
+
+        assertThat(clientDeserialized.getMacAddress().toByteArray()).isEqualTo(TEST_MAC);
+        assertThat(clientDeserialized).isEqualTo(client);
+        assertThat(clientDeserialized.hashCode()).isEqualTo(client.hashCode());
+    }
+
+    @Test
+    public void testEquals() {
+        NativeWifiClient client = new NativeWifiClient(MacAddress.fromBytes(TEST_MAC));
+        NativeWifiClient client2 =
+                new NativeWifiClient(MacAddress.fromBytes(new byte[] { 7, 8, 9, 10, 11, 12 }));
+
+        assertThat(client2).isNotEqualTo(client);
+    }
+}
diff --git a/tests/tests/net/src/android/net/wifi/nl80211/cts/PnoNetworkTest.java b/tests/tests/net/src/android/net/wifi/nl80211/cts/PnoNetworkTest.java
new file mode 100644
index 0000000..f3a8f05
--- /dev/null
+++ b/tests/tests/net/src/android/net/wifi/nl80211/cts/PnoNetworkTest.java
@@ -0,0 +1,97 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.net.wifi.nl80211.cts;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import static org.junit.Assume.assumeTrue;
+
+import android.content.Context;
+import android.net.wifi.cts.WifiFeature;
+import android.net.wifi.nl80211.PnoNetwork;
+import android.os.Parcel;
+
+import androidx.test.filters.SmallTest;
+import androidx.test.platform.app.InstrumentationRegistry;
+import androidx.test.runner.AndroidJUnit4;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+/** CTS tests for {@link PnoNetwork}. */
+@SmallTest
+@RunWith(AndroidJUnit4.class)
+public class PnoNetworkTest {
+
+    private static final byte[] TEST_SSID = { 's', 's', 'i', 'd' };
+    private static final int[] TEST_FREQUENCIES = { 2412, 2417, 5035 };
+
+    @Before
+    public void setUp() {
+        Context context = InstrumentationRegistry.getInstrumentation().getContext();
+        // skip tests if Wifi is not supported
+        assumeTrue(WifiFeature.isWifiSupported(context));
+    }
+
+    @Test
+    public void testGetters() {
+        PnoNetwork network = new PnoNetwork();
+        network.setSsid(TEST_SSID);
+        network.setFrequenciesMhz(TEST_FREQUENCIES);
+        network.setHidden(true);
+
+        assertThat(network.getSsid()).isEqualTo(TEST_SSID);
+        assertThat(network.getFrequenciesMhz()).isEqualTo(TEST_FREQUENCIES);
+        assertThat(network.isHidden()).isTrue();
+    }
+
+    @Test
+    public void canSerializeAndDeserialize() {
+        PnoNetwork network = new PnoNetwork();
+        network.setSsid(TEST_SSID);
+        network.setFrequenciesMhz(TEST_FREQUENCIES);
+        network.setHidden(true);
+
+        Parcel parcel = Parcel.obtain();
+        network.writeToParcel(parcel, 0);
+        // Rewind the pointer to the head of the parcel.
+        parcel.setDataPosition(0);
+        PnoNetwork networkDeserialized = PnoNetwork.CREATOR.createFromParcel(parcel);
+
+        assertThat(networkDeserialized.getSsid()).isEqualTo(TEST_SSID);
+        assertThat(networkDeserialized.getFrequenciesMhz()).isEqualTo(TEST_FREQUENCIES);
+        assertThat(networkDeserialized.isHidden()).isTrue();
+        assertThat(networkDeserialized).isEqualTo(network);
+        assertThat(networkDeserialized.hashCode()).isEqualTo(network.hashCode());
+    }
+
+    @Test
+    public void testEquals() {
+        PnoNetwork network = new PnoNetwork();
+        network.setSsid(TEST_SSID);
+        network.setFrequenciesMhz(TEST_FREQUENCIES);
+        network.setHidden(true);
+
+        PnoNetwork network2 = new PnoNetwork();
+        network.setSsid(new byte[] { 'a', 's', 'd', 'f'});
+        network.setFrequenciesMhz(new int[] { 1, 2, 3 });
+        network.setHidden(false);
+
+        assertThat(network2).isNotEqualTo(network);
+    }
+}
diff --git a/tests/tests/net/src/android/net/wifi/nl80211/cts/PnoSettingsTest.java b/tests/tests/net/src/android/net/wifi/nl80211/cts/PnoSettingsTest.java
new file mode 100644
index 0000000..59f5d99
--- /dev/null
+++ b/tests/tests/net/src/android/net/wifi/nl80211/cts/PnoSettingsTest.java
@@ -0,0 +1,124 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.net.wifi.nl80211.cts;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import static org.junit.Assume.assumeTrue;
+
+import android.content.Context;
+import android.net.wifi.cts.WifiFeature;
+import android.net.wifi.nl80211.PnoNetwork;
+import android.net.wifi.nl80211.PnoSettings;
+import android.os.Parcel;
+
+import androidx.test.filters.SmallTest;
+import androidx.test.platform.app.InstrumentationRegistry;
+import androidx.test.runner.AndroidJUnit4;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import java.util.Arrays;
+import java.util.List;
+
+/** CTS tests for {@link PnoSettings}. */
+@SmallTest
+@RunWith(AndroidJUnit4.class)
+public class PnoSettingsTest {
+
+    private static List<PnoNetwork> createTestNetworks() {
+        PnoNetwork network1 = new PnoNetwork();
+        network1.setSsid(new byte[] { 's', 's', 'i', 'd' });
+        network1.setFrequenciesMhz(new int[] { 2412, 2417, 5035 });
+        network1.setHidden(true);
+
+        PnoNetwork network2 = new PnoNetwork();
+        network2.setSsid(new byte[] { 'a', 's', 'd', 'f' });
+        network2.setFrequenciesMhz(new int[] { 2422, 2427, 5040 });
+        network2.setHidden(false);
+
+        return Arrays.asList(network1, network2);
+    }
+
+    @Before
+    public void setUp() {
+        Context context = InstrumentationRegistry.getInstrumentation().getContext();
+        // skip tests if Wifi is not supported
+        assumeTrue(WifiFeature.isWifiSupported(context));
+    }
+
+    @Test
+    public void testGetters() {
+        PnoSettings settings = new PnoSettings();
+        settings.setIntervalMillis(1000);
+        settings.setMin2gRssiDbm(-70);
+        settings.setMin5gRssiDbm(-60);
+        settings.setMin6gRssiDbm(-50);
+        settings.setPnoNetworks(createTestNetworks());
+
+        assertThat(settings.getIntervalMillis()).isEqualTo(1000);
+        assertThat(settings.getMin2gRssiDbm()).isEqualTo(-70);
+        assertThat(settings.getMin5gRssiDbm()).isEqualTo(-60);
+        assertThat(settings.getMin6gRssiDbm()).isEqualTo(-50);
+        assertThat(settings.getPnoNetworks()).isEqualTo(createTestNetworks());
+    }
+
+    @Test
+    public void canSerializeAndDeserialize() {
+        PnoSettings settings = new PnoSettings();
+        settings.setIntervalMillis(1000);
+        settings.setMin2gRssiDbm(-70);
+        settings.setMin5gRssiDbm(-60);
+        settings.setMin6gRssiDbm(-50);
+        settings.setPnoNetworks(createTestNetworks());
+
+        Parcel parcel = Parcel.obtain();
+        settings.writeToParcel(parcel, 0);
+        // Rewind the pointer to the head of the parcel.
+        parcel.setDataPosition(0);
+        PnoSettings settingsDeserialized = PnoSettings.CREATOR.createFromParcel(parcel);
+
+        assertThat(settingsDeserialized.getIntervalMillis()).isEqualTo(1000);
+        assertThat(settingsDeserialized.getMin2gRssiDbm()).isEqualTo(-70);
+        assertThat(settingsDeserialized.getMin5gRssiDbm()).isEqualTo(-60);
+        assertThat(settingsDeserialized.getMin6gRssiDbm()).isEqualTo(-50);
+        assertThat(settingsDeserialized.getPnoNetworks()).isEqualTo(createTestNetworks());
+        assertThat(settingsDeserialized).isEqualTo(settings);
+        assertThat(settingsDeserialized.hashCode()).isEqualTo(settings.hashCode());
+    }
+
+    @Test
+    public void testEquals() {
+        PnoSettings settings = new PnoSettings();
+        settings.setIntervalMillis(1000);
+        settings.setMin2gRssiDbm(-70);
+        settings.setMin5gRssiDbm(-60);
+        settings.setMin6gRssiDbm(-50);
+        settings.setPnoNetworks(createTestNetworks());
+
+        PnoSettings settings2 = new PnoSettings();
+        settings.setIntervalMillis(2000);
+        settings.setMin2gRssiDbm(-70);
+        settings.setMin5gRssiDbm(-60);
+        settings.setMin6gRssiDbm(-50);
+        settings.setPnoNetworks(createTestNetworks());
+
+        assertThat(settings2).isNotEqualTo(settings);
+    }
+}
diff --git a/tests/tests/net/src/android/net/wifi/nl80211/cts/RadioChainInfoTest.java b/tests/tests/net/src/android/net/wifi/nl80211/cts/RadioChainInfoTest.java
new file mode 100644
index 0000000..0a76bdb
--- /dev/null
+++ b/tests/tests/net/src/android/net/wifi/nl80211/cts/RadioChainInfoTest.java
@@ -0,0 +1,83 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.net.wifi.nl80211.cts;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import static org.junit.Assume.assumeTrue;
+
+import android.content.Context;
+import android.net.wifi.cts.WifiFeature;
+import android.net.wifi.nl80211.RadioChainInfo;
+import android.os.Parcel;
+
+import androidx.test.filters.SmallTest;
+import androidx.test.platform.app.InstrumentationRegistry;
+import androidx.test.runner.AndroidJUnit4;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+/** CTS tests for {@link RadioChainInfo}. */
+@SmallTest
+@RunWith(AndroidJUnit4.class)
+public class RadioChainInfoTest {
+
+    private static final int TEST_CHAIN_ID = 1;
+    private static final int TEST_CHAIN_ID2 = 2;
+    private static final int TEST_LEVEL_DBM = -50;
+    private static final int TEST_LEVEL_DBM2 = -80;
+
+    @Before
+    public void setUp() {
+        Context context = InstrumentationRegistry.getInstrumentation().getContext();
+        // skip tests if Wifi is not supported
+        assumeTrue(WifiFeature.isWifiSupported(context));
+    }
+
+    @Test
+    public void testGetters() {
+        RadioChainInfo info = new RadioChainInfo(TEST_CHAIN_ID, TEST_LEVEL_DBM);
+        assertThat(info.getChainId()).isEqualTo(TEST_CHAIN_ID);
+        assertThat(info.getLevelDbm()).isEqualTo(TEST_LEVEL_DBM);
+    }
+
+    @Test
+    public void canSerializeAndDeserialize() {
+        RadioChainInfo info = new RadioChainInfo(TEST_CHAIN_ID, TEST_LEVEL_DBM);
+
+        Parcel parcel = Parcel.obtain();
+        info.writeToParcel(parcel, 0);
+        // Rewind the pointer to the head of the parcel.
+        parcel.setDataPosition(0);
+        RadioChainInfo infoDeserialized = RadioChainInfo.CREATOR.createFromParcel(parcel);
+
+        assertThat(infoDeserialized.getChainId()).isEqualTo(TEST_CHAIN_ID);
+        assertThat(infoDeserialized.getLevelDbm()).isEqualTo(TEST_LEVEL_DBM);
+        assertThat(infoDeserialized).isEqualTo(info);
+        assertThat(infoDeserialized.hashCode()).isEqualTo(info.hashCode());
+    }
+
+    @Test
+    public void testEquals() {
+        RadioChainInfo info = new RadioChainInfo(TEST_CHAIN_ID, TEST_LEVEL_DBM);
+        RadioChainInfo info2 = new RadioChainInfo(TEST_CHAIN_ID2, TEST_LEVEL_DBM2);
+
+        assertThat(info2).isNotEqualTo(info);
+    }
+}
diff --git a/tests/tests/net/src/android/net/wifi/nl80211/cts/WifiNl80211ManagerTest.java b/tests/tests/net/src/android/net/wifi/nl80211/cts/WifiNl80211ManagerTest.java
new file mode 100644
index 0000000..f1f3010
--- /dev/null
+++ b/tests/tests/net/src/android/net/wifi/nl80211/cts/WifiNl80211ManagerTest.java
@@ -0,0 +1,84 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.net.wifi.nl80211.cts;
+
+import static android.net.wifi.nl80211.WifiNl80211Manager.OemSecurityType;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import static org.junit.Assume.assumeTrue;
+
+import android.content.Context;
+import android.net.wifi.ScanResult;
+import android.net.wifi.cts.WifiFeature;
+import android.net.wifi.nl80211.WifiNl80211Manager;
+
+import androidx.test.filters.SmallTest;
+import androidx.test.platform.app.InstrumentationRegistry;
+import androidx.test.runner.AndroidJUnit4;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import java.util.Arrays;
+
+/** CTS tests for {@link WifiNl80211Manager}. */
+@SmallTest
+@RunWith(AndroidJUnit4.class)
+public class WifiNl80211ManagerTest {
+
+    private Context mContext;
+
+    @Before
+    public void setUp() {
+        mContext = InstrumentationRegistry.getInstrumentation().getContext();
+        // skip tests if Wifi is not supported
+        assumeTrue(WifiFeature.isWifiSupported(mContext));
+    }
+
+    @Test
+    public void testOemSecurityTypeConstructor() {
+        OemSecurityType securityType = new OemSecurityType(
+                ScanResult.PROTOCOL_WPA,
+                Arrays.asList(ScanResult.KEY_MGMT_PSK, ScanResult.KEY_MGMT_SAE),
+                Arrays.asList(ScanResult.CIPHER_NONE, ScanResult.CIPHER_TKIP),
+                ScanResult.CIPHER_CCMP);
+
+        assertThat(securityType.protocol).isEqualTo(ScanResult.PROTOCOL_WPA);
+        assertThat(securityType.keyManagement)
+                .isEqualTo(Arrays.asList(ScanResult.KEY_MGMT_PSK, ScanResult.KEY_MGMT_SAE));
+        assertThat(securityType.pairwiseCipher)
+                .isEqualTo(Arrays.asList(ScanResult.CIPHER_NONE, ScanResult.CIPHER_TKIP));
+        assertThat(securityType.groupCipher).isEqualTo(ScanResult.CIPHER_CCMP);
+    }
+
+    @Test
+    public void testSendMgmtFrame() {
+        try {
+            WifiNl80211Manager manager = mContext.getSystemService(WifiNl80211Manager.class);
+            manager.sendMgmtFrame("wlan0", new byte[]{}, -1, Runnable::run,
+                    new WifiNl80211Manager.SendMgmtFrameCallback() {
+                        @Override
+                        public void onAck(int elapsedTimeMs) {}
+
+                        @Override
+                        public void onFailure(int reason) {}
+                    });
+        } catch (Exception ignore) {}
+    }
+}
diff --git a/tests/tests/net/src/android/net/wifi/p2p/cts/WifiP2pConfigTest.java b/tests/tests/net/src/android/net/wifi/p2p/cts/WifiP2pConfigTest.java
index ee7e1ed..0a2a2e6 100644
--- a/tests/tests/net/src/android/net/wifi/p2p/cts/WifiP2pConfigTest.java
+++ b/tests/tests/net/src/android/net/wifi/p2p/cts/WifiP2pConfigTest.java
@@ -28,6 +28,24 @@
     private static final int TEST_OWNER_FREQ = 2447;
     private static final String TEST_DEVICE_ADDRESS = "aa:bb:cc:dd:ee:ff";
 
+    public void testWifiP2pConfigCopyConstructor() {
+        WifiP2pConfig config = new WifiP2pConfig.Builder()
+                .setNetworkName(TEST_NETWORK_NAME)
+                .setPassphrase(TEST_PASSPHRASE)
+                .setGroupOperatingBand(TEST_OWNER_BAND)
+                .setDeviceAddress(MacAddress.fromString(TEST_DEVICE_ADDRESS))
+                .enablePersistentMode(true)
+                .build();
+
+        WifiP2pConfig copiedConfig = new WifiP2pConfig(config);
+
+        assertEquals(copiedConfig.deviceAddress, TEST_DEVICE_ADDRESS);
+        assertEquals(copiedConfig.getNetworkName(), TEST_NETWORK_NAME);
+        assertEquals(copiedConfig.getPassphrase(), TEST_PASSPHRASE);
+        assertEquals(copiedConfig.getGroupOwnerBand(), TEST_OWNER_BAND);
+        assertEquals(copiedConfig.getNetworkId(), WifiP2pGroup.NETWORK_ID_PERSISTENT);
+    }
+
     public void testWifiP2pConfigBuilderForPersist() {
         WifiP2pConfig config = new WifiP2pConfig.Builder()
                 .setNetworkName(TEST_NETWORK_NAME)
diff --git a/tests/tests/net/src/android/net/wifi/p2p/cts/WifiP2pDeviceTest.java b/tests/tests/net/src/android/net/wifi/p2p/cts/WifiP2pDeviceTest.java
new file mode 100644
index 0000000..1510d7c
--- /dev/null
+++ b/tests/tests/net/src/android/net/wifi/p2p/cts/WifiP2pDeviceTest.java
@@ -0,0 +1,38 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.net.wifi.p2p.cts;
+
+import android.net.InetAddresses;
+import android.net.wifi.p2p.WifiP2pDevice;
+import android.test.AndroidTestCase;
+
+public class WifiP2pDeviceTest extends AndroidTestCase {
+
+    public void testDefaultWpsMethodSupportCheck() {
+        WifiP2pDevice dev = new WifiP2pDevice();
+
+        assertFalse(dev.wpsPbcSupported());
+        assertFalse(dev.wpsDisplaySupported());
+        assertFalse(dev.wpsKeypadSupported());
+    }
+
+    public void testDefaultDeviceCapabilityCheck() {
+        WifiP2pDevice dev = new WifiP2pDevice();
+
+        assertFalse(dev.isServiceDiscoveryCapable());
+    }
+}
diff --git a/tests/tests/net/src/android/net/wifi/p2p/cts/WifiP2pInfoTest.java b/tests/tests/net/src/android/net/wifi/p2p/cts/WifiP2pInfoTest.java
new file mode 100644
index 0000000..8504f15
--- /dev/null
+++ b/tests/tests/net/src/android/net/wifi/p2p/cts/WifiP2pInfoTest.java
@@ -0,0 +1,60 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.net.wifi.p2p.cts;
+
+import android.net.InetAddresses;
+import android.net.wifi.p2p.WifiP2pInfo;
+import android.test.AndroidTestCase;
+
+public class WifiP2pInfoTest extends AndroidTestCase {
+
+    public String TEST_GROUP_OWNER_ADDRESS = "192.168.43.1";
+
+    public void testWifiP2pInfoNoGroup() {
+        WifiP2pInfo info = new WifiP2pInfo();
+        info.groupFormed = false;
+
+        WifiP2pInfo copiedInfo = new WifiP2pInfo(info);
+        assertEquals(info.groupFormed, copiedInfo.groupFormed);
+        assertEquals(info.isGroupOwner, copiedInfo.isGroupOwner);
+        assertEquals(info.groupOwnerAddress, copiedInfo.groupOwnerAddress);
+    }
+
+    public void testWifiP2pInfoGroupOwner() {
+        WifiP2pInfo info = new WifiP2pInfo();
+        info.groupFormed = true;
+        info.isGroupOwner = true;
+        info.groupOwnerAddress = InetAddresses.parseNumericAddress(TEST_GROUP_OWNER_ADDRESS);
+
+        WifiP2pInfo copiedInfo = new WifiP2pInfo(info);
+        assertEquals(info.groupFormed, copiedInfo.groupFormed);
+        assertEquals(info.isGroupOwner, copiedInfo.isGroupOwner);
+        assertEquals(info.groupOwnerAddress, copiedInfo.groupOwnerAddress);
+    }
+
+    public void testWifiP2pInfoGroupClient() {
+        WifiP2pInfo info = new WifiP2pInfo();
+        info.groupFormed = true;
+        info.isGroupOwner = false;
+        info.groupOwnerAddress = InetAddresses.parseNumericAddress(TEST_GROUP_OWNER_ADDRESS);
+
+        WifiP2pInfo copiedInfo = new WifiP2pInfo(info);
+        assertEquals(info.groupFormed, copiedInfo.groupFormed);
+        assertEquals(info.isGroupOwner, copiedInfo.isGroupOwner);
+        assertEquals(info.groupOwnerAddress, copiedInfo.groupOwnerAddress);
+    }
+}
diff --git a/tests/tests/net/src/android/net/wifi/p2p/cts/WifiP2pServiceRequestTest.java b/tests/tests/net/src/android/net/wifi/p2p/cts/WifiP2pServiceRequestTest.java
new file mode 100644
index 0000000..b363b1e
--- /dev/null
+++ b/tests/tests/net/src/android/net/wifi/p2p/cts/WifiP2pServiceRequestTest.java
@@ -0,0 +1,75 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.net.wifi.p2p.cts;
+
+import android.net.wifi.p2p.nsd.WifiP2pServiceInfo;
+import android.net.wifi.p2p.nsd.WifiP2pServiceRequest;
+import android.net.wifi.p2p.nsd.WifiP2pUpnpServiceRequest;
+import android.test.AndroidTestCase;
+import android.util.Log;
+
+import java.util.Arrays;
+import java.util.List;
+import java.util.Locale;
+import java.util.stream.Collectors;
+
+public class WifiP2pServiceRequestTest extends AndroidTestCase {
+
+    private final int TEST_UPNP_VERSION = 0x10;
+    private final String TEST_UPNP_QUERY = "ssdp:all";
+
+    private String bin2HexStr(byte[] data) {
+        StringBuffer sb = new StringBuffer();
+        for (byte b: data) {
+            sb.append(String.format(Locale.US, "%02x", b & 0xff));
+        }
+        return sb.toString();
+    }
+
+    public void testValidRawRequest() throws IllegalArgumentException {
+        StringBuffer sb = new StringBuffer();
+        sb.append(String.format(Locale.US, "%02x", TEST_UPNP_VERSION));
+        sb.append(bin2HexStr(TEST_UPNP_QUERY.getBytes()));
+
+        WifiP2pServiceRequest rawRequest =
+                WifiP2pServiceRequest.newInstance(
+                        WifiP2pServiceInfo.SERVICE_TYPE_UPNP,
+                        sb.toString());
+
+        WifiP2pUpnpServiceRequest upnpRequest =
+                WifiP2pUpnpServiceRequest.newInstance(
+                        TEST_UPNP_QUERY);
+
+        assertEquals(rawRequest, upnpRequest);
+    }
+
+    public void testInvalidRawRequest() {
+        StringBuffer sb = new StringBuffer();
+        sb.append(String.format(Locale.US, "%02x", TEST_UPNP_VERSION));
+        sb.append(bin2HexStr(TEST_UPNP_QUERY.getBytes()));
+        sb.append("x");
+
+        try {
+            WifiP2pServiceRequest request =
+                    WifiP2pServiceRequest.newInstance(
+                            WifiP2pServiceInfo.SERVICE_TYPE_UPNP, sb.toString());
+            fail("Expected IllegalArgumentException");
+        } catch (IllegalArgumentException ex) {
+            return;
+        }
+    }
+}
diff --git a/tests/tests/net/src/android/net/wifi/p2p/cts/WifiP2pWfdInfoTest.java b/tests/tests/net/src/android/net/wifi/p2p/cts/WifiP2pWfdInfoTest.java
new file mode 100644
index 0000000..75df5bf
--- /dev/null
+++ b/tests/tests/net/src/android/net/wifi/p2p/cts/WifiP2pWfdInfoTest.java
@@ -0,0 +1,50 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.net.wifi.p2p.cts;
+
+import android.net.wifi.p2p.WifiP2pWfdInfo;
+import android.test.AndroidTestCase;
+
+public class WifiP2pWfdInfoTest extends AndroidTestCase {
+
+    private final int TEST_DEVICE_TYPE = WifiP2pWfdInfo.DEVICE_TYPE_WFD_SOURCE;
+    private final boolean TEST_DEVICE_ENABLE_STATUS = true;
+    private final boolean TEST_SESSION_STATUS = true;
+    private final int TEST_CONTROL_PORT = 9999;
+    private final int TEST_MAX_THROUGHPUT = 1024;
+    private final boolean TEST_CONTENT_PROTECTION_SUPPORTED_STATUS = true;
+
+    public void testWifiP2pWfdInfo() {
+        WifiP2pWfdInfo info = new WifiP2pWfdInfo();
+
+        info.setDeviceType(TEST_DEVICE_TYPE);
+        info.setEnabled(TEST_DEVICE_ENABLE_STATUS);
+        info.setSessionAvailable(true);
+        info.setControlPort(TEST_CONTROL_PORT);
+        info.setMaxThroughput(TEST_MAX_THROUGHPUT);
+        info.setContentProtectionSupported(true);
+
+        WifiP2pWfdInfo copiedInfo = new WifiP2pWfdInfo(info);
+        assertEquals(TEST_DEVICE_TYPE, copiedInfo.getDeviceType());
+        assertEquals(TEST_DEVICE_ENABLE_STATUS, copiedInfo.isEnabled());
+        assertEquals(TEST_SESSION_STATUS, copiedInfo.isSessionAvailable());
+        assertEquals(TEST_CONTROL_PORT, copiedInfo.getControlPort());
+        assertEquals(TEST_MAX_THROUGHPUT, copiedInfo.getMaxThroughput());
+        assertEquals(TEST_CONTENT_PROTECTION_SUPPORTED_STATUS,
+                copiedInfo.isContentProtectionSupported());
+    }
+}
diff --git a/tests/tests/notificationlegacy/AndroidTest.xml b/tests/tests/notificationlegacy/AndroidTest.xml
index 690766c..571fe44 100644
--- a/tests/tests/notificationlegacy/AndroidTest.xml
+++ b/tests/tests/notificationlegacy/AndroidTest.xml
@@ -16,6 +16,8 @@
 <configuration description="Config for CTS Notification legacy test cases">
     <option name="test-suite-tag" value="cts" />
     <option name="config-descriptor:metadata" key="component" value="framework" />
+    <!-- Not testing features backed by native code, so only need to run against one ABI -->
+    <option name="config-descriptor:metadata" key="parameter" value="not_multi_abi" />
     <target_preparer class="com.android.tradefed.targetprep.suite.SuiteApkInstaller">
         <option name="cleanup-apks" value="true" />
         <option name="test-file-name" value="CtsLegacyNotificationTestCases.apk" />
diff --git a/tests/tests/os/src/android/os/cts/BinderTest.java b/tests/tests/os/src/android/os/cts/BinderTest.java
index 59b81e2..d73aff8 100644
--- a/tests/tests/os/src/android/os/cts/BinderTest.java
+++ b/tests/tests/os/src/android/os/cts/BinderTest.java
@@ -331,6 +331,8 @@
         assertTrue(mBinder.unlinkToDeath(new MockDeathRecipient(), 0));
 
         assertTrue(mBinder.pingBinder());
+
+        assertTrue(IBinder.getSuggestedMaxIpcSizeBytes() > 0);
     }
 
     public void testFlushPendingCommands() {
@@ -381,6 +383,22 @@
         Binder.restoreCallingIdentity(token);
     }
 
+    public void testClearCallingWorkSource() {
+        final long token = Binder.clearCallingWorkSource();
+        Binder.restoreCallingWorkSource(token);
+    }
+
+    public void testSetCallingWorkSourceUid() {
+        final int otherUid = android.os.Process.myUid() + 1;
+        assertFalse(Binder.getCallingWorkSourceUid() == otherUid);
+
+        final long token = Binder.setCallingWorkSourceUid(otherUid);
+        assertTrue(Binder.getCallingWorkSourceUid() == otherUid);
+        Binder.restoreCallingWorkSource(token);
+
+        assertFalse(Binder.getCallingWorkSourceUid() == otherUid);
+    }
+
     public void testInterfaceRelatedMethods() {
         assertNull(mBinder.getInterfaceDescriptor());
         mBinder.attachInterface(new MockIInterface(), DESCRIPTOR_GOOGLE);
diff --git a/tests/tests/os/src/android/os/cts/ParcelFileDescriptorTest.java b/tests/tests/os/src/android/os/cts/ParcelFileDescriptorTest.java
index f0f2d36..69f9a40 100644
--- a/tests/tests/os/src/android/os/cts/ParcelFileDescriptorTest.java
+++ b/tests/tests/os/src/android/os/cts/ParcelFileDescriptorTest.java
@@ -341,6 +341,24 @@
     }
 
     @Test
+    public void testFileWrapped() throws Exception {
+        final Handler handler1 = new Handler(Looper.getMainLooper());
+        final Handler handler2 = new Handler(Looper.getMainLooper());
+        final FutureCloseListener listener1 = new FutureCloseListener();
+        final FutureCloseListener listener2 = new FutureCloseListener();
+        final ParcelFileDescriptor file1 = ParcelFileDescriptor.open(
+                File.createTempFile("pfd", "bbq"), ParcelFileDescriptor.MODE_READ_WRITE, handler1,
+                listener1);
+        final ParcelFileDescriptor file2 = ParcelFileDescriptor.wrap(file1, handler2, listener2);
+
+        write(file2, 7);
+        file2.close();
+
+        // make sure we were notified
+        assertEquals(null, listener2.get());
+    }
+
+    @Test
     public void testSocketErrorAfterClose() throws Exception {
         final ParcelFileDescriptor[] pair = ParcelFileDescriptor.createReliableSocketPair();
         final ParcelFileDescriptor red = pair[0];
diff --git a/tests/tests/os/src/android/os/cts/ParcelTest.java b/tests/tests/os/src/android/os/cts/ParcelTest.java
index 0fd3d38..bb7b41a 100644
--- a/tests/tests/os/src/android/os/cts/ParcelTest.java
+++ b/tests/tests/os/src/android/os/cts/ParcelTest.java
@@ -2055,6 +2055,18 @@
         p.recycle();
     }
 
+    public void testReadParcelableCreator() {
+        MockClassLoader mcl = new MockClassLoader();
+        final String signatureString  = "1234567890abcdef";
+        Signature s = new Signature(signatureString);
+
+        Parcel p = Parcel.obtain();
+        p.writeParcelableCreator(s);
+        p.setDataPosition(0);
+        assertSame(Signature.CREATOR, p.readParcelableCreator(mcl));
+        p.recycle();
+    }
+
     public void testReadParcelableArray() {
         Parcel p;
         MockClassLoader mcl = new MockClassLoader();
diff --git a/tests/tests/packageinstaller/nopermission/AndroidTest.xml b/tests/tests/packageinstaller/nopermission/AndroidTest.xml
index 2229230..08ae8cc 100644
--- a/tests/tests/packageinstaller/nopermission/AndroidTest.xml
+++ b/tests/tests/packageinstaller/nopermission/AndroidTest.xml
@@ -36,6 +36,10 @@
         <option name="test-file-name" value="CtsNoPermissionTestCases.apk" />
     </target_preparer>
 
+    <target_preparer class="com.android.tradefed.targetprep.RunCommandTargetPreparer">
+        <option name="run-command" value="appops set android.packageinstaller.nopermission.cts REQUEST_INSTALL_PACKAGES allow" />
+    </target_preparer>
+
     <test class="com.android.tradefed.testtype.AndroidJUnitTest" >
         <option name="package" value="android.packageinstaller.nopermission.cts" />
         <option name="runtime-hint" value="1m" />
diff --git a/tests/tests/packageinstaller/nopermission/src/android.packageinstaller.nopermission.cts/NoPermissionTests.kt b/tests/tests/packageinstaller/nopermission/src/android.packageinstaller.nopermission.cts/NoPermissionTests.kt
index 022d598..024d1ad 100644
--- a/tests/tests/packageinstaller/nopermission/src/android.packageinstaller.nopermission.cts/NoPermissionTests.kt
+++ b/tests/tests/packageinstaller/nopermission/src/android.packageinstaller.nopermission.cts/NoPermissionTests.kt
@@ -15,7 +15,6 @@
  */
 package android.packageinstaller.nopermission.cts
 
-import android.app.AppOpsManager.MODE_ALLOWED
 import android.app.PendingIntent
 import android.content.BroadcastReceiver
 import android.content.Context
@@ -33,7 +32,6 @@
 import android.support.test.uiautomator.UiDevice
 import android.support.test.uiautomator.Until
 import androidx.core.content.FileProvider
-import com.android.compatibility.common.util.AppOpsUtils
 import org.junit.After
 import org.junit.Assert.assertFalse
 import org.junit.Assert.assertTrue
@@ -54,7 +52,6 @@
 private const val ACTION = "NoPermissionTests.install_cb"
 
 private const val WAIT_FOR_UI_TIMEOUT = 5000L
-private const val APP_OP_STR = "REQUEST_INSTALL_PACKAGES"
 
 @RunWith(AndroidJUnit4::class)
 @MediumTest
@@ -92,12 +89,6 @@
     }
 
     @Before
-    fun allowToInstallPackages() {
-        // To make sure no other blocking dialogs appear
-        AppOpsUtils.setOpMode(context.packageName, APP_OP_STR, MODE_ALLOWED)
-    }
-
-    @Before
     fun registerInstallResultReceiver() {
         context.registerReceiver(receiver, IntentFilter(ACTION))
     }
diff --git a/tests/tests/permission/src/android/permission/cts/ShellPermissionTest.java b/tests/tests/permission/src/android/permission/cts/ShellPermissionTest.java
index 13c75de..6b73cbd 100644
--- a/tests/tests/permission/src/android/permission/cts/ShellPermissionTest.java
+++ b/tests/tests/permission/src/android/permission/cts/ShellPermissionTest.java
@@ -47,6 +47,7 @@
     /** Permissions that shell is NOT permitted to have. */
     private static final String[] BLACKLISTED_PERMISSIONS = {
             "android.permission.MANAGE_USERS",
+            "android.permission.NETWORK_STACK",
     };
 
     private static final Context sContext = InstrumentationRegistry.getTargetContext();
diff --git a/tests/tests/permission2/res/raw/android_manifest.xml b/tests/tests/permission2/res/raw/android_manifest.xml
index 9bbc177..9534529 100644
--- a/tests/tests/permission2/res/raw/android_manifest.xml
+++ b/tests/tests/permission2/res/raw/android_manifest.xml
@@ -1180,6 +1180,14 @@
                 android:description="@string/permdesc_callCompanionApp"
                 android:protectionLevel="normal" />
 
+    <!-- Exempt this uid from restrictions to background audio recording
+     <p>Protection level: signature|privileged
+    -->
+    <permission android:name="android.permission.EXEMPT_FROM_AUDIO_RECORD_RESTRICTIONS"
+                android:label="@string/permlab_exemptFromAudioRecordRestrictions"
+                android:description="@string/permdesc_exemptFromAudioRecordRestrictions"
+                android:protectionLevel="signature|privileged" />
+
     <!-- Allows a calling app to continue a call which was started in another app.  An example is a
          video calling app that wants to continue a voice call on the user's mobile network.<p>
          When the handover of a call from one app to another takes place, there are two devices
@@ -1308,6 +1316,15 @@
         android:description="@string/permdesc_systemCamera"
         android:protectionLevel="system|signature" />
 
+    <!-- Allows receiving the camera service notifications when a camera is opened
+        (by a certain application package) or closed.
+        @hide -->
+    <permission android:name="android.permission.CAMERA_OPEN_CLOSE_LISTENER"
+        android:permissionGroup="android.permission-group.UNDEFINED"
+        android:label="@string/permlab_cameraOpenCloseListener"
+        android:description="@string/permdesc_cameraOpenCloseListener"
+        android:protectionLevel="signature" />
+
     <!-- ====================================================================== -->
     <!-- Permissions for accessing the device sensors                           -->
     <!-- ====================================================================== -->
@@ -1663,6 +1680,10 @@
     <permission android:name="android.permission.NETWORK_FACTORY"
                 android:protectionLevel="signature" />
 
+    <!-- @SystemApi @hide Allows applications to access network stats provider -->
+    <permission android:name="android.permission.NETWORK_STATS_PROVIDER"
+                android:protectionLevel="signature" />
+
     <!-- Allows Settings and SystemUI to call methods in Networking services
          <p>Not for use by third-party or privileged applications.
          @SystemApi
@@ -3723,6 +3744,12 @@
     <permission android:name="android.permission.WHITELIST_RESTRICTED_PERMISSIONS"
                 android:protectionLevel="signature|installer" />
 
+    <!-- @SystemApi Allows an application to an exempt an app from having its permission be
+        auto-revoked when unused for an extended period of time.
+        @hide -->
+    <permission android:name="android.permission.WHITELIST_AUTO_REVOKE_PERMISSIONS"
+        android:protectionLevel="signature|installer" />
+
     <!-- @hide Allows an application to observe permission changes. -->
     <permission android:name="android.permission.OBSERVE_GRANT_REVOKE_PERMISSIONS"
         android:protectionLevel="signature|privileged" />
diff --git a/tests/tests/permission3/src/android/permission3/cts/PermissionTest23.kt b/tests/tests/permission3/src/android/permission3/cts/PermissionTest23.kt
index cecdd38..7b3850c 100644
--- a/tests/tests/permission3/src/android/permission3/cts/PermissionTest23.kt
+++ b/tests/tests/permission3/src/android/permission3/cts/PermissionTest23.kt
@@ -16,6 +16,7 @@
 
 package android.permission3.cts
 
+import androidx.test.filters.FlakyTest
 import org.junit.Before
 import org.junit.Test
 
@@ -228,6 +229,7 @@
         assertAppHasPermission(android.Manifest.permission.READ_CONTACTS, false)
     }
 
+    @FlakyTest
     @Test
     fun testNoResidualPermissionsOnUninstall() {
         // Grant all permissions
diff --git a/tests/tests/provider/src/android/provider/cts/DocumentsContractTest.java b/tests/tests/provider/src/android/provider/cts/DocumentsContractTest.java
index 66bb43b..8f435f7 100644
--- a/tests/tests/provider/src/android/provider/cts/DocumentsContractTest.java
+++ b/tests/tests/provider/src/android/provider/cts/DocumentsContractTest.java
@@ -260,6 +260,12 @@
     }
 
     @Test
+    public void testManageMode() {
+        assertFalse(DocumentsContract.isManageMode(URI_RED));
+        assertTrue(DocumentsContract.isManageMode(DocumentsContract.setManageMode(URI_RED)));
+    }
+
+    @Test
     public void testCreateDocument() throws Exception {
         doReturn(DOC_RESULT).when(mProvider).createDocument(DOC_RED, MIME_TYPE, DISPLAY_NAME);
         assertEquals(URI_RESULT, createDocument(mResolver, URI_RED, MIME_TYPE, DISPLAY_NAME));
diff --git a/tests/tests/provider/src/android/provider/cts/SettingsPanelTest.java b/tests/tests/provider/src/android/provider/cts/SettingsPanelTest.java
index 4c5f898..357e5e8 100644
--- a/tests/tests/provider/src/android/provider/cts/SettingsPanelTest.java
+++ b/tests/tests/provider/src/android/provider/cts/SettingsPanelTest.java
@@ -55,6 +55,13 @@
     private static final String RESOURCE_DONE = "done";
     private static final String RESOURCE_SEE_MORE = "see_more";
     private static final String RESOURCE_TITLE = "panel_title";
+    private static final String RESOURCE_HEADER = "header_title";
+    private static final String TEST_PACKAGE_NAME = "test_package_name";
+    private static final String MEDIA_OUTPUT_TITLE_NAME = "Media";
+    private static final String ACTION_MEDIA_OUTPUT =
+            "com.android.settings.panel.action.MEDIA_OUTPUT";
+    private static final String EXTRA_PACKAGE_NAME =
+            "com.android.settings.panel.extra.PACKAGE_NAME";
 
     private String mSettingsPackage;
     private String mLauncherPackage;
@@ -120,6 +127,24 @@
     }
 
     @Test
+    public void mediaOutputPanel_withPackageNameExtra_correctPackage() {
+        launchMediaOutputPanel(TEST_PACKAGE_NAME);
+
+        String currentPackage = mDevice.getCurrentPackageName();
+
+        assertThat(currentPackage).isEqualTo(mSettingsPackage);
+    }
+
+    @Test
+    public void mediaOutputPanel_noPutPackageNameExtra_correctPackage() {
+        launchMediaOutputPanel(null /* packageName */);
+
+        String currentPackage = mDevice.getCurrentPackageName();
+
+        assertThat(currentPackage).isEqualTo(mSettingsPackage);
+    }
+
+    @Test
     public void wifiPanel_correctPackage() {
         launchWifiPanel();
 
@@ -129,6 +154,14 @@
     }
 
     @Test
+    public void mediaOutputPanel_correctTitle() {
+        launchMediaOutputPanel(TEST_PACKAGE_NAME);
+
+        final UiObject2 titleView = mDevice.findObject(By.res(mSettingsPackage, RESOURCE_HEADER));
+
+        assertThat(titleView.getText()).isEqualTo(MEDIA_OUTPUT_TITLE_NAME);
+    }
+    @Test
     public void internetPanel_doneClosesPanel() {
         // Launch panel
         launchInternetPanel();
@@ -189,6 +222,22 @@
     }
 
     @Test
+    public void mediaOutputPanel_doneClosesPanel() {
+        // Launch panel
+        launchMediaOutputPanel(TEST_PACKAGE_NAME);
+        String currentPackage = mDevice.getCurrentPackageName();
+        assertThat(currentPackage).isEqualTo(mSettingsPackage);
+
+        // Click the done button
+        mDevice.findObject(By.res(currentPackage, RESOURCE_DONE)).click();
+        mDevice.wait(Until.hasObject(By.pkg(mLauncherPackage).depth(0)), TIMEOUT);
+
+        // Assert that we have left the panel
+        currentPackage = mDevice.getCurrentPackageName();
+        assertThat(currentPackage).isNotEqualTo(mSettingsPackage);
+    }
+
+    @Test
     public void internetPanel_seeMoreButton_launchesIntoSettings() {
         // Launch panel
         launchInternetPanel();
@@ -261,6 +310,19 @@
         assertThat(titleView).isNull();
     }
 
+    @Test
+    public void mediaOutputPanel_seeMoreButton_doNothing() {
+        // Launch panel
+        launchMediaOutputPanel(TEST_PACKAGE_NAME);
+        String currentPackage = mDevice.getCurrentPackageName();
+        assertThat(currentPackage).isEqualTo(mSettingsPackage);
+
+        // Find the see more button
+        // SeeMoreIntent is null in MediaOutputPanel, so the see more button will not visible.
+        UiObject2 seeMoreView = mDevice.findObject(By.res(mSettingsPackage, RESOURCE_SEE_MORE));
+        assertThat(seeMoreView).isNull();
+    }
+
     private void launchVolumePanel() {
         launchPanel(Settings.Panel.ACTION_VOLUME);
     }
@@ -269,6 +331,10 @@
         launchPanel(Settings.Panel.ACTION_INTERNET_CONNECTIVITY);
     }
 
+    private void launchMediaOutputPanel(String packageName) {
+        launchPanel(ACTION_MEDIA_OUTPUT, packageName);
+    }
+
     private void launchNfcPanel() {
         assumeTrue(mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_NFC));
         launchPanel(Settings.Panel.ACTION_NFC);
@@ -280,6 +346,10 @@
     }
 
     private void launchPanel(String action) {
+        launchPanel(action,  null /* packageName */);
+    }
+
+    private void launchPanel(String action, String packageName) {
         // Start from the home screen
         mDevice.pressHome();
         mDevice.wait(Until.hasObject(By.pkg(mLauncherPackage).depth(0)), TIMEOUT);
@@ -287,6 +357,7 @@
         Intent intent = new Intent(action);
         intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK
                 | Intent.FLAG_ACTIVITY_CLEAR_TASK);    // Clear out any previous instances
+        intent.putExtra(EXTRA_PACKAGE_NAME, packageName);
         mContext.startActivity(intent);
 
         // Wait for the app to appear
diff --git a/tests/tests/provider/src/android/provider/cts/media/MediaStoreTest.java b/tests/tests/provider/src/android/provider/cts/media/MediaStoreTest.java
index 7b2e562..37ed546 100644
--- a/tests/tests/provider/src/android/provider/cts/media/MediaStoreTest.java
+++ b/tests/tests/provider/src/android/provider/cts/media/MediaStoreTest.java
@@ -148,6 +148,15 @@
     }
 
     @Test
+    public void testGetRecentExternalVolumeNames() {
+        Set<String> volumeNames = MediaStore.getRecentExternalVolumeNames(getContext());
+
+        assertFalse(volumeNames.contains(MediaStore.VOLUME_INTERNAL));
+        assertFalse(volumeNames.contains(MediaStore.VOLUME_EXTERNAL));
+        assertTrue(volumeNames.contains(MediaStore.VOLUME_EXTERNAL_PRIMARY));
+    }
+
+    @Test
     public void testGetStorageVolume() throws Exception {
         Assume.assumeFalse(MediaStore.VOLUME_EXTERNAL.equals(mVolumeName));
 
diff --git a/tests/tests/provider/src/android/provider/cts/media/MediaStore_Audio_AlbumsTest.java b/tests/tests/provider/src/android/provider/cts/media/MediaStore_Audio_AlbumsTest.java
index ca0413c..2621949 100644
--- a/tests/tests/provider/src/android/provider/cts/media/MediaStore_Audio_AlbumsTest.java
+++ b/tests/tests/provider/src/android/provider/cts/media/MediaStore_Audio_AlbumsTest.java
@@ -202,6 +202,7 @@
 
             // Delete item and confirm art is cleaned up
             mContentResolver.delete(mediaUri, null, null);
+            MediaStore.waitForIdle(mContentResolver);
 
             try {
                 mContentResolver.loadThumbnail(mediaUri, new Size(32, 32), null);
diff --git a/tests/tests/security/AndroidTest.xml b/tests/tests/security/AndroidTest.xml
index 4dfec996..45220d9 100644
--- a/tests/tests/security/AndroidTest.xml
+++ b/tests/tests/security/AndroidTest.xml
@@ -17,7 +17,7 @@
     <option name="test-suite-tag" value="cts" />
     <option name="config-descriptor:metadata" key="component" value="security" />
     <option name="config-descriptor:metadata" key="parameter" value="not_multi_abi" />
-    <option name="config-descriptor:metadata" key="parameter" value="not_instant_app" />
+    <option name="config-descriptor:metadata" key="parameter" value="instant_app" />
     <option name="config-descriptor:metadata" key="parameter" value="secondary_user" />
     <target_preparer class="com.android.tradefed.targetprep.suite.SuiteApkInstaller">
         <option name="cleanup-apks" value="true" />
diff --git a/tests/tests/security/src/android/security/cts/ActivityManagerTest.java b/tests/tests/security/src/android/security/cts/ActivityManagerTest.java
index 5a035dd..47730e1 100644
--- a/tests/tests/security/src/android/security/cts/ActivityManagerTest.java
+++ b/tests/tests/security/src/android/security/cts/ActivityManagerTest.java
@@ -15,11 +15,15 @@
  */
 package android.security.cts;
 
+import android.app.ActivityManager;
 import android.os.IBinder;
 import android.platform.test.annotations.SecurityTest;
+import android.util.Log;
 
 import junit.framework.TestCase;
 
+import java.lang.reflect.InvocationTargetException;
+
 @SecurityTest
 public class ActivityManagerTest extends TestCase {
 
@@ -44,4 +48,32 @@
             // Patched devices should throw this exception
         }
     }
+
+    // b/144285917
+    @SecurityTest(minPatchLevel = "2020-05")
+    public void testActivityManager_attachNullApplication() {
+        SecurityException securityException = null;
+        Exception unexpectedException = null;
+        try {
+            final Object iam = ActivityManager.class.getDeclaredMethod("getService").invoke(null);
+            Class.forName("android.app.IActivityManager").getDeclaredMethod("attachApplication",
+                    Class.forName("android.app.IApplicationThread"), long.class)
+                    .invoke(iam, null /* thread */, 0 /* startSeq */);
+        } catch (SecurityException e) {
+            securityException = e;
+        } catch (InvocationTargetException e) {
+            if (e.getCause() instanceof SecurityException) {
+                securityException = (SecurityException) e.getCause();
+            } else {
+                unexpectedException = e;
+            }
+        } catch (Exception e) {
+            unexpectedException = e;
+        }
+        if (unexpectedException != null) {
+            Log.w("ActivityManagerTest", "Unexpected exception", unexpectedException);
+        }
+
+        assertNotNull("Expect SecurityException by attaching null application", securityException);
+    }
 }
diff --git a/tests/tests/security/src/android/security/cts/NanoAppBundleTest.java b/tests/tests/security/src/android/security/cts/NanoAppBundleTest.java
index e7ab8eb..a324fd7 100644
--- a/tests/tests/security/src/android/security/cts/NanoAppBundleTest.java
+++ b/tests/tests/security/src/android/security/cts/NanoAppBundleTest.java
@@ -48,9 +48,11 @@
 
 import android.util.Log;
 import android.annotation.Nullable;
+import android.platform.test.annotations.AppModeFull;
 import static java.lang.Thread.sleep;
 import static org.junit.Assert.assertTrue;
 
+@AppModeFull
 @SecurityTest
 public class NanoAppBundleTest extends AndroidTestCase {
 
diff --git a/tests/tests/security/src/android/security/cts/StagefrightTest.java b/tests/tests/security/src/android/security/cts/StagefrightTest.java
index 6b122da..875bc91 100644
--- a/tests/tests/security/src/android/security/cts/StagefrightTest.java
+++ b/tests/tests/security/src/android/security/cts/StagefrightTest.java
@@ -111,17 +111,17 @@
 
     @SecurityTest(minPatchLevel = "2016-08")
     public void testStagefright_cve_2016_3829() throws Exception {
-        doStagefrightTest(R.raw.cve_2016_3829, false);
+        doStagefrightTest(R.raw.cve_2016_3829, new CrashUtils.Config().checkMinAddress(false));
     }
 
     @SecurityTest(minPatchLevel = "2017-06")
     public void testStagefright_cve_2017_0643() throws Exception {
-        doStagefrightTest(R.raw.cve_2017_0643, false);
+        doStagefrightTest(R.raw.cve_2017_0643, new CrashUtils.Config().checkMinAddress(false));
     }
 
     @SecurityTest(minPatchLevel = "2017-08")
     public void testStagefright_cve_2017_0728() throws Exception {
-        doStagefrightTest(R.raw.cve_2017_0728, false);
+        doStagefrightTest(R.raw.cve_2017_0728, new CrashUtils.Config().checkMinAddress(false));
     }
 
     @SecurityTest(minPatchLevel = "2017-10")
@@ -161,7 +161,7 @@
 
     @SecurityTest(minPatchLevel = "2017-06")
     public void testStagefright_bug_35763994() throws Exception {
-        doStagefrightTest(R.raw.bug_35763994, false);
+        doStagefrightTest(R.raw.bug_35763994, new CrashUtils.Config().checkMinAddress(false));
     }
 
     @SecurityTest(minPatchLevel = "2017-03")
@@ -171,7 +171,7 @@
 
     @SecurityTest(minPatchLevel = "2017-07")
     public void testStagefright_cve_2016_2507() throws Exception {
-        doStagefrightTest(R.raw.cve_2016_2507, false);
+        doStagefrightTest(R.raw.cve_2016_2507, new CrashUtils.Config().checkMinAddress(false));
     }
 
     @SecurityTest(minPatchLevel = "2017-03")
@@ -266,13 +266,14 @@
 
     @SecurityTest(minPatchLevel = "2017-02")
     public void testStagefright_cve_2016_2429_b_27211885() throws Exception {
-        doStagefrightTest(R.raw.cve_2016_2429_b_27211885, false);
+        doStagefrightTest(R.raw.cve_2016_2429_b_27211885,
+                new CrashUtils.Config().checkMinAddress(false));
     }
 
     @SecurityTest(minPatchLevel = "2017-08")
     public void testStagefright_bug_34031018() throws Exception {
-        doStagefrightTest(R.raw.bug_34031018_32bit, false);
-        doStagefrightTest(R.raw.bug_34031018_64bit, false);
+        doStagefrightTest(R.raw.bug_34031018_32bit, new CrashUtils.Config().checkMinAddress(false));
+        doStagefrightTest(R.raw.bug_34031018_64bit, new CrashUtils.Config().checkMinAddress(false));
     }
 
     /***********************************************************
@@ -297,7 +298,8 @@
 
     @SecurityTest(minPatchLevel = "2018-01")
     public void testStagefright_cve_2017_0852_b_62815506() throws Exception {
-        doStagefrightTest(R.raw.cve_2017_0852_b_62815506, false);
+        doStagefrightTest(R.raw.cve_2017_0852_b_62815506,
+                new CrashUtils.Config().checkMinAddress(false));
     }
 
     @SecurityTest(minPatchLevel = "2018-02")
@@ -323,7 +325,7 @@
 
     @SecurityTest(minPatchLevel = "2016-10")
     public void testStagefright_cve_2016_3920() throws Exception {
-        doStagefrightTest(R.raw.cve_2016_3920, false);
+        doStagefrightTest(R.raw.cve_2016_3920, new CrashUtils.Config().checkMinAddress(false));
     }
 
     @SecurityTest(minPatchLevel = "2018-06")
@@ -338,7 +340,7 @@
 
     @SecurityTest(minPatchLevel = "2016-08")
     public void testStagefright_cve_2016_3821() throws Exception {
-        doStagefrightTest(R.raw.cve_2016_3821, false);
+        doStagefrightTest(R.raw.cve_2016_3821, new CrashUtils.Config().checkMinAddress(false));
     }
 
     @SecurityTest(minPatchLevel = "2018-04")
@@ -358,12 +360,12 @@
 
     @SecurityTest(minPatchLevel = "2017-09")
     public void testStagefright_bug_38115076() throws Exception {
-        doStagefrightTest(R.raw.bug_38115076, false);
+        doStagefrightTest(R.raw.bug_38115076, new CrashUtils.Config().checkMinAddress(false));
     }
 
     @SecurityTest(minPatchLevel = "2017-05")
     public void testStagefright_bug_34618607() throws Exception {
-        doStagefrightTest(R.raw.bug_34618607, false);
+        doStagefrightTest(R.raw.bug_34618607, new CrashUtils.Config().checkMinAddress(false));
     }
 
     @SecurityTest(minPatchLevel = "2018-02")
@@ -388,13 +390,14 @@
 
     @SecurityTest(minPatchLevel = "2017-05")
     public void testStagefright_cve_2017_0600() throws Exception {
-        doStagefrightTest(R.raw.cve_2017_0600, false);
+        doStagefrightTest(R.raw.cve_2017_0600, new CrashUtils.Config().checkMinAddress(false));
     }
 
     @SecurityTest(minPatchLevel = "2017-08")
     public void testBug_38014992() throws Exception {
         int[] frameSizes = getFrameSizes(R.raw.bug_38014992_framelen);
-        doStagefrightTestRawBlob(R.raw.bug_38014992_avc, "video/avc", 640, 480, frameSizes, false);
+        doStagefrightTestRawBlob(R.raw.bug_38014992_avc, "video/avc", 640, 480, frameSizes,
+                new CrashUtils.Config().checkMinAddress(false));
     }
 
     @SecurityTest(minPatchLevel = "2017-07")
@@ -424,7 +427,8 @@
     @SecurityTest(minPatchLevel = "2017-03")
     public void testBug_33387820() throws Exception {
         int[] frameSizes = {45, 3202, 430, 2526};
-        doStagefrightTestRawBlob(R.raw.bug_33387820_avc, "video/avc", 320, 240, frameSizes, false);
+        doStagefrightTestRawBlob(R.raw.bug_33387820_avc, "video/avc", 320, 240, frameSizes,
+                new CrashUtils.Config().checkMinAddress(false));
     }
 
     @SecurityTest(minPatchLevel = "2017-07")
@@ -461,13 +465,15 @@
     public void testBug_28816956() throws Exception {
         int[] frameSizes = getFrameSizes(R.raw.bug_28816956_framelen);
         doStagefrightTestRawBlob(
-                R.raw.bug_28816956_hevc, "video/hevc", 352, 288, frameSizes, false);
+                R.raw.bug_28816956_hevc, "video/hevc", 352, 288, frameSizes,
+                    new CrashUtils.Config().checkMinAddress(false));
     }
 
     @SecurityTest(minPatchLevel = "2017-03")
     public void testBug_33818500() throws Exception {
         int[] frameSizes = getFrameSizes(R.raw.bug_33818500_framelen);
-        doStagefrightTestRawBlob(R.raw.bug_33818500_avc, "video/avc", 64, 32, frameSizes, false);
+        doStagefrightTestRawBlob(R.raw.bug_33818500_avc, "video/avc", 64, 32, frameSizes,
+                new CrashUtils.Config().checkMinAddress(false));
     }
 
     @SecurityTest(minPatchLevel = "2018-01")
@@ -496,7 +502,7 @@
 
     @SecurityTest(minPatchLevel = "2017-05")
     public void testStagefright_cve_2017_0599() throws Exception {
-        doStagefrightTest(R.raw.cve_2017_0599, false);
+        doStagefrightTest(R.raw.cve_2017_0599, new CrashUtils.Config().checkMinAddress(false));
     }
 
     @SecurityTest(minPatchLevel = "2017-09")
@@ -526,7 +532,7 @@
 
     @SecurityTest(minPatchLevel = "2017-09")
     public void testStagefright_cve_2016_6712() throws Exception {
-        doStagefrightTest(R.raw.cve_2016_6712, false);
+        doStagefrightTest(R.raw.cve_2016_6712, new CrashUtils.Config().checkMinAddress(false));
     }
 
     @SecurityTest(minPatchLevel = "2017-04")
@@ -552,12 +558,12 @@
 
     @SecurityTest(minPatchLevel = "2017-06")
     public void testStagefright_bug_33818508() throws Exception {
-        doStagefrightTest(R.raw.bug_33818508, false);
+        doStagefrightTest(R.raw.bug_33818508, new CrashUtils.Config().checkMinAddress(false));
     }
 
     @SecurityTest(minPatchLevel = "2017-08")
     public void testStagefright_bug_32873375() throws Exception {
-        doStagefrightTest(R.raw.bug_32873375, false);
+        doStagefrightTest(R.raw.bug_32873375, new CrashUtils.Config().checkMinAddress(false));
     }
 
     @SecurityTest(minPatchLevel = "2018-02")
@@ -620,7 +626,7 @@
 
     @SecurityTest(minPatchLevel = "2016-06")
     public void testStagefright_cve_2016_2428() throws Exception {
-        doStagefrightTest(R.raw.cve_2016_2428, false);
+        doStagefrightTest(R.raw.cve_2016_2428, new CrashUtils.Config().checkMinAddress(false));
     }
 
     @SecurityTest(minPatchLevel = "2016-07")
@@ -658,7 +664,8 @@
                 @Override
                 public void run() {
                     try {
-                        doStagefrightTestMediaCodec(tempFile.getAbsolutePath(), false);
+                        doStagefrightTestMediaCodec(tempFile.getAbsolutePath(),
+                                new CrashUtils.Config().checkMinAddress(false));
                     } catch (Exception | AssertionError e) {
                         if (!tempFile.delete()) {
                             Log.e(TAG, "Failed to delete temporary PoC file");
@@ -683,7 +690,7 @@
 
     @SecurityTest(minPatchLevel = "2017-06")
     public void testStagefright_bug_32322258() throws Exception {
-        doStagefrightTest(R.raw.bug_32322258, false);
+        doStagefrightTest(R.raw.bug_32322258, new CrashUtils.Config().checkMinAddress(false));
     }
 
     @SecurityTest(minPatchLevel = "2015-10")
@@ -713,7 +720,8 @@
 
     @SecurityTest(minPatchLevel = "2015-10")
     public void testStagefright_cve_2015_3862_b_22954006() throws Exception {
-        doStagefrightTest(R.raw.cve_2015_3862_b_22954006, false);
+        doStagefrightTest(R.raw.cve_2015_3862_b_22954006,
+                new CrashUtils.Config().checkMinAddress(false));
     }
 
     @SecurityTest(minPatchLevel = "2015-10")
@@ -778,12 +786,13 @@
 
     @SecurityTest(minPatchLevel = "2016-07")
     public void testStagefright_cve_2016_3755() throws Exception {
-        doStagefrightTest(R.raw.cve_2016_3755, false);
+        doStagefrightTest(R.raw.cve_2016_3755, new CrashUtils.Config().checkMinAddress(false));
     }
 
     @SecurityTest(minPatchLevel = "2016-09")
     public void testStagefright_cve_2016_3878_b_29493002() throws Exception {
-        doStagefrightTest(R.raw.cve_2016_3878_b_29493002, false);
+        doStagefrightTest(R.raw.cve_2016_3878_b_29493002,
+                new CrashUtils.Config().checkMinAddress(false));
     }
 
     @SecurityTest(minPatchLevel = "2017-08")
@@ -803,12 +812,12 @@
 
     @SecurityTest(minPatchLevel = "2016-06")
     public void testStagefright_bug_27855419_CVE_2016_2463() throws Exception {
-        doStagefrightTest(R.raw.bug_27855419, false);
+        doStagefrightTest(R.raw.bug_27855419, new CrashUtils.Config().checkMinAddress(false));
     }
 
     @SecurityTest(minPatchLevel = "2015-11")
     public void testStagefright_bug_19779574() throws Exception {
-        doStagefrightTest(R.raw.bug_19779574, false);
+        doStagefrightTest(R.raw.bug_19779574, new CrashUtils.Config().checkMinAddress(false));
     }
 
     /***********************************************************
@@ -823,7 +832,7 @@
 
     @SecurityTest(minPatchLevel = "2017-07")
     public void testStagefright_bug_36279112() throws Exception {
-        doStagefrightTest(R.raw.bug_36279112, false);
+        doStagefrightTest(R.raw.bug_36279112, new CrashUtils.Config().checkMinAddress(false));
     }
 
     @SecurityTest(minPatchLevel = "2017-06")
@@ -905,7 +914,8 @@
         };
         server.start();
         String uri = "http://127.0.0.1:8080/bug_68342866.m3u8";
-        final MediaPlayerCrashListener mpcl = new MediaPlayerCrashListener(false);
+        final MediaPlayerCrashListener mpcl =
+                new MediaPlayerCrashListener(new CrashUtils.Config().checkMinAddress(false));
         LooperThread t = new LooperThread(new Runnable() {
             @Override
             public void run() {
@@ -1071,7 +1081,7 @@
 
     @SecurityTest(minPatchLevel = "2016-12")
     public void testStagefright_cve_2016_6764() throws Exception {
-        doStagefrightTest(R.raw.cve_2016_6764, false);
+        doStagefrightTest(R.raw.cve_2016_6764, new CrashUtils.Config().checkMinAddress(false));
     }
 
     @SecurityTest(minPatchLevel = "2018-01")
@@ -1081,7 +1091,7 @@
 
     @SecurityTest(minPatchLevel = "2017-06")
     public void testStagefright_bug_35467107() throws Exception {
-        doStagefrightTest(R.raw.bug_35467107, false);
+        doStagefrightTest(R.raw.bug_35467107, new CrashUtils.Config().checkMinAddress(false));
     }
 
     /***********************************************************
@@ -1217,12 +1227,12 @@
 
     @SecurityTest(minPatchLevel = "2016-12")
     public void testStagefright_cve_2016_6765() throws Exception {
-        doStagefrightTest(R.raw.cve_2016_6765, false);
+        doStagefrightTest(R.raw.cve_2016_6765, new CrashUtils.Config().checkMinAddress(false));
     }
 
     @SecurityTest(minPatchLevel = "2016-07")
     public void testStagefright_cve_2016_2508() throws Exception {
-        doStagefrightTest(R.raw.cve_2016_2508, false);
+        doStagefrightTest(R.raw.cve_2016_2508, new CrashUtils.Config().checkMinAddress(false));
     }
 
     @SecurityTest(minPatchLevel = "2016-11")
@@ -1242,19 +1252,19 @@
 
     @SecurityTest(minPatchLevel = "2016-09")
     public void testStagefright_cve_2016_3879() throws Exception {
-        doStagefrightTest(R.raw.cve_2016_3879, false);
+        doStagefrightTest(R.raw.cve_2016_3879, new CrashUtils.Config().checkMinAddress(false));
     }
 
     private void doStagefrightTest(final int rid) throws Exception {
-        doStagefrightTest(rid, true); // check addresss by default
+        doStagefrightTest(rid, null);
     }
 
-    private void doStagefrightTest(final int rid, boolean checkMinCrashAddress) throws Exception {
+    private void doStagefrightTest(final int rid, CrashUtils.Config config) throws Exception {
         NetworkSecurityPolicy policy = NetworkSecurityPolicy.getInstance();
         policy.setCleartextTrafficPermitted(true);
-        doStagefrightTestMediaPlayer(rid, checkMinCrashAddress);
-        doStagefrightTestMediaCodec(rid, checkMinCrashAddress);
-        doStagefrightTestMediaMetadataRetriever(rid, checkMinCrashAddress);
+        doStagefrightTestMediaPlayer(rid, config);
+        doStagefrightTestMediaCodec(rid, config);
+        doStagefrightTestMediaMetadataRetriever(rid, config);
 
         Context context = getInstrumentation().getContext();
         CtsTestServer server = null;
@@ -1270,10 +1280,10 @@
         String rname = resources.getResourceEntryName(rid);
         String url = server.getAssetUrl("raw/" + rname);
         verifyServer(rid, url);
-        doStagefrightTestMediaPlayer(url, checkMinCrashAddress);
-        doStagefrightTestMediaCodec(url, checkMinCrashAddress);
-        doStagefrightTestMediaMetadataRetriever(url, checkMinCrashAddress);
         policy.setCleartextTrafficPermitted(false);
+        doStagefrightTestMediaPlayer(url, config);
+        doStagefrightTestMediaCodec(url, config);
+        doStagefrightTestMediaMetadataRetriever(url, config);
         server.shutdown();
     }
 
@@ -1303,16 +1313,16 @@
     }
 
     private void doStagefrightTest(final int rid, int timeout) throws Exception {
-        doStagefrightTest(rid, true, timeout); // check crash address by default
+        doStagefrightTest(rid, null, timeout);
     }
 
     private void doStagefrightTest(
-            final int rid, boolean checkMinCrashAddress, int timeout) throws Exception {
+            final int rid, CrashUtils.Config config, int timeout) throws Exception {
         runWithTimeout(new Runnable() {
             @Override
             public void run() {
                 try {
-                  doStagefrightTest(rid, checkMinCrashAddress);
+                  doStagefrightTest(rid, config);
                 } catch (Exception e) {
                   fail(e.toString());
                 }
@@ -1321,12 +1331,12 @@
     }
 
     private void doStagefrightTestANR(final int rid) throws Exception {
-        doStagefrightTestANR(rid, true); // check crash address by default
+        doStagefrightTestANR(rid, null);
     }
 
     private void doStagefrightTestANR(
-            final int rid, boolean checkMinCrashAddress) throws Exception {
-        doStagefrightTestMediaPlayerANR(rid, null);
+            final int rid, CrashUtils.Config config) throws Exception {
+        doStagefrightTestMediaPlayerANR(rid, null, config);
     }
 
     public JSONArray getCrashReport(String testname, long timeout)
@@ -1360,7 +1370,7 @@
         MediaPlayer.OnPreparedListener,
         MediaPlayer.OnCompletionListener {
 
-        boolean checkMinAddress = true;
+        CrashUtils.Config config;
 
         private final Pattern[] validProcessPatterns = {
             Pattern.compile("adsprpcd"),
@@ -1384,10 +1394,16 @@
         };
 
         MediaPlayerCrashListener() {
+            this(null);
         }
 
-        MediaPlayerCrashListener(boolean checkMinAddress) {
-            this.checkMinAddress = checkMinAddress;
+        MediaPlayerCrashListener(CrashUtils.Config config) {
+            if (config == null) {
+                config = new CrashUtils.Config();
+            }
+            // if a different process is needed for a test, it should be added to the main list.
+            config.setProcessPatterns(validProcessPatterns);
+            this.config = config;
         }
 
         @Override
@@ -1435,8 +1451,7 @@
                 if (crashes == null) {
                     Log.e(TAG, "Crash results not found for test " + getName());
                     return what;
-                } else if (CrashUtils.securityCrashDetected(
-                        crashes, checkMinAddress, validProcessPatterns)) {
+                } else if (CrashUtils.securityCrashDetected(crashes, config)) {
                     return what;
                 } else {
                     Log.i(TAG, "Crash ignored due to no security crash found for test " +
@@ -1484,21 +1499,21 @@
     }
 
     private void doStagefrightTestMediaPlayer(final int rid) throws Exception {
-        doStagefrightTestMediaPlayer(rid, true); // check crash address by default
+        doStagefrightTestMediaPlayer(rid, null, null);
     }
 
     private void doStagefrightTestMediaPlayer(
-            final int rid, boolean checkMinCrashAddress) throws Exception {
-        doStagefrightTestMediaPlayer(rid, null, checkMinCrashAddress);
+            final int rid, CrashUtils.Config config) throws Exception {
+        doStagefrightTestMediaPlayer(rid, null, config);
     }
 
     private void doStagefrightTestMediaPlayer(final String url) throws Exception {
-        doStagefrightTestMediaPlayer(url, true); // check crash address by default
+        doStagefrightTestMediaPlayer(url, null);
     }
 
     private void doStagefrightTestMediaPlayer(
-            final String url, boolean checkMinCrashAddress) throws Exception {
-        doStagefrightTestMediaPlayer(-1, url, checkMinCrashAddress);
+            final String url, CrashUtils.Config config) throws Exception {
+        doStagefrightTestMediaPlayer(-1, url, config);
     }
 
     private void closeQuietly(AutoCloseable closeable) {
@@ -1513,17 +1528,17 @@
     }
 
     private void doStagefrightTestMediaPlayer(final int rid, final String uri) throws Exception {
-        doStagefrightTestMediaPlayer(rid, uri, true); // check crash address by default
+        doStagefrightTestMediaPlayer(rid, uri, null);
     }
 
     private void doStagefrightTestMediaPlayer(final int rid, final String uri,
-            boolean checkMinCrashAddress) throws Exception {
+            CrashUtils.Config config) throws Exception {
 
         String name = uri != null ? uri :
             getInstrumentation().getContext().getResources().getResourceEntryName(rid);
         Log.i(TAG, "start mediaplayer test for: " + name);
 
-        final MediaPlayerCrashListener mpcl = new MediaPlayerCrashListener(checkMinCrashAddress);
+        final MediaPlayerCrashListener mpcl = new MediaPlayerCrashListener(config);
 
         LooperThread t = new LooperThread(new Runnable() {
             @Override
@@ -1644,31 +1659,31 @@
     }
 
     private void doStagefrightTestMediaCodec(final int rid) throws Exception {
-        doStagefrightTestMediaCodec(rid, true); // check crash address by default
+        doStagefrightTestMediaCodec(rid, null, null);
     }
 
     private void doStagefrightTestMediaCodec(
-            final int rid, boolean checkMinCrashAddress) throws Exception {
-        doStagefrightTestMediaCodec(rid, null, checkMinCrashAddress);
+            final int rid, CrashUtils.Config config) throws Exception {
+        doStagefrightTestMediaCodec(rid, null, config);
     }
 
     private void doStagefrightTestMediaCodec(final String url) throws Exception {
-        doStagefrightTestMediaCodec(url, true); // check crash address by default
+        doStagefrightTestMediaCodec(url, null);
     }
 
     private void doStagefrightTestMediaCodec(
-            final String url, boolean checkMinCrashAddress) throws Exception {
-        doStagefrightTestMediaCodec(-1, url, checkMinCrashAddress);
+            final String url, CrashUtils.Config config) throws Exception {
+        doStagefrightTestMediaCodec(-1, url, config);
     }
 
     private void doStagefrightTestMediaCodec(final int rid, final String url) throws Exception {
-        doStagefrightTestMediaCodec(rid, url, true); // check crash address by default
+        doStagefrightTestMediaCodec(rid, url, null);
     }
 
     private void doStagefrightTestMediaCodec(
-            final int rid, final String url, boolean checkMinCrashAddress) throws Exception {
+            final int rid, final String url, CrashUtils.Config config) throws Exception {
 
-        final MediaPlayerCrashListener mpcl = new MediaPlayerCrashListener(checkMinCrashAddress);
+        final MediaPlayerCrashListener mpcl = new MediaPlayerCrashListener(config);
 
         LooperThread thr = new LooperThread(new Runnable() {
             @Override
@@ -1826,31 +1841,31 @@
     }
 
     private void doStagefrightTestMediaMetadataRetriever(final int rid) throws Exception {
-        doStagefrightTestMediaMetadataRetriever(rid, true); // check crash address by default
+        doStagefrightTestMediaMetadataRetriever(rid, null, null);
     }
     private void doStagefrightTestMediaMetadataRetriever(
-            final int rid, boolean checkMinCrashAddress) throws Exception {
-        doStagefrightTestMediaMetadataRetriever(rid, null, checkMinCrashAddress);
+            final int rid, CrashUtils.Config config) throws Exception {
+        doStagefrightTestMediaMetadataRetriever(rid, null, config);
     }
 
     private void doStagefrightTestMediaMetadataRetriever(final String url) throws Exception {
-        doStagefrightTestMediaMetadataRetriever(url, true); // check crash address by default
+        doStagefrightTestMediaMetadataRetriever(url, null);
     }
 
     private void doStagefrightTestMediaMetadataRetriever(
-            final String url, boolean checkMinCrashAddress) throws Exception {
-        doStagefrightTestMediaMetadataRetriever(-1, url, checkMinCrashAddress);
+            final String url, CrashUtils.Config config) throws Exception {
+        doStagefrightTestMediaMetadataRetriever(-1, url, config);
     }
 
     private void doStagefrightTestMediaMetadataRetriever(
             final int rid, final String url) throws Exception {
-        doStagefrightTestMediaMetadataRetriever(rid, url, true); // check crash address by default
+        doStagefrightTestMediaMetadataRetriever(rid, url, null);
     }
 
     private void doStagefrightTestMediaMetadataRetriever(
-            final int rid, final String url, boolean checkMinCrashAddress) throws Exception {
+            final int rid, final String url, CrashUtils.Config config) throws Exception {
 
-        final MediaPlayerCrashListener mpcl = new MediaPlayerCrashListener(checkMinCrashAddress);
+        final MediaPlayerCrashListener mpcl = new MediaPlayerCrashListener(config);
 
         LooperThread thr = new LooperThread(new Runnable() {
             @Override
@@ -1925,12 +1940,14 @@
 
     @SecurityTest(minPatchLevel = "2017-08")
     public void testBug36816007() throws Exception {
-        doStagefrightTestRawBlob(R.raw.bug_36816007, "video/avc", 320, 240, false);
+        doStagefrightTestRawBlob(R.raw.bug_36816007, "video/avc", 320, 240,
+                new CrashUtils.Config().checkMinAddress(false));
     }
 
     @SecurityTest(minPatchLevel = "2017-05")
     public void testBug36895511() throws Exception {
-        doStagefrightTestRawBlob(R.raw.bug_36895511, "video/hevc", 320, 240, false);
+        doStagefrightTestRawBlob(R.raw.bug_36895511, "video/hevc", 320, 240,
+                new CrashUtils.Config().checkMinAddress(false));
     }
 
     @SecurityTest(minPatchLevel = "2017-11")
@@ -1960,7 +1977,8 @@
 
     @SecurityTest(minPatchLevel = "2018-04")
     public void testBug_70897394() throws Exception {
-        doStagefrightTestRawBlob(R.raw.bug_70897394_avc, "video/avc", 320, 240, false);
+        doStagefrightTestRawBlob(R.raw.bug_70897394_avc, "video/avc", 320, 240,
+                new CrashUtils.Config().checkMinAddress(false));
     }
 
     @SecurityTest(minPatchLevel = "Unknown")
@@ -2032,14 +2050,13 @@
 
     private void doStagefrightTestRawBlob(
             int rid, String mime, int initWidth, int initHeight) throws Exception {
-        // check crash address by default
-        doStagefrightTestRawBlob(rid, mime, initWidth, initHeight, true);
+        doStagefrightTestRawBlob(rid, mime, initWidth, initHeight, new CrashUtils.Config());
     }
 
     private void doStagefrightTestRawBlob(int rid, String mime, int initWidth, int initHeight,
-            boolean checkMinCrashAddress) throws Exception {
+            CrashUtils.Config config) throws Exception {
 
-        final MediaPlayerCrashListener mpcl = new MediaPlayerCrashListener(checkMinCrashAddress);
+        final MediaPlayerCrashListener mpcl = new MediaPlayerCrashListener(config);
         final Context context = getInstrumentation().getContext();
         final Resources resources =  context.getResources();
 
@@ -2154,13 +2171,13 @@
     private void doStagefrightTestRawBlob(int rid, String mime, int initWidth, int initHeight,
             int frameSizes[]) throws Exception {
         // check crash address by default
-        doStagefrightTestRawBlob(rid, mime, initWidth, initHeight, frameSizes, true);
+        doStagefrightTestRawBlob(rid, mime, initWidth, initHeight, frameSizes, new CrashUtils.Config());
     }
 
     private void doStagefrightTestRawBlob(int rid, String mime, int initWidth, int initHeight,
-            int frameSizes[], boolean checkMinCrashAddress) throws Exception {
+            int frameSizes[], CrashUtils.Config config) throws Exception {
 
-        final MediaPlayerCrashListener mpcl = new MediaPlayerCrashListener(checkMinCrashAddress);
+        final MediaPlayerCrashListener mpcl = new MediaPlayerCrashListener(config);
         final Context context = getInstrumentation().getContext();
         final Resources resources =  context.getResources();
 
@@ -2294,16 +2311,16 @@
     }
 
     private void doStagefrightTestMediaPlayerANR(final int rid, final String uri) throws Exception {
-        doStagefrightTestMediaPlayerANR(rid, uri, true); // check crash address by default
+        doStagefrightTestMediaPlayerANR(rid, uri, null);
     }
 
     private void doStagefrightTestMediaPlayerANR(final int rid, final String uri,
-            boolean checkMinCrashAddress) throws Exception {
+            CrashUtils.Config config) throws Exception {
         String name = uri != null ? uri :
             getInstrumentation().getContext().getResources().getResourceEntryName(rid);
         Log.i(TAG, "start mediaplayerANR test for: " + name);
 
-        final MediaPlayerCrashListener mpl = new MediaPlayerCrashListener(checkMinCrashAddress);
+        final MediaPlayerCrashListener mpl = new MediaPlayerCrashListener(config);
 
         LooperThread t = new LooperThread(new Runnable() {
             @Override
@@ -2347,12 +2364,12 @@
     }
 
     private void doStagefrightTestExtractorSeek(final int rid, final long offset) throws Exception {
-        doStagefrightTestExtractorSeek(rid, offset, true); // check crash address by default
+        doStagefrightTestExtractorSeek(rid, offset, new CrashUtils.Config()); // check crash address by default
     }
 
     private void doStagefrightTestExtractorSeek(final int rid, final long offset,
-            boolean checkMinCrashAddress) throws Exception {
-        final MediaPlayerCrashListener mpcl = new MediaPlayerCrashListener(checkMinCrashAddress);
+            CrashUtils.Config config) throws Exception {
+        final MediaPlayerCrashListener mpcl = new MediaPlayerCrashListener(config);
         LooperThread thr = new LooperThread(new Runnable() {
             @Override
             public void run() {
diff --git a/tests/appsearch/Android.bp b/tests/tests/sharesheet/Android.bp
similarity index 60%
rename from tests/appsearch/Android.bp
rename to tests/tests/sharesheet/Android.bp
index 1f70dc4..5d1f060 100644
--- a/tests/appsearch/Android.bp
+++ b/tests/tests/sharesheet/Android.bp
@@ -1,4 +1,4 @@
-// Copyright (C) 2019 The Android Open Source Project
+// Copyright (C) 2020 The Android Open Source Project
 //
 // Licensed under the Apache License, Version 2.0 (the "License");
 // you may not use this file except in compliance with the License.
@@ -13,20 +13,28 @@
 // limitations under the License.
 
 android_test {
-    name: "CtsAppSearchTestCases",
+    name: "CtsSharesheetTestCases",
     defaults: ["cts_defaults"],
-    static_libs: [
-      "androidx.test.ext.junit",
-      "androidx.test.rules",
-      "compatibility-device-util-axt",
-    ],
-    srcs: [
-      "src/**/*.java",
-    ],
+
     test_suites: [
-      "cts",
-      "vts",
-      "general-tests",
+        "cts",
+        "vts",
+        "general-tests",
     ],
-    platform_apis: true,
+
+    static_libs: [
+        "ctstestrunner-axt",
+        "compatibility-device-util-axt",
+        "mockito-target-minus-junit4",
+        "ub-uiautomator",
+    ],
+
+    libs: [
+        "android.test.runner.stubs",
+        "android.test.base.stubs",
+    ],
+
+    srcs: ["src/**/*.java"],
+
+    sdk_version: "test_current",
 }
diff --git a/tests/tests/sharesheet/AndroidManifest.xml b/tests/tests/sharesheet/AndroidManifest.xml
new file mode 100644
index 0000000..e501caf
--- /dev/null
+++ b/tests/tests/sharesheet/AndroidManifest.xml
@@ -0,0 +1,76 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ -->
+
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+    package="android.sharesheet.cts">
+
+    <uses-permission android:name="android.permission.DISABLE_KEYGUARD" />
+
+    <!-- Needed permission and android:requestLegacyExternalStorage to dump screenshots in case of
+         failure -->
+    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
+
+    <application 
+        android:requestLegacyExternalStorage="true"
+        android:label="@string/test_app_label">
+
+        <uses-library android:name="android.test.runner" />
+    
+        <activity android:name=".CtsSharesheetDeviceActivity">
+
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+                <category android:name="android.intent.category.LAUNCHER" />
+            </intent-filter>
+
+            <intent-filter>
+                <action android:name="android.intent.action.SEND" />
+                <category android:name="android.intent.category.DEFAULT" />
+                <data android:mimeType="test/cts" />
+            </intent-filter>
+
+            <!-- Used to provide Sharing Shortcuts -->
+            <meta-data android:name="android.app.shortcuts"
+                    android:resource="@xml/shortcuts"/>
+
+            <meta-data android:name="android.service.chooser.chooser_target_service"
+                    android:value=".CtsSharesheetChooserTargetService"/>
+
+        </activity>
+
+        <service android:name=".CtsSharesheetChooserTargetService"
+            android:permission="android.permission.BIND_CHOOSER_TARGET_SERVICE">
+            <intent-filter>
+                <action android:name="android.service.chooser.ChooserTargetService" />
+            </intent-filter>
+        </service>
+
+        <activity-alias android:name=".ExtraInitialIntentTestActivity"
+                        android:label="@string/test_extra_initial_intents_label"
+                        android:targetActivity=".CtsSharesheetDeviceActivity"/>
+
+    </application>
+
+    <instrumentation android:name="androidx.test.runner.AndroidJUnitRunner"
+                     android:targetPackage="android.sharesheet.cts"
+                     android:label="CTS tests of android.sharesheet">
+        <meta-data android:name="listener"
+            android:value="com.android.cts.runner.CtsTestRunListener" />
+    </instrumentation>
+
+</manifest>
+
diff --git a/tests/tests/sharesheet/AndroidTest.xml b/tests/tests/sharesheet/AndroidTest.xml
new file mode 100644
index 0000000..59a4c97
--- /dev/null
+++ b/tests/tests/sharesheet/AndroidTest.xml
@@ -0,0 +1,46 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2020 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+
+<configuration description="Config for CTS Sharesheet test cases">
+    <option name="test-suite-tag" value="cts" />
+    <option name="config-descriptor:metadata" key="component" value="framework" />
+    <!-- Instant apps can't access ShortcutManager -->
+    <option name="config-descriptor:metadata" key="parameter" value="not_instant_app" />
+    <option name="config-descriptor:metadata" key="parameter" value="not_multi_abi" />
+    <option name="config-descriptor:metadata" key="parameter" value="secondary_user" />
+    <option name="not-shardable" value="true" />
+    
+    <target_preparer class="com.android.tradefed.targetprep.suite.SuiteApkInstaller">
+        <option name="cleanup-apks" value="true" />
+        <option name="test-file-name" value="CtsSharesheetTestCases.apk" />
+        <option name="test-file-name" value="CtsSharesheetActivityLabelTester.apk" />
+        <option name="test-file-name" value="CtsSharesheetIntentFilterLabelTester.apk" />
+        <option name="test-file-name" value="CtsSharesheetExcludeTester.apk" />
+    </target_preparer>
+    
+    <test class="com.android.tradefed.testtype.AndroidJUnitTest" >
+        <option name="package" value="android.sharesheet.cts" />
+        <!-- Update hint with appx run time later <option name="runtime-hint" value="7m30s" />-->
+    </test>
+
+    <!-- Collect the files generated on error -->
+    <metrics_collector class="com.android.tradefed.device.metric.FilePullerLogCollector">
+        <option name="directory-keys" value="/sdcard/CtsSharesheetTestCases" />
+        <option name="collect-on-run-ended-only" value="true" />
+        <option name="clean-up" value="false" />
+    </metrics_collector>
+
+</configuration>
diff --git a/tests/tests/sharesheet/OWNERS b/tests/tests/sharesheet/OWNERS
new file mode 100644
index 0000000..8bea7af
--- /dev/null
+++ b/tests/tests/sharesheet/OWNERS
@@ -0,0 +1,6 @@
+# Bug component: 324112
+digman@google.com
+asc@google.com
+dsandler@google.com
+mpietal@google.com
+arangelov@google.com
\ No newline at end of file
diff --git a/tests/tests/sharesheet/packages/Android.bp b/tests/tests/sharesheet/packages/Android.bp
new file mode 100644
index 0000000..12a6838
--- /dev/null
+++ b/tests/tests/sharesheet/packages/Android.bp
@@ -0,0 +1,64 @@
+// Copyright (C) 2020 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+android_test_helper_app {
+    name: "CtsSharesheetActivityLabelTester",
+    defaults: ["cts_defaults"],
+    srcs: ["packages/src/**/*.java"],
+    // tag this module as a cts test artifact
+    test_suites: [
+        "cts",
+        "vts",
+        "general-tests",
+    ],
+    aaptflags: [
+        "--rename-manifest-package",
+        "android.sharesheet.cts.packages.activitylabeltester",
+    ],
+    manifest: "AndroidManifest-ActivityLabelTester.xml",
+}
+
+android_test_helper_app {
+    name: "CtsSharesheetIntentFilterLabelTester",
+    defaults: ["cts_defaults"],
+    srcs: ["packages/src/**/*.java"],
+    // tag this module as a cts test artifact
+    test_suites: [
+        "cts",
+        "vts",
+        "general-tests",
+    ],
+    aaptflags: [
+        "--rename-manifest-package",
+        "android.sharesheet.cts.packages.intentfilterlabeltester",
+    ],
+    manifest: "AndroidManifest-IntentFilterLabelTester.xml",
+}
+
+android_test_helper_app {
+    name: "CtsSharesheetExcludeTester",
+    defaults: ["cts_defaults"],
+    srcs: ["packages/src/**/*.java"],
+    // tag this module as a cts test artifact
+    test_suites: [
+        "cts",
+        "vts",
+        "general-tests",
+    ],
+    aaptflags: [
+        "--rename-manifest-package",
+        "android.sharesheet.cts.packages.excludetester",
+    ],
+    manifest: "AndroidManifest-ExcludeTester.xml",
+}
\ No newline at end of file
diff --git a/tests/tests/sharesheet/packages/AndroidManifest-ActivityLabelTester.xml b/tests/tests/sharesheet/packages/AndroidManifest-ActivityLabelTester.xml
new file mode 100644
index 0000000..9da4a37
--- /dev/null
+++ b/tests/tests/sharesheet/packages/AndroidManifest-ActivityLabelTester.xml
@@ -0,0 +1,41 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ -->
+
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+    package="android.sharesheet.cts.packages">
+
+    <application android:label="App A">
+
+        <activity android:name=".LabelTestActivity" android:label="Activity A">
+
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+                <category android:name="android.intent.category.LAUNCHER" />
+            </intent-filter>
+
+            <intent-filter>
+                <action android:name="android.intent.action.SEND" />
+                <category android:name="android.intent.category.DEFAULT" />
+                <data android:mimeType="test/cts" />
+            </intent-filter>
+
+        </activity>
+
+    </application>
+
+</manifest>
+
diff --git a/tests/tests/sharesheet/packages/AndroidManifest-ExcludeTester.xml b/tests/tests/sharesheet/packages/AndroidManifest-ExcludeTester.xml
new file mode 100644
index 0000000..ca2e79e
--- /dev/null
+++ b/tests/tests/sharesheet/packages/AndroidManifest-ExcludeTester.xml
@@ -0,0 +1,41 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  ~ Copyright (C) 2020 The Android Open Source Project
+  ~
+  ~ Licensed under the Apache License, Version 2.0 (the "License");
+  ~ you may not use this file except in compliance with the License.
+  ~ You may obtain a copy of the License at
+  ~
+  ~      http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing, software
+  ~ distributed under the License is distributed on an "AS IS" BASIS,
+  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  ~ See the License for the specific language governing permissions and
+  ~ limitations under the License.
+  -->
+
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+    package="android.sharesheet.cts.packages">
+
+    <application android:label="Bl Label">
+
+        <activity android:name=".LabelTestActivity">
+
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+                <category android:name="android.intent.category.LAUNCHER" />
+            </intent-filter>
+
+            <intent-filter>
+                <action android:name="android.intent.action.SEND" />
+                <category android:name="android.intent.category.DEFAULT" />
+                <data android:mimeType="test/cts" />
+            </intent-filter>
+
+        </activity>
+
+    </application>
+
+</manifest>
+
diff --git a/tests/tests/sharesheet/packages/AndroidManifest-IntentFilterLabelTester.xml b/tests/tests/sharesheet/packages/AndroidManifest-IntentFilterLabelTester.xml
new file mode 100644
index 0000000..1169b49
--- /dev/null
+++ b/tests/tests/sharesheet/packages/AndroidManifest-IntentFilterLabelTester.xml
@@ -0,0 +1,41 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  ~ Copyright (C) 2020 The Android Open Source Project
+  ~
+  ~ Licensed under the Apache License, Version 2.0 (the "License");
+  ~ you may not use this file except in compliance with the License.
+  ~ You may obtain a copy of the License at
+  ~
+  ~      http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing, software
+  ~ distributed under the License is distributed on an "AS IS" BASIS,
+  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  ~ See the License for the specific language governing permissions and
+  ~ limitations under the License.
+  -->
+
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+    package="android.sharesheet.cts.packages">
+
+    <application android:label="App If">
+
+        <activity android:name=".LabelTestActivity" android:label="Activity If">
+
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+                <category android:name="android.intent.category.LAUNCHER" />
+            </intent-filter>
+
+            <intent-filter android:label="IntentFilter If">
+                <action android:name="android.intent.action.SEND" />
+                <category android:name="android.intent.category.DEFAULT" />
+                <data android:mimeType="test/cts" />
+            </intent-filter>
+
+        </activity>
+
+    </application>
+
+</manifest>
+
diff --git a/tests/tests/sharesheet/packages/src/android/sharesheet/cts/packages/LabelTestActivity.java b/tests/tests/sharesheet/packages/src/android/sharesheet/cts/packages/LabelTestActivity.java
new file mode 100644
index 0000000..564c269
--- /dev/null
+++ b/tests/tests/sharesheet/packages/src/android/sharesheet/cts/packages/LabelTestActivity.java
@@ -0,0 +1,33 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package android.sharesheet.cts.packages;
+
+import android.app.Activity;
+import android.content.Context;
+import android.os.Bundle;
+
+import java.lang.Override;
+
+public class LabelTestActivity extends Activity {
+
+    @Override
+    public void onCreate(Bundle icicle) {
+        super.onCreate(icicle);
+        // This activity may be opened to ensure click behavior functions properly.
+        // To ensure test repeatability do not stay open.
+        finish();
+    }
+}
\ No newline at end of file
diff --git a/tests/tests/sharesheet/res/drawable-nodpi/black_64x64.png b/tests/tests/sharesheet/res/drawable-nodpi/black_64x64.png
new file mode 100644
index 0000000..7cc9373
--- /dev/null
+++ b/tests/tests/sharesheet/res/drawable-nodpi/black_64x64.png
Binary files differ
diff --git a/tests/tests/sharesheet/res/values/strings.xml b/tests/tests/sharesheet/res/values/strings.xml
new file mode 100644
index 0000000..62529b6
--- /dev/null
+++ b/tests/tests/sharesheet/res/values/strings.xml
@@ -0,0 +1,31 @@
+<!--
+  ~ Copyright (C) 2020 The Android Open Source Project
+  ~
+  ~ Licensed under the Apache License, Version 2.0 (the "License");
+  ~ you may not use this file except in compliance with the License.
+  ~ You may obtain a copy of the License at
+  ~
+  ~      http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing, software
+  ~ distributed under the License is distributed on an "AS IS" BASIS,
+  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  ~ See the License for the specific language governing permissions and
+  ~ limitations under the License.
+  -->
+<resources>
+    <!-- All strings are intentionally short to avoid potential issues with truncation -->
+    <string name="test_app_label">App 1</string>
+    <string name="test_activity_label_app">App A</string>
+    <string name="test_activity_label_activity">Activity A</string>
+    <string name="test_intent_filter_label_app">App If</string>
+    <string name="test_intent_filter_label_activity">Activity If</string>
+    <string name="test_intent_filter_label_intentfilter">IntentFilter If</string>
+    <string name="test_blacklist_label">Bl Label</string>
+    <string name="test_chooser_target_service_label">CTS target</string>
+    <string name="test_sharing_shortcut_label">ShS target</string>
+    <string name="test_extra_chooser_targets_label">ECT target</string>
+    <string name="test_extra_initial_intents_label">EII target</string>
+    <string name="test_preview_title">Preview title</string>
+    <string name="test_preview_text">Preview text</string>
+</resources>
diff --git a/tests/tests/sharesheet/res/xml/shortcuts.xml b/tests/tests/sharesheet/res/xml/shortcuts.xml
new file mode 100644
index 0000000..684ebb4
--- /dev/null
+++ b/tests/tests/sharesheet/res/xml/shortcuts.xml
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="utf-8"?>
+<shortcuts xmlns:android="http://schemas.android.com/apk/res/android">
+    <share-target android:targetClass="android.sharesheet.cts.CtsSharesheetDeviceActivity">
+        <data android:mimeType="test/cts"/>
+        <category android:name="CATEGORY_CTS_TEST"/>
+    </share-target>
+</shortcuts>
\ No newline at end of file
diff --git a/tests/tests/sharesheet/src/android/sharesheet/cts/CtsSharesheetChooserTargetService.java b/tests/tests/sharesheet/src/android/sharesheet/cts/CtsSharesheetChooserTargetService.java
new file mode 100644
index 0000000..5fda05f
--- /dev/null
+++ b/tests/tests/sharesheet/src/android/sharesheet/cts/CtsSharesheetChooserTargetService.java
@@ -0,0 +1,44 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package android.sharesheet.cts;
+
+import android.content.ComponentName;
+import android.content.IntentFilter;
+import android.graphics.drawable.Icon;
+import android.os.Bundle;
+import android.service.chooser.ChooserTarget;
+import android.service.chooser.ChooserTargetService;
+
+import java.util.Arrays;
+import java.util.List;
+
+public class CtsSharesheetChooserTargetService extends ChooserTargetService {
+
+	@Override
+	public List<ChooserTarget> onGetChooserTargets(ComponentName componentName,
+			IntentFilter intentFilter) {
+
+    	ChooserTarget ct = new ChooserTarget(
+    			getString(R.string.test_chooser_target_service_label),
+				Icon.createWithResource(this, R.drawable.black_64x64),
+				1f,
+				componentName,
+				new Bundle());
+
+    	ChooserTarget[] ret = {ct};
+    	return Arrays.asList(ret);
+    }
+}
\ No newline at end of file
diff --git a/tests/tests/sharesheet/src/android/sharesheet/cts/CtsSharesheetDeviceActivity.java b/tests/tests/sharesheet/src/android/sharesheet/cts/CtsSharesheetDeviceActivity.java
new file mode 100644
index 0000000..f22a1cf
--- /dev/null
+++ b/tests/tests/sharesheet/src/android/sharesheet/cts/CtsSharesheetDeviceActivity.java
@@ -0,0 +1,33 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package android.sharesheet.cts;
+
+import android.app.Activity;
+import android.content.Context;
+import android.os.Bundle;
+
+import java.lang.Override;
+
+public class CtsSharesheetDeviceActivity extends Activity {
+
+    @Override
+    public void onCreate(Bundle icicle) {
+        super.onCreate(icicle);
+        // This activity may be opened to ensure click behavior functions properly.
+        // To ensure test repeatability do not stay open.
+        finish();
+    }
+}
\ No newline at end of file
diff --git a/tests/tests/sharesheet/src/android/sharesheet/cts/CtsSharesheetDeviceTest.java b/tests/tests/sharesheet/src/android/sharesheet/cts/CtsSharesheetDeviceTest.java
new file mode 100644
index 0000000..52bb7bc
--- /dev/null
+++ b/tests/tests/sharesheet/src/android/sharesheet/cts/CtsSharesheetDeviceTest.java
@@ -0,0 +1,588 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package android.sharesheet.cts;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertTrue;
+
+import android.app.ActivityManager;
+import android.app.Instrumentation;
+import android.app.PendingIntent;
+import android.app.UiAutomation;
+import android.content.BroadcastReceiver;
+import android.content.ComponentName;
+import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.content.pm.LabeledIntent;
+import android.content.pm.PackageManager;
+import android.content.pm.ResolveInfo;
+import android.content.pm.ShortcutInfo;
+import android.content.pm.ShortcutManager;
+import android.graphics.drawable.Icon;
+import android.os.Bundle;
+import android.service.chooser.ChooserTarget;
+import android.support.test.uiautomator.By;
+import android.support.test.uiautomator.BySelector;
+import android.support.test.uiautomator.UiDevice;
+import android.support.test.uiautomator.UiObject2;
+import android.support.test.uiautomator.Until;
+
+import androidx.test.InstrumentationRegistry;
+import androidx.test.runner.AndroidJUnit4;
+
+import java.util.ArrayList;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.TimeUnit;
+import java.util.stream.Collectors;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+/**
+ * TODO: Add JavaDoc
+ */
+@RunWith(AndroidJUnit4.class)
+public class CtsSharesheetDeviceTest {
+
+    public static final String TAG = CtsSharesheetDeviceTest.class.getSimpleName();
+
+    private static final int WAIT_AND_ASSERT_FOUND_TIMEOUT_MS = 5000;
+    private static final int WAIT_AND_ASSERT_NOT_FOUND_TIMEOUT_MS = 2500;
+    private static final int WAIT_FOR_IDLE_TIMEOUT_MS = 5000;
+
+    private static final int MAX_EXTRA_INITIAL_INTENTS_SHOWN = 2;
+    private static final int MAX_EXTRA_CHOOSER_TARGETS_SHOWN = 2;
+
+    private static final String ACTION_INTENT_SENDER_FIRED_ON_CLICK =
+            "android.sharesheet.cts.ACTION_INTENT_SENDER_FIRED_ON_CLICK";
+
+    static final String CTS_DATA_TYPE = "test/cts"; // Special CTS mime type
+    static final String CATEGORY_CTS_TEST = "CATEGORY_CTS_TEST";
+
+    private Context mContext;
+    private Instrumentation mInstrumentation;
+    private UiAutomation mAutomation;
+    public UiDevice mDevice;
+
+    private String mPkg, mExcludePkg, mActivityLabelTesterPkg, mIntentFilterLabelTesterPkg;
+    private String mSharesheetPkg;
+
+    private ActivityManager mActivityManager;
+    private ShortcutManager mShortcutManager;
+
+    private String mAppLabel,
+            mActivityTesterAppLabel, mActivityTesterActivityLabel,
+            mIntentFilterTesterAppLabel, mIntentFilterTesterActivityLabel,
+            mIntentFilterTesterIntentFilterLabel,
+            mBlacklistLabel,
+            mChooserTargetServiceLabel, mSharingShortcutLabel, mExtraChooserTargetsLabelBase,
+            mExtraInitialIntentsLabelBase, mPreviewTitle, mPreviewText;
+
+    private Set<ComponentName> mTargetsToExclude;
+
+    /**
+     * To validate Sharesheet API and API behavior works as intended UI test sare required. It is
+     * impossible to know the how the Sharesheet UI will be modified by end partners so these tests
+     * attempt to assume use the minimum needed assumptions to make the tests work.
+     *
+     * We cannot assume a scrolling direction or starting point because of potential UI variations.
+     * Because of limits of the UiAutomator pipeline only content visible on screen can be tested.
+     * These two constraints mean that all automated Sharesheet tests must be for content we
+     * reasonably expect to be visible after the sheet is opened without any direct interaction.
+     *
+     * Extra care is taken to ensure tested content is reasonably visible by:
+     * - Splitting tests across multiple Sharesheet calls
+     * - Excluding all packages not relevant to the test
+     * - Assuming a max of three targets per row of apps
+     */
+
+    @Before
+    public void init() throws Exception {
+        mInstrumentation = InstrumentationRegistry.getInstrumentation();
+        mContext = mInstrumentation.getTargetContext();
+        mPkg = mContext.getPackageName();
+        mExcludePkg = mPkg + ".packages.excludetester";
+        mActivityLabelTesterPkg = mPkg + ".packages.activitylabeltester";
+        mIntentFilterLabelTesterPkg = mPkg + ".packages.intentfilterlabeltester";
+
+        mDevice = UiDevice.getInstance(mInstrumentation);
+        mAutomation = mInstrumentation.getUiAutomation();
+
+        mActivityManager = mContext.getSystemService(ActivityManager.class);
+        mShortcutManager = mContext.getSystemService(ShortcutManager.class);
+        PackageManager pm = mContext.getPackageManager();
+        assertNotNull(mActivityManager);
+        assertNotNull(mShortcutManager);
+        assertNotNull(pm);
+
+        // Load in string to match against
+        mBlacklistLabel = mContext.getString(R.string.test_blacklist_label);
+        mAppLabel = mContext.getString(R.string.test_app_label);
+        mActivityTesterAppLabel = mContext.getString(R.string.test_activity_label_app);
+        mActivityTesterActivityLabel = mContext.getString(R.string.test_activity_label_activity);
+        mIntentFilterTesterAppLabel = mContext.getString(R.string.test_intent_filter_label_app);
+        mIntentFilterTesterActivityLabel =
+                mContext.getString(R.string.test_intent_filter_label_activity);
+        mIntentFilterTesterIntentFilterLabel =
+                mContext.getString(R.string.test_intent_filter_label_intentfilter);
+        mChooserTargetServiceLabel = mContext.getString(R.string.test_chooser_target_service_label);
+        mSharingShortcutLabel = mContext.getString(R.string.test_sharing_shortcut_label);
+        mExtraChooserTargetsLabelBase = mContext.getString(R.string.test_extra_chooser_targets_label);
+        mExtraInitialIntentsLabelBase = mContext.getString(R.string.test_extra_initial_intents_label);
+        mPreviewTitle = mContext.getString(R.string.test_preview_title);
+        mPreviewText = mContext.getString(R.string.test_preview_text);
+
+        // We want to only show targets in the sheet put forth by the CTS test. In order to do that
+        // a special type is used but this doesn't prevent apps registered against */* from showing.
+        // To hide */* targets, search for all matching targets and exclude them.
+        List<ResolveInfo> matchingTargets = mContext.getPackageManager().queryIntentActivities(
+                createMatchingIntent(),
+                PackageManager.MATCH_DEFAULT_ONLY | PackageManager.GET_META_DATA
+        );
+
+        mTargetsToExclude = matchingTargets.stream()
+                .map(ri -> {
+                    return new ComponentName(ri.activityInfo.packageName, ri.activityInfo.name);
+                })
+                .filter(cn -> {
+                    // Exclude our own test targets
+                    String pkg = cn.getPackageName();
+                    boolean isInternalPkg  = pkg.equals(mPkg) ||
+                            pkg.equals(mActivityLabelTesterPkg) ||
+                            pkg.equals(mIntentFilterLabelTesterPkg);
+
+                    return !isInternalPkg;
+                })
+                .collect(Collectors.toSet());
+
+        // We need to know the package used by the system Sharesheet so we can properly
+        // wait for the UI to load. Do this by resolving which activity consumes the share intent.
+        // There must be a system Sharesheet or fail, otherwise fetch its the package.
+        Intent shareIntent = createShareIntent(false, 0, 0);
+        ResolveInfo shareRi = pm.resolveActivity(shareIntent, PackageManager.MATCH_DEFAULT_ONLY);
+
+        assertNotNull(shareRi);
+        assertNotNull(shareRi.activityInfo);
+
+        mSharesheetPkg = shareRi.activityInfo.packageName;
+        assertNotNull(mSharesheetPkg);
+
+        // Finally ensure the device is awake
+        mDevice.wakeUp();
+    }
+
+    /**
+     * To test all features the Sharesheet will need to be opened and closed a few times. To keep
+     * total run time low, jam as many tests are possible into each visible test portion.
+     */
+    @Test
+    public void bulkTest1() {
+        try {
+            launchSharesheet(createShareIntent(true /* test content preview */,
+                    0 /* do not test EIIs */,
+                    0 /* do not test ECTs */));
+
+            doesExcludeComponents();
+            showsApplicationLabel();
+            showsAppAndActivityLabel();
+            showsAppAndIntentFilterLabel();
+            showsContentPreviewTitle();
+            showsContentPreviewText();
+            isChooserTargetServiceDirectShareEnabled();
+
+            // Must be run last, partial completion closes the Sharesheet
+            firesIntentSenderWithExtraChosenComponent();
+
+        } catch (Exception e) {
+            // No-op
+        } finally {
+            // The Sharesheet may or may not be open depending on test success, close it if it is
+            closeSharesheetIfNeeded();
+        }
+    }
+
+    @Test
+    public void bulkTest2() {
+        try {
+            addShortcuts(1);
+            launchSharesheet(createShareIntent(false /* do not test preview */,
+                    MAX_EXTRA_INITIAL_INTENTS_SHOWN + 1 /* test EIIs at 1 above cap */,
+                    MAX_EXTRA_CHOOSER_TARGETS_SHOWN + 1 /* test ECTs at 1 above cap */));
+            // Note: EII and ECT cap is not tested here
+
+            showsExtraInitialIntents();
+            showsExtraChooserTargets();
+            isSharingShortcutDirectShareEnabled();
+
+        } catch (Exception e) {
+            // No-op
+        } finally {
+            closeSharesheet();
+            clearShortcuts();
+        }
+    }
+
+    /*
+    Test methods
+     */
+
+    /**
+     * Tests API compliance for Intent.EXTRA_EXCLUDE_COMPONENTS. This test is necessary for other
+     * tests to run as expected.
+     */
+    public void doesExcludeComponents() {
+        // The excluded component should not be found on screen
+        waitAndAssertNoTextContains(mBlacklistLabel);
+    }
+
+    /**
+     * Tests API behavior compliance for security to always show application label
+     */
+    public void showsApplicationLabel() {
+        // For each app target the providing app's application manifest label should be shown
+        waitAndAssertTextContains(mAppLabel);
+    }
+
+    /**
+     * Tests API behavior compliance to show application and activity label when available
+     */
+    public void showsAppAndActivityLabel() {
+        waitAndAssertTextContains(mActivityTesterAppLabel);
+        waitAndAssertTextContains(mActivityTesterActivityLabel);
+    }
+
+    /**
+     * Tests API behavior compliance to show application and intent filter label when available
+     */
+    public void showsAppAndIntentFilterLabel() {
+        // NOTE: it is not necessary to show any set Activity label if an IntentFilter label is set
+        waitAndAssertTextContains(mIntentFilterTesterAppLabel);
+        waitAndAssertTextContains(mIntentFilterTesterIntentFilterLabel);
+    }
+
+    /**
+     * Tests API compliance for Intent.EXTRA_INITIAL_INTENTS
+     */
+    public void showsExtraInitialIntents() {
+        // Should show extra initial intents but must limit them, can't test limit here
+        waitAndAssertTextContains(mExtraInitialIntentsLabelBase);
+    }
+
+    /**
+     * Tests API compliance for Intent.EXTRA_CHOOSER_TARGETS
+     */
+    public void showsExtraChooserTargets() {
+        // Should show chooser targets but must limit them, can't test limit here
+        waitAndAssertTextContains(mExtraChooserTargetsLabelBase);
+    }
+
+    /**
+     * Tests API behavior compliance for Intent.EXTRA_TITLE
+     */
+    public void showsContentPreviewTitle() {
+        waitAndAssertTextContains(mPreviewTitle);
+    }
+
+    /**
+     * Tests API behavior compliance for Intent.EXTRA_TEXT
+     */
+    public void showsContentPreviewText() {
+        waitAndAssertTextContains(mPreviewText);
+    }
+
+    /**
+     * Tests API compliance for Intent.EXTRA_CHOSEN_COMPONENT_INTENT_SENDER and related APIs
+     * UI assumption: target labels are clickable, clicking opens target
+     */
+    public void firesIntentSenderWithExtraChosenComponent() throws Exception {
+        // To receive the extra chosen component a target must be clicked. Clicking the target
+        // will close the Sharesheet. Run this last in any sequence of tests.
+
+        // First find the target to click. This will fail if the showsApplicationLabel() test fails.
+        UiObject2 shareTarget = findTextContains(mAppLabel);
+        assertNotNull(shareTarget);
+
+        ComponentName clickedComponent = new ComponentName(mContext,
+                CtsSharesheetDeviceActivity.class);
+
+        final CountDownLatch latch = new CountDownLatch(1);
+        final Intent[] response = {null}; // Must be final so use an array
+
+        // Listen for the PendingIntent broadcast on click
+        BroadcastReceiver br = new BroadcastReceiver() {
+            @Override
+            public void onReceive(Context context, Intent intent) {
+                response[0] = intent;
+                latch.countDown();
+            }
+        };
+        mContext.registerReceiver(br, new IntentFilter(ACTION_INTENT_SENDER_FIRED_ON_CLICK));
+
+        // Start the event sequence and wait for results
+        shareTarget.click();
+
+        // The latch may fail for a number of reasons but we still need to unregister the
+        // BroadcastReceiver, so capture and rethrow any errors.
+        Exception delayedException = null;
+        try {
+            latch.await(1000, TimeUnit.MILLISECONDS);
+        } catch (Exception e) {
+            delayedException = e;
+        } finally {
+            mContext.unregisterReceiver(br);
+        }
+        if (delayedException != null) throw delayedException;
+
+        // Finally validate the received Intent
+        validateChosenComponentIntent(response[0], clickedComponent);
+    }
+
+    private void validateChosenComponentIntent(Intent intent, ComponentName matchingComponent) {
+        assertNotNull(intent);
+
+        assertTrue(intent.hasExtra(Intent.EXTRA_CHOSEN_COMPONENT));
+        Object extra = intent.getParcelableExtra(Intent.EXTRA_CHOSEN_COMPONENT);
+        assertNotNull(extra);
+
+        assertTrue(extra instanceof ComponentName);
+        ComponentName component = (ComponentName) extra;
+
+        assertEquals(component, matchingComponent);
+    }
+
+    /**
+     * Tests API behavior compliance for ChooserTargetService
+     */
+    public void isChooserTargetServiceDirectShareEnabled() {
+        // ChooserTargets can take time to load. To account for this:
+        // * All non-test ChooserTargetServices shouldn't be loaded because of blacklist
+        // * waitAndAssert operations have lengthy timeout periods
+        // * Last time to run in suite so prior operations reduce wait time
+
+        if (mActivityManager.isLowRamDevice()) {
+            // Ensure direct share is disabled on low ram devices
+            waitAndAssertNoTextContains(mChooserTargetServiceLabel);
+        } else {
+            // Ensure direct share is enabled
+            waitAndAssertTextContains(mChooserTargetServiceLabel);
+        }
+    }
+
+    /**
+     * Tests API behavior compliance for Sharing Shortcuts
+     */
+    public void isSharingShortcutDirectShareEnabled() {
+        if (mActivityManager.isLowRamDevice()) {
+            // Ensure direct share is disabled on low ram devices
+            waitAndAssertNoTextContains(mSharingShortcutLabel);
+        } else {
+            // Ensure direct share is enabled
+            waitAndAssertTextContains(mSharingShortcutLabel);
+        }
+    }
+
+    /*
+    Setup methods
+     */
+
+    public void addShortcuts(int size) {
+        mShortcutManager.addDynamicShortcuts(createShortcuts(size));
+    }
+
+    public void clearShortcuts() {
+        mShortcutManager.removeAllDynamicShortcuts();
+    }
+
+    private List<ShortcutInfo> createShortcuts(int size) {
+        List<ShortcutInfo> ret = new ArrayList<>();
+        for (int i=0; i<size; i++) {
+            ret.add(createShortcut(""+i));
+        }
+        return ret;
+    }
+
+    private ShortcutInfo createShortcut(String id) {
+        HashSet<String> categories = new HashSet<>();
+        categories.add(CATEGORY_CTS_TEST);
+
+        return new ShortcutInfo.Builder(mContext, id)
+                .setShortLabel(mSharingShortcutLabel)
+                .setIcon(Icon.createWithResource(mContext, R.drawable.black_64x64))
+                .setCategories(categories)
+                .setIntent(new Intent(Intent.ACTION_DEFAULT)) /* an Intent with an action must be set */
+                .build();
+    }
+
+    private void launchSharesheet(Intent shareIntent) {
+        mContext.startActivity(shareIntent);
+        waitAndAssertPkgVisible(mSharesheetPkg);
+        waitForIdle();
+    }
+
+    private void closeSharesheetIfNeeded() {
+        if (isSharesheetVisible()) closeSharesheet();
+    }
+
+    private void closeSharesheet() {
+        mDevice.pressBack();
+        waitAndAssertPkgNotVisible(mSharesheetPkg);
+        waitForIdle();
+    }
+
+    private boolean isSharesheetVisible() {
+        // This method intentionally does not wait, looks to see if visible on method call
+        return mDevice.findObject(By.pkg(mSharesheetPkg).depth(0)) != null;
+    }
+
+    private Intent createMatchingIntent() {
+        Intent intent = new Intent(Intent.ACTION_SEND);
+        intent.setType(CTS_DATA_TYPE);
+        return intent;
+    }
+
+    private Intent createShareIntent(boolean contentPreview,
+            int numExtraInitialIntents,
+            int numExtraChooserTargets) {
+
+        Intent intent = createMatchingIntent();
+
+        if (contentPreview) {
+            intent.putExtra(Intent.EXTRA_TITLE, mPreviewTitle);
+            intent.putExtra(Intent.EXTRA_TEXT, mPreviewText);
+        }
+
+        PendingIntent pi = PendingIntent.getBroadcast(
+                mContext,
+                9384 /* number not relevant */ ,
+                new Intent(ACTION_INTENT_SENDER_FIRED_ON_CLICK),
+                PendingIntent.FLAG_UPDATE_CURRENT);
+
+        Intent shareIntent = Intent.createChooser(intent, null, pi.getIntentSender());
+
+        // Intent.EXTRA_EXCLUDE_COMPONENTS is used to ensure only test targets appear
+        List<ComponentName> list = new ArrayList<>(mTargetsToExclude);
+        list.add(new ComponentName(mPkg, mPkg + ".BlacklistTestActivity"));
+        shareIntent.putExtra(Intent.EXTRA_EXCLUDE_COMPONENTS,
+                list.toArray(new ComponentName[0]));
+
+        if (numExtraInitialIntents > 0) {
+            Intent[] eiis = new Intent[numExtraInitialIntents];
+            for (int i = 0; i < eiis.length; i++) {
+                Intent eii = new Intent();
+                eii.setComponent(new ComponentName(mPkg,
+                        mPkg + ".ExtraInitialIntentTestActivity"));
+
+                LabeledIntent labeledEii = new LabeledIntent(eii, mPkg,
+                        getExtraInitialIntentsLabel(i),
+                        0 /* provide no icon */);
+
+                eiis[i] = labeledEii;
+            }
+
+            shareIntent.putExtra(Intent.EXTRA_INITIAL_INTENTS, eiis);
+        }
+
+        if (numExtraChooserTargets > 0) {
+            ChooserTarget[] ects = new ChooserTarget[numExtraChooserTargets];
+            for (int i = 0; i < ects.length; i++) {
+                ects[i] = new ChooserTarget(
+                        getExtraChooserTargetLabel(i),
+                        Icon.createWithResource(mContext, R.drawable.black_64x64),
+                        1f,
+                        new ComponentName(mPkg, mPkg + ".CtsSharesheetDeviceActivity"),
+                        new Bundle());
+            }
+
+            shareIntent.putExtra(Intent.EXTRA_CHOOSER_TARGETS, ects);
+        }
+
+        // Ensure the sheet will launch directly from the test
+        shareIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+
+        return shareIntent;
+    }
+
+    private String getExtraChooserTargetLabel(int position) {
+        return mExtraChooserTargetsLabelBase + " " + position;
+    }
+
+    private String getExtraInitialIntentsLabel(int position) {
+        return mExtraInitialIntentsLabelBase + " " + position;
+    }
+
+    /*
+    UI testing methods
+     */
+
+    private void waitForIdle() {
+        mDevice.waitForIdle(WAIT_FOR_IDLE_TIMEOUT_MS);
+    }
+
+    private void waitAndAssertPkgVisible(String pkg) {
+        waitAndAssertFound(By.pkg(pkg).depth(0));
+    }
+
+    private void waitAndAssertPkgNotVisible(String pkg) {
+        waitAndAssertNotFound(By.pkg(pkg));
+    }
+
+    private void waitAndAssertTextContains(String containsText) {
+        waitAndAssertFound(By.textContains(containsText));
+    }
+
+    private void waitAndAssertNoTextContains(String containsText) {
+        waitAndAssertNotFound(By.textContains(containsText));
+    }
+
+    /**
+     * waitAndAssertFound will wait until UI defined by the selector is found. If it's never found,
+     * this will wait for the duration of the full timeout. Take care to call this method after
+     * reasonable steps are taken to ensure fast completion.
+     */
+    private void waitAndAssertFound(BySelector selector) {
+        assertNotNull(mDevice.wait(Until.findObject(selector), WAIT_AND_ASSERT_FOUND_TIMEOUT_MS));
+    }
+
+    /**
+     * waitAndAssertNotFound waits for any visible UI to be hidden, validates that it's indeed gone
+     * without waiting more and returns. This means if the UI wasn't visible to start with the
+     * method will return without no timeout. Take care to call this method only once there's reason
+     * to think the UI is in the right state for testing.
+     */
+    private void waitAndAssertNotFound(BySelector selector) {
+        mDevice.wait(Until.gone(selector), WAIT_AND_ASSERT_NOT_FOUND_TIMEOUT_MS);
+        assertNull(mDevice.findObject(selector));
+    }
+
+    /**
+     * findTextContains uses logic similar to waitAndAssertFound to locate UI objects that contain
+     * the provided String.
+     * @param containsText the String to search for, note this is not an exact match only contains
+     * @return UiObject2 that can be used, for example, to execute a click
+     */
+    private UiObject2 findTextContains(String containsText) {
+        return mDevice.wait(Until.findObject(By.textContains(containsText)),
+                WAIT_AND_ASSERT_FOUND_TIMEOUT_MS);
+    }
+}
diff --git a/tests/tests/telecom/src/android/telecom/cts/ConnectionServiceTest.java b/tests/tests/telecom/src/android/telecom/cts/ConnectionServiceTest.java
index 08931eb..28ceed0 100755
--- a/tests/tests/telecom/src/android/telecom/cts/ConnectionServiceTest.java
+++ b/tests/tests/telecom/src/android/telecom/cts/ConnectionServiceTest.java
@@ -18,6 +18,8 @@
 
 import static android.telecom.cts.TestUtils.*;
 
+import static com.android.compatibility.common.util.SystemUtil.runWithShellPermissionIdentity;
+
 import android.content.ComponentName;
 import android.content.Context;
 import android.media.AudioManager;
@@ -27,6 +29,8 @@
 import android.telecom.ConnectionService;
 import android.telecom.PhoneAccountHandle;
 
+import androidx.test.InstrumentationRegistry;
+
 import java.util.Collection;
 
 /**
@@ -59,7 +63,9 @@
         // Add second connection (add existing connection)
         final MockConnection connection = new MockConnection();
         connection.setOnHold();
-        CtsConnectionService.addExistingConnectionToTelecom(TEST_PHONE_ACCOUNT_HANDLE, connection);
+        runWithShellPermissionIdentity(() ->
+                CtsConnectionService.addExistingConnectionToTelecom(TEST_PHONE_ACCOUNT_HANDLE,
+                        connection));
         assertNumCalls(mInCallCallbacks.getService(), 2);
         mInCallCallbacks.lock.drainPermits();
         final Call call = mInCallCallbacks.getService().getLastCall();
@@ -81,8 +87,9 @@
                 "com.android.services.telephony.TelephonyConnectionService");
         // This command will fail and a SecurityException will be thrown by Telecom. The Exception
         // will then be absorbed by the ConnectionServiceAdapter.
-        CtsConnectionService.addExistingConnectionToTelecom(new PhoneAccountHandle(invalidName,
-                "Test"), connection);
+        runWithShellPermissionIdentity(() ->
+                CtsConnectionService.addExistingConnectionToTelecom(
+                        new PhoneAccountHandle(invalidName, "Test"), connection));
         // Make sure that only the original Call exists.
         assertNumCalls(mInCallCallbacks.getService(), 1);
         mInCallCallbacks.lock.drainPermits();
@@ -103,8 +110,9 @@
         connection.setOnHold();
         ComponentName validName = new ComponentName(PACKAGE, COMPONENT);
         // This command will fail because the PhoneAccount is not registered to Telecom currently.
-        CtsConnectionService.addExistingConnectionToTelecom(new PhoneAccountHandle(validName,
-                "Invalid Account Id"), connection);
+        runWithShellPermissionIdentity(() ->
+                CtsConnectionService.addExistingConnectionToTelecom(
+                        new PhoneAccountHandle(validName, "Invalid Account Id"), connection));
         // Make sure that only the original Call exists.
         assertNumCalls(mInCallCallbacks.getService(), 1);
         mInCallCallbacks.lock.drainPermits();
@@ -243,19 +251,28 @@
             return;
         }
 
-        // Need to add a call to ensure ConnectionService is up and bound.
-        placeAndVerifyCall();
-        verifyConnectionForOutgoingCall().setActive();
+        InstrumentationRegistry.getInstrumentation().getUiAutomation()
+                .adoptShellPermissionIdentity("android.permission.MODIFY_PHONE_STATE");
+        try {
+            // Need to add a call to ensure ConnectionService is up and bound.
+            placeAndVerifyCall();
+            verifyConnectionForOutgoingCall().setActive();
 
-        final MockConnection connection = new MockConnection();
-        connection.setActive();
-        connection.setCallDirection(Call.Details.DIRECTION_INCOMING);
-        CtsConnectionService.addExistingConnectionToTelecom(TEST_PHONE_ACCOUNT_HANDLE, connection);
-        assertNumCalls(mInCallCallbacks.getService(), 2);
-        mInCallCallbacks.lock.drainPermits();
-        final Call call = mInCallCallbacks.getService().getLastCall();
-        assertCallState(call, Call.STATE_ACTIVE);
-        assertEquals(Call.Details.DIRECTION_INCOMING, call.getDetails().getCallDirection());
+            final MockConnection connection = new MockConnection();
+            connection.setActive();
+            connection.setCallDirection(Call.Details.DIRECTION_INCOMING);
+            CtsConnectionService.addExistingConnectionToTelecom(TEST_PHONE_ACCOUNT_HANDLE,
+                    connection);
+            assertNumCalls(mInCallCallbacks.getService(), 2);
+            mInCallCallbacks.lock.drainPermits();
+            final Call call = mInCallCallbacks.getService().getLastCall();
+            assertCallState(call, Call.STATE_ACTIVE);
+            assertEquals(Call.Details.DIRECTION_INCOMING, call.getDetails().getCallDirection());
+        } finally {
+            InstrumentationRegistry.getInstrumentation().getUiAutomation()
+                    .dropShellPermissionIdentity();
+        }
+
     }
 
     public void testCallDirectionOutgoing() {
@@ -263,25 +280,33 @@
             return;
         }
 
-        // Ensure CS is up and bound.
-        placeAndVerifyCall();
-        verifyConnectionForOutgoingCall().setActive();
+        InstrumentationRegistry.getInstrumentation().getUiAutomation()
+                .adoptShellPermissionIdentity("android.permission.MODIFY_PHONE_STATE");
+        try {
+            // Ensure CS is up and bound.
+            placeAndVerifyCall();
+            verifyConnectionForOutgoingCall().setActive();
 
-        final MockConnection connection = new MockConnection();
-        connection.setActive();
-        connection.setCallDirection(Call.Details.DIRECTION_OUTGOING);
-        connection.setConnectTimeMillis(1000L);
-        assertEquals(1000L, connection.getConnectTimeMillis());
-        connection.setConnectionStartElapsedRealtimeMillis(100L);
-        assertEquals(100L, connection.getConnectionStartElapsedRealtimeMillis());
+            final MockConnection connection = new MockConnection();
+            connection.setActive();
+            connection.setCallDirection(Call.Details.DIRECTION_OUTGOING);
+            connection.setConnectTimeMillis(1000L);
+            assertEquals(1000L, connection.getConnectTimeMillis());
+            connection.setConnectionStartElapsedRealtimeMillis(100L);
+            assertEquals(100L, connection.getConnectionStartElapsedRealtimeMillis());
 
-        CtsConnectionService.addExistingConnectionToTelecom(TEST_PHONE_ACCOUNT_HANDLE, connection);
-        assertNumCalls(mInCallCallbacks.getService(), 2);
-        mInCallCallbacks.lock.drainPermits();
-        final Call call = mInCallCallbacks.getService().getLastCall();
-        assertCallState(call, Call.STATE_ACTIVE);
-        assertEquals(Call.Details.DIRECTION_OUTGOING, call.getDetails().getCallDirection());
-        assertEquals(1000L, call.getDetails().getConnectTimeMillis());
+            CtsConnectionService.addExistingConnectionToTelecom(TEST_PHONE_ACCOUNT_HANDLE,
+                    connection);
+            assertNumCalls(mInCallCallbacks.getService(), 2);
+            mInCallCallbacks.lock.drainPermits();
+            final Call call = mInCallCallbacks.getService().getLastCall();
+            assertCallState(call, Call.STATE_ACTIVE);
+            assertEquals(Call.Details.DIRECTION_OUTGOING, call.getDetails().getCallDirection());
+            assertEquals(1000L, call.getDetails().getConnectTimeMillis());
+        } finally {
+            InstrumentationRegistry.getInstrumentation().getUiAutomation()
+                    .dropShellPermissionIdentity();
+        }
     }
 
     public void testGetAllConnections() {
@@ -289,33 +314,42 @@
             return;
         }
 
-        // Add first connection (outgoing call)
-        placeAndVerifyCall();
-        final Connection connection1 = verifyConnectionForOutgoingCall();
+        InstrumentationRegistry.getInstrumentation().getUiAutomation()
+                .adoptShellPermissionIdentity("android.permission.MODIFY_PHONE_STATE");
+        try {
+            // Add first connection (outgoing call)
+            placeAndVerifyCall();
+            final Connection connection1 = verifyConnectionForOutgoingCall();
 
-        Collection<Connection> connections = CtsConnectionService.getAllConnectionsFromTelecom();
-        assertEquals(1, connections.size());
-        assertTrue(connections.contains(connection1));
-        // Need to move this to active since we reject the 3rd incoming call below if this is in
-        // dialing state (b/23428950).
-        connection1.setActive();
-        assertCallState(mInCallCallbacks.getService().getLastCall(), Call.STATE_ACTIVE);
+            Collection<Connection> connections =
+                    CtsConnectionService.getAllConnectionsFromTelecom();
+            assertEquals(1, connections.size());
+            assertTrue(connections.contains(connection1));
+            // Need to move this to active since we reject the 3rd incoming call below if this is in
+            // dialing state (b/23428950).
+            connection1.setActive();
+            assertCallState(mInCallCallbacks.getService().getLastCall(), Call.STATE_ACTIVE);
 
-        // Add second connection (add existing connection)
-        final Connection connection2 = new MockConnection();
-        connection2.setActive();
-        CtsConnectionService.addExistingConnectionToTelecom(TEST_PHONE_ACCOUNT_HANDLE, connection2);
-        assertNumCalls(mInCallCallbacks.getService(), 2);
-        mInCallCallbacks.lock.drainPermits();
-        connections = CtsConnectionService.getAllConnectionsFromTelecom();
-        assertEquals(2, connections.size());
-        assertTrue(connections.contains(connection2));
+            // Add second connection (add existing connection)
+            final Connection connection2 = new MockConnection();
+            connection2.setActive();
+            CtsConnectionService.addExistingConnectionToTelecom(TEST_PHONE_ACCOUNT_HANDLE,
+                            connection2);
+            assertNumCalls(mInCallCallbacks.getService(), 2);
+            mInCallCallbacks.lock.drainPermits();
+            connections = CtsConnectionService.getAllConnectionsFromTelecom();
+            assertEquals(2, connections.size());
+            assertTrue(connections.contains(connection2));
 
-        // Add third connection (incoming call)
-        addAndVerifyNewIncomingCall(createTestNumber(), null);
-        final Connection connection3 = verifyConnectionForIncomingCall();
-        connections = CtsConnectionService.getAllConnectionsFromTelecom();
-        assertEquals(3, connections.size());
-        assertTrue(connections.contains(connection3));
+            // Add third connection (incoming call)
+            addAndVerifyNewIncomingCall(createTestNumber(), null);
+            final Connection connection3 = verifyConnectionForIncomingCall();
+            connections = CtsConnectionService.getAllConnectionsFromTelecom();
+            assertEquals(3, connections.size());
+            assertTrue(connections.contains(connection3));
+        } finally {
+            InstrumentationRegistry.getInstrumentation().getUiAutomation()
+                    .dropShellPermissionIdentity();
+        }
     }
 }
diff --git a/tests/tests/telephony/current/src/android/telephony/cts/CarrierConfigManagerTest.java b/tests/tests/telephony/current/src/android/telephony/cts/CarrierConfigManagerTest.java
index 92cd25b..3c95139 100644
--- a/tests/tests/telephony/current/src/android/telephony/cts/CarrierConfigManagerTest.java
+++ b/tests/tests/telephony/current/src/android/telephony/cts/CarrierConfigManagerTest.java
@@ -137,6 +137,23 @@
             assertEquals("KEY_CARRIER_VVM_PACKAGE_NAME_STRING doesn't match static default.",
                 config.getString(CarrierConfigManager.KEY_CARRIER_VVM_PACKAGE_NAME_STRING), "");
             assertFalse(CarrierConfigManager.isConfigForIdentifiedCarrier(config));
+
+            // Check default value matching
+            assertEquals("KEY_DATA_LIMIT_NOTIFICATION_BOOL doesn't match static default.",
+                    config.getBoolean(CarrierConfigManager.KEY_DATA_LIMIT_NOTIFICATION_BOOL),
+                            true);
+            assertEquals("KEY_DATA_RAPID_NOTIFICATION_BOOL doesn't match static default.",
+                    config.getBoolean(CarrierConfigManager.KEY_DATA_RAPID_NOTIFICATION_BOOL),
+                            true);
+            assertEquals("KEY_DATA_WARNING_NOTIFICATION_BOOL doesn't match static default.",
+                    config.getBoolean(CarrierConfigManager.KEY_DATA_WARNING_NOTIFICATION_BOOL),
+                            true);
+            assertEquals("Gps.KEY_PERSIST_LPP_MODE_BOOL doesn't match static default.",
+                    config.getBoolean(CarrierConfigManager.Gps.KEY_PERSIST_LPP_MODE_BOOL),
+                            true);
+            assertEquals("KEY_MONTHLY_DATA_CYCLE_DAY_INT doesn't match static default.",
+                    config.getInt(CarrierConfigManager.KEY_MONTHLY_DATA_CYCLE_DAY_INT),
+                            CarrierConfigManager.DATA_CYCLE_USE_PLATFORM_DEFAULT);
         }
 
         // These key should return default values if not customized.
@@ -150,6 +167,12 @@
                 CarrierConfigManager.KEY_LTE_RSRQ_THRESHOLDS_INT_ARRAY));
         assertNotNull(config.getIntArray(
                 CarrierConfigManager.KEY_LTE_RSSNR_THRESHOLDS_INT_ARRAY));
+
+        // Check the GPS key prefix
+        assertTrue("Gps.KEY_PREFIX doesn't match the prefix of the name of "
+                + "Gps.KEY_PERSIST_LPP_MODE_BOOL",
+                        CarrierConfigManager.Gps.KEY_PERSIST_LPP_MODE_BOOL.startsWith(
+                                CarrierConfigManager.Gps.KEY_PREFIX));
     }
 
     @Test
diff --git a/tests/tests/telephony/current/src/android/telephony/cts/CbGeoUtilsTest.java b/tests/tests/telephony/current/src/android/telephony/cts/CbGeoUtilsTest.java
new file mode 100644
index 0000000..cf935f9
--- /dev/null
+++ b/tests/tests/telephony/current/src/android/telephony/cts/CbGeoUtilsTest.java
@@ -0,0 +1,89 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.telephony.cts;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+
+import android.telephony.CbGeoUtils;
+
+import org.junit.Test;
+
+import java.util.ArrayList;
+
+public class CbGeoUtilsTest {
+
+    // latitude is in range -90, 90
+    private static final double LAT1 = 30;
+    // longitude is in range -180, 180
+    private static final double LNG1 = 100;
+
+    private static final double LAT2 = 10;
+    private static final double LNG2 = 120;
+
+    private static final double LAT3 = -10;
+    private static final double LNG3 = -90;
+
+    // distance in meters between (LAT1, LNG1) and (LAT2, LNG2)
+    private static final double DIST = 3040602;
+
+    // max allowed error in calculations
+    private static final double DELTA = 1;
+
+    @Test
+    public void testLatLong() {
+        CbGeoUtils.LatLng p1 = new CbGeoUtils.LatLng(LAT1, LNG1);
+        CbGeoUtils.LatLng p2 = new CbGeoUtils.LatLng(LAT2, LNG2);
+
+        CbGeoUtils.LatLng difference = new CbGeoUtils.LatLng(LAT1 - LAT2, LNG1 - LNG2);
+        assertEquals(difference.lat, p1.subtract(p2).lat, DELTA);
+        assertEquals(difference.lng, p1.subtract(p2).lng, DELTA);
+
+        assertEquals(DIST, p1.distance(p2), DELTA);
+    }
+
+    @Test
+    public void testPolygon() {
+        CbGeoUtils.LatLng p1 = new CbGeoUtils.LatLng(LAT1, LNG1);
+        CbGeoUtils.LatLng p2 = new CbGeoUtils.LatLng(LAT2, LNG2);
+        CbGeoUtils.LatLng p3 = new CbGeoUtils.LatLng(LAT3, LNG3);
+
+        ArrayList<CbGeoUtils.LatLng> vertices = new ArrayList<>();
+        vertices.add(p1);
+        vertices.add(p2);
+        vertices.add(p3);
+
+        CbGeoUtils.Polygon polygon = new CbGeoUtils.Polygon((vertices));
+        assertEquals(vertices, polygon.getVertices());
+
+        assertTrue(polygon.contains(p1));
+        assertTrue(polygon.contains(p2));
+        assertTrue(polygon.contains(p3));
+    }
+
+    @Test
+    public void testCircle() {
+        CbGeoUtils.LatLng p1 = new CbGeoUtils.LatLng(LAT1, LNG1);
+        double radius = 1000;
+        CbGeoUtils.Circle circle = new CbGeoUtils.Circle(p1, radius);
+
+        assertEquals(radius, circle.getRadius(), DELTA);
+        assertEquals(p1, circle.getCenter());
+        // circle should always contain its center
+        assertTrue(circle.contains(p1));
+    }
+}
diff --git a/tests/tests/telephony/current/src/android/telephony/cts/PhoneStateListenerTest.java b/tests/tests/telephony/current/src/android/telephony/cts/PhoneStateListenerTest.java
index 32d18de..864cbac 100644
--- a/tests/tests/telephony/current/src/android/telephony/cts/PhoneStateListenerTest.java
+++ b/tests/tests/telephony/current/src/android/telephony/cts/PhoneStateListenerTest.java
@@ -51,7 +51,6 @@
 import androidx.test.InstrumentationRegistry;
 
 import com.android.compatibility.common.util.ShellIdentityUtils;
-import com.android.compatibility.common.util.TestThread;
 
 import org.junit.After;
 import org.junit.Before;
@@ -59,9 +58,7 @@
 
 import java.util.Arrays;
 import java.util.List;
-import java.util.concurrent.CountDownLatch;
 import java.util.concurrent.Executor;
-import java.util.concurrent.TimeUnit;
 
 public class PhoneStateListenerTest {
 
@@ -103,6 +100,8 @@
     private final Object mLock = new Object();
     private static final String TAG = "android.telephony.cts.PhoneStateListenerTest";
     private static ConnectivityManager mCm;
+    private HandlerThread mHandlerThread;
+    private Handler mHandler;
     private static final List<Integer> DATA_CONNECTION_STATE = Arrays.asList(
             TelephonyManager.DATA_CONNECTED,
             TelephonyManager.DATA_DISCONNECTED,
@@ -135,6 +134,9 @@
         mTelephonyManager =
                 (TelephonyManager)getContext().getSystemService(Context.TELEPHONY_SERVICE);
         mCm = (ConnectivityManager)getContext().getSystemService(Context.CONNECTIVITY_SERVICE);
+        mHandlerThread = new HandlerThread("PhoneStateListenerTest");
+        mHandlerThread.start();
+        mHandler = new Handler(mHandlerThread.getLooper());
     }
 
     @After
@@ -143,6 +145,9 @@
             // unregister the listener
             mTelephonyManager.listen(mListener, PhoneStateListener.LISTEN_NONE);
         }
+        if (mHandlerThread != null) {
+            mHandlerThread.quitSafely();
+        }
     }
 
     @Test
@@ -156,11 +161,6 @@
         new PhoneStateListener();
     }
 
-    /*
-     * The tests below rely on the framework to immediately call the installed listener upon
-     * registration. There is no simple way to emulate state changes for testing the listeners.
-     */
-
     @Test
     public void testOnServiceStateChanged() throws Throwable {
         if (mCm.getNetworkInfo(ConnectivityManager.TYPE_MOBILE) == null) {
@@ -168,34 +168,26 @@
             return;
         }
 
-        TestThread t = new TestThread(new Runnable() {
-            public void run() {
-                Looper.prepare();
-
-                mListener = new PhoneStateListener() {
-                    @Override
-                    public void onServiceStateChanged(ServiceState serviceState) {
-                        synchronized(mLock) {
-                            mOnServiceStateChangedCalled = true;
-                            mLock.notify();
-                        }
-                    }
-                };
-                mTelephonyManager.listen(mListener, PhoneStateListener.LISTEN_SERVICE_STATE);
-
-                Looper.loop();
-            }
-        });
-
         assertFalse(mOnServiceStateChangedCalled);
-        t.start();
 
+        mHandler.post(() -> {
+            mListener = new PhoneStateListener() {
+                @Override
+                public void onServiceStateChanged(ServiceState serviceState) {
+                    synchronized (mLock) {
+                        mOnServiceStateChangedCalled = true;
+                        mLock.notify();
+                    }
+                }
+            };
+            mTelephonyManager.listen(mListener, PhoneStateListener.LISTEN_SERVICE_STATE);
+        });
         synchronized (mLock) {
             if (!mOnServiceStateChangedCalled){
                 mLock.wait(WAIT_TIME);
             }
         }
-        t.checkException();
+
         assertTrue(mOnServiceStateChangedCalled);
     }
 
@@ -206,34 +198,26 @@
             return;
         }
 
-        TestThread t = new TestThread(new Runnable() {
-            public void run() {
-                Looper.prepare();
-
-                mListener = new PhoneStateListener() {
-                    @Override
-                    public void onServiceStateChanged(ServiceState serviceState) {
-                        synchronized(mLock) {
-                            mOnServiceStateChangedCalled = true;
-                            mLock.notify();
-                        }
-                    }
-                };
-                mTelephonyManager.listen(mListener, PhoneStateListener.LISTEN_SERVICE_STATE);
-
-                Looper.loop();
-            }
-        });
-
         assertFalse(mOnServiceStateChangedCalled);
-        t.start();
 
+        mHandler.post(() -> {
+            mListener = new PhoneStateListener() {
+                @Override
+                public void onServiceStateChanged(ServiceState serviceState) {
+                    synchronized (mLock) {
+                        mOnServiceStateChangedCalled = true;
+                        mLock.notify();
+                    }
+                }
+            };
+            mTelephonyManager.listen(mListener, PhoneStateListener.LISTEN_SERVICE_STATE);
+        });
         synchronized (mLock) {
             if (!mOnServiceStateChangedCalled){
                 mLock.wait(WAIT_TIME);
             }
         }
-        t.checkException();
+
         assertTrue(mOnServiceStateChangedCalled);
 
         // reset and un-register
@@ -256,7 +240,7 @@
                 mLock.wait(WAIT_TIME);
             }
         }
-        t.checkException();
+
         assertTrue(mOnServiceStateChangedCalled);
     }
 
@@ -267,37 +251,33 @@
             return;
         }
 
-        TestThread t = new TestThread(new Runnable() {
-            public void run() {
-                Looper.prepare();
-
-                mListener = new PhoneStateListener() {
-                    @Override
-                    public void onSignalStrengthChanged(int asu) {
-                        synchronized(mLock) {
-                            mOnSignalStrengthChangedCalled = true;
-                            mLock.notify();
-                        }
-                    }
-                };
-                mTelephonyManager.listen(mListener, PhoneStateListener.LISTEN_SIGNAL_STRENGTH);
-
-                Looper.loop();
-            }
-        });
-
         assertFalse(mOnSignalStrengthChangedCalled);
-        t.start();
 
+        mHandler.post(() -> {
+            mListener = new PhoneStateListener() {
+                @Override
+                public void onSignalStrengthChanged(int asu) {
+                    synchronized (mLock) {
+                        mOnSignalStrengthChangedCalled = true;
+                        mLock.notify();
+                    }
+                }
+            };
+            mTelephonyManager.listen(mListener, PhoneStateListener.LISTEN_SIGNAL_STRENGTH);
+        });
         synchronized (mLock) {
             if (!mOnSignalStrengthChangedCalled){
                 mLock.wait(WAIT_TIME);
             }
         }
-        t.checkException();
+
         assertTrue(mOnSignalStrengthChangedCalled);
     }
 
+    /**
+     * Due to the corresponding API is hidden in R and will be public in S, this test
+     * is commented and will be un-commented in Android S.
+     *
     @Test
     public void testOnAlwaysReportedSignalStrengthChanged() throws Throwable {
         if (mCm.getNetworkInfo(ConnectivityManager.TYPE_MOBILE) == null) {
@@ -305,38 +285,29 @@
             return;
         }
 
-        TestThread t = new TestThread(new Runnable() {
-            public void run() {
-                Looper.prepare();
-
-                mListener = new PhoneStateListener() {
-                    @Override
-                    public void onSignalStrengthsChanged(SignalStrength signalStrength) {
-                        synchronized (mLock) {
-                            mSignalStrength = signalStrength;
-                            mLock.notify();
-                        }
-                    }
-                };
-                ShellIdentityUtils.invokeMethodWithShellPermissionsNoReturn(mTelephonyManager,
-                        (tm) -> tm.listen(mListener,
-                                PhoneStateListener.LISTEN_ALWAYS_REPORTED_SIGNAL_STRENGTH));
-
-                Looper.loop();
-            }
-        });
-
         assertTrue(mSignalStrength == null);
-        t.start();
 
+        mHandler.post(() -> {
+            mListener = new PhoneStateListener() {
+                @Override
+                public void onSignalStrengthsChanged(SignalStrength signalStrength) {
+                    synchronized (mLock) {
+                        mSignalStrength = signalStrength;
+                        mLock.notify();
+                    }
+                }
+            };
+            ShellIdentityUtils.invokeMethodWithShellPermissionsNoReturn(mTelephonyManager,
+                (tm) -> tm.listen(mListener,
+                    PhoneStateListener.LISTEN_ALWAYS_REPORTED_SIGNAL_STRENGTH));
+        });
         synchronized (mLock) {
             if (mSignalStrength == null) {
                 mLock.wait(WAIT_TIME);
             }
         }
-        t.checkException();
-        assertTrue(mSignalStrength != null);
 
+        assertTrue(mSignalStrength != null);
         // Call SignalStrength methods to make sure they do not throw any exceptions
         mSignalStrength.getCdmaDbm();
         mSignalStrength.getCdmaEcio();
@@ -348,12 +319,16 @@
         mSignalStrength.isGsm();
         mSignalStrength.getLevel();
     }
+    */
 
     /**
+     * Due to the corresponding API is hidden in R and will be public in S, this test
+     * is commented and will be un-commented in Android S.
+     *
      * Validate that SecurityException should be thrown when listen
      * with LISTEN_ALWAYS_REPORTED_SIGNAL_STRENGTH without LISTEN_ALWAYS_REPORTED_SIGNAL_STRENGTH
      * permission.
-     */
+     *
     @Test
     public void testOnAlwaysReportedSignalStrengthChangedWithoutPermission() throws Throwable {
         if (mCm.getNetworkInfo(ConnectivityManager.TYPE_MOBILE) == null) {
@@ -361,41 +336,38 @@
             return;
         }
 
-        TestThread t = new TestThread(new Runnable() {
-            public void run() {
-                Looper.prepare();
+        assertTrue(mSignalStrength == null);
 
-                mListener = new PhoneStateListener() {
-                    @Override
-                    public void onSignalStrengthsChanged(SignalStrength signalStrength) {
-                        synchronized (mLock) {
-                            mSignalStrength = signalStrength;
-                            mLock.notify();
-                        }
+        mHandler.post(() -> {
+            mListener = new PhoneStateListener() {
+                @Override
+                public void onSignalStrengthsChanged(SignalStrength signalStrength) {
+                    synchronized (mLock) {
+                        mSignalStrength = signalStrength;
+                        mLock.notify();
                     }
-                };
-                try {
-                    mTelephonyManager.listen(mListener,
-                            PhoneStateListener.LISTEN_ALWAYS_REPORTED_SIGNAL_STRENGTH);
-                } catch (SecurityException se) {
+                }
+            };
+            try {
+                mTelephonyManager.listen(mListener,
+                    PhoneStateListener.LISTEN_ALWAYS_REPORTED_SIGNAL_STRENGTH);
+            } catch (SecurityException se) {
+                synchronized (mLock) {
                     mSecurityExceptionThrown = true;
                     mLock.notify();
                 }
-                Looper.loop();
             }
         });
-
-        assertTrue(mSignalStrength == null);
-        t.start();
-
         synchronized (mLock) {
             if (!mSecurityExceptionThrown) {
                 mLock.wait(WAIT_TIME);
             }
         }
+
         assertThat(mSecurityExceptionThrown).isTrue();
         assertTrue(mSignalStrength == null);
     }
+    */
 
     @Test
     public void testOnSignalStrengthsChanged() throws Throwable {
@@ -403,37 +375,27 @@
             Log.d(TAG, "Skipping test that requires ConnectivityManager.TYPE_MOBILE");
             return;
         }
-
-        TestThread t = new TestThread(new Runnable() {
-            public void run() {
-                Looper.prepare();
-
-                mListener = new PhoneStateListener() {
-                    @Override
-                    public void onSignalStrengthsChanged(SignalStrength signalStrength) {
-                        synchronized(mLock) {
-                            mSignalStrength = signalStrength;
-                            mLock.notify();
-                        }
-                    }
-                };
-                mTelephonyManager.listen(mListener, PhoneStateListener.LISTEN_SIGNAL_STRENGTHS);
-
-                Looper.loop();
-            }
-        });
-
         assertTrue(mSignalStrength == null);
-        t.start();
 
+        mHandler.post(() -> {
+            mListener = new PhoneStateListener() {
+                @Override
+                public void onSignalStrengthsChanged(SignalStrength signalStrength) {
+                    synchronized (mLock) {
+                        mSignalStrength = signalStrength;
+                        mLock.notify();
+                    }
+                }
+            };
+            mTelephonyManager.listen(mListener, PhoneStateListener.LISTEN_SIGNAL_STRENGTHS);
+        });
         synchronized (mLock) {
             if (mSignalStrength == null) {
                 mLock.wait(WAIT_TIME);
             }
         }
-        t.checkException();
-        assertTrue(mSignalStrength != null);
 
+        assertTrue(mSignalStrength != null);
         // Call SignalStrength methods to make sure they do not throw any exceptions
         mSignalStrength.getCdmaDbm();
         mSignalStrength.getCdmaEcio();
@@ -452,127 +414,94 @@
             Log.d(TAG, "Skipping test that requires ConnectivityManager.TYPE_MOBILE");
             return;
         }
-
-        TestThread t = new TestThread(new Runnable() {
-            public void run() {
-                Looper.prepare();
-
-                mListener = new PhoneStateListener() {
-                    @Override
-                    public void onMessageWaitingIndicatorChanged(boolean mwi) {
-                        synchronized(mLock) {
-                            mOnMessageWaitingIndicatorChangedCalled = true;
-                            mLock.notify();
-                        }
-                    }
-                };
-                mTelephonyManager.listen(
-                        mListener, PhoneStateListener.LISTEN_MESSAGE_WAITING_INDICATOR);
-
-                Looper.loop();
-            }
-        });
-
         assertFalse(mOnMessageWaitingIndicatorChangedCalled);
-        t.start();
 
+        mHandler.post(() -> {
+            mListener = new PhoneStateListener() {
+                @Override
+                public void onMessageWaitingIndicatorChanged(boolean mwi) {
+                    synchronized (mLock) {
+                        mOnMessageWaitingIndicatorChangedCalled = true;
+                        mLock.notify();
+                    }
+                }
+            };
+            mTelephonyManager.listen(
+                    mListener, PhoneStateListener.LISTEN_MESSAGE_WAITING_INDICATOR);
+        });
         synchronized (mLock) {
             if (!mOnMessageWaitingIndicatorChangedCalled){
                 mLock.wait(WAIT_TIME);
             }
         }
-        t.checkException();
+
         assertTrue(mOnMessageWaitingIndicatorChangedCalled);
     }
 
-    /*
-     * The tests below rely on the framework to immediately call the installed listener upon
-     * registration. There is no simple way to emulate state changes for testing the listeners.
-     */
     @Test
     public void testOnPreciseCallStateChanged() throws Throwable {
         if (mCm.getNetworkInfo(ConnectivityManager.TYPE_MOBILE) == null) {
             Log.d(TAG, "Skipping test that requires ConnectivityManager.TYPE_MOBILE");
             return;
         }
-
-        TestThread t = new TestThread(new Runnable() {
-            public void run() {
-                Looper.prepare();
-
-                mListener = new PhoneStateListener() {
-                    @Override
-                    public void onPreciseCallStateChanged(PreciseCallState preciseCallState) {
-                        synchronized (mLock) {
-                            mOnPreciseCallStateChangedCalled = true;
-                            mPreciseCallState = preciseCallState;
-                            mLock.notify();
-                        }
-                    }
-                };
-                ShellIdentityUtils.invokeMethodWithShellPermissionsNoReturn(mTelephonyManager,
-                        (tm) -> tm.listen(mListener, PhoneStateListener.LISTEN_PRECISE_CALL_STATE));
-                Looper.loop();
-            }
-        });
-
         assertThat(mOnPreciseCallStateChangedCalled).isFalse();
-        t.start();
 
+        mHandler.post(() -> {
+            mListener = new PhoneStateListener() {
+                @Override
+                public void onPreciseCallStateChanged(PreciseCallState preciseCallState) {
+                    synchronized (mLock) {
+                        mOnPreciseCallStateChangedCalled = true;
+                        mPreciseCallState = preciseCallState;
+                        mLock.notify();
+                    }
+                }
+            };
+            ShellIdentityUtils.invokeMethodWithShellPermissionsNoReturn(mTelephonyManager,
+                    (tm) -> tm.listen(mListener, PhoneStateListener.LISTEN_PRECISE_CALL_STATE));
+        });
         synchronized (mLock) {
             if (!mOnPreciseCallStateChangedCalled) {
                 mLock.wait(WAIT_TIME);
             }
         }
-        t.checkException();
         Log.d(TAG, "testOnPreciseCallStateChanged: " + mOnPreciseCallStateChangedCalled);
+
         assertThat(mOnPreciseCallStateChangedCalled).isTrue();
         assertThat(mPreciseCallState.getForegroundCallState()).isIn(PRECISE_CALL_STATE);
         assertThat(mPreciseCallState.getBackgroundCallState()).isIn(PRECISE_CALL_STATE);
         assertThat(mPreciseCallState.getRingingCallState()).isIn(PRECISE_CALL_STATE);
     }
 
-    /*
-     * The tests below rely on the framework to immediately call the installed listener upon
-     * registration. There is no simple way to emulate state changes for testing the listeners.
-     */
     @Test
     public void testOnCallDisconnectCauseChanged() throws Throwable {
         if (mCm.getNetworkInfo(ConnectivityManager.TYPE_MOBILE) == null) {
             Log.d(TAG, "Skipping test that requires ConnectivityManager.TYPE_MOBILE");
             return;
         }
-
-        TestThread t = new TestThread(new Runnable() {
-            public void run() {
-                Looper.prepare();
-
-                mListener = new PhoneStateListener() {
-                    @Override
-                    public void onCallDisconnectCauseChanged(int disconnectCause,
-                                                             int preciseDisconnectCause) {
-                        synchronized (mLock) {
-                            mOnCallDisconnectCauseChangedCalled = true;
-                            mLock.notify();
-                        }
-                    }
-                };
-                ShellIdentityUtils.invokeMethodWithShellPermissionsNoReturn(mTelephonyManager,
-                            (tm) -> tm.listen(mListener,
-                                    PhoneStateListener.LISTEN_CALL_DISCONNECT_CAUSES));
-                Looper.loop();
-            }
-        });
-
         assertThat(mOnCallDisconnectCauseChangedCalled).isFalse();
-        t.start();
 
+        mHandler.post(() -> {
+            mListener = new PhoneStateListener() {
+                @Override
+                public void onCallDisconnectCauseChanged(int disconnectCause,
+                        int preciseDisconnectCause) {
+                    synchronized (mLock) {
+                        mOnCallDisconnectCauseChangedCalled = true;
+                        mLock.notify();
+                    }
+                }
+            };
+            ShellIdentityUtils.invokeMethodWithShellPermissionsNoReturn(mTelephonyManager,
+                    (tm) -> tm.listen(mListener,
+                            PhoneStateListener.LISTEN_CALL_DISCONNECT_CAUSES));
+        });
         synchronized (mLock) {
             if (!mOnCallDisconnectCauseChangedCalled){
                 mLock.wait(WAIT_TIME);
             }
         }
-        t.checkException();
+
         assertThat(mOnCallDisconnectCauseChangedCalled).isTrue();
     }
 
@@ -582,36 +511,28 @@
             Log.d(TAG, "Skipping test that requires ConnectivityManager.TYPE_MOBILE");
             return;
         }
-
-        TestThread t = new TestThread(new Runnable() {
-            public void run() {
-                Looper.prepare();
-
-                mListener = new PhoneStateListener() {
-                    @Override
-                    public void onImsCallDisconnectCauseChanged(ImsReasonInfo imsReason) {
-                        synchronized (mLock) {
-                            mOnImsCallDisconnectCauseChangedCalled = true;
-                            mLock.notify();
-                        }
-                    }
-                };
-                ShellIdentityUtils.invokeMethodWithShellPermissionsNoReturn(mTelephonyManager,
-                        (tm) -> tm.listen(mListener,
-                                PhoneStateListener.LISTEN_IMS_CALL_DISCONNECT_CAUSES));
-                Looper.loop();
-            }
-        });
-
         assertThat(mOnImsCallDisconnectCauseChangedCalled).isFalse();
-        t.start();
 
+        mHandler.post(() -> {
+            mListener = new PhoneStateListener() {
+                @Override
+                public void onImsCallDisconnectCauseChanged(ImsReasonInfo imsReason) {
+                    synchronized (mLock) {
+                        mOnImsCallDisconnectCauseChangedCalled = true;
+                        mLock.notify();
+                    }
+                }
+            };
+            ShellIdentityUtils.invokeMethodWithShellPermissionsNoReturn(mTelephonyManager,
+                    (tm) -> tm.listen(mListener,
+                            PhoneStateListener.LISTEN_IMS_CALL_DISCONNECT_CAUSES));
+        });
         synchronized (mLock) {
             if (!mOnImsCallDisconnectCauseChangedCalled){
                 mLock.wait(WAIT_TIME);
             }
         }
-        t.checkException();
+
         assertThat(mOnImsCallDisconnectCauseChangedCalled).isTrue();
     }
 
@@ -621,169 +542,130 @@
             Log.d(TAG, "Skipping test that requires ConnectivityManager.TYPE_MOBILE");
             return;
         }
-        TestThread t = new TestThread(new Runnable() {
-            public void run() {
-                Looper.prepare();
-
-                mListener = new PhoneStateListener(mSimpleExecutor) {
-                    @Override
-                    public void onSrvccStateChanged(int state) {
-                        synchronized (mLock) {
-                            mSrvccStateChangedCalled = true;
-                            mLock.notify();
-                        }
-                    }
-                };
-                ShellIdentityUtils.invokeMethodWithShellPermissionsNoReturn(mTelephonyManager,
-                        (tm) -> tm.listen(mListener,
-                                PhoneStateListener.LISTEN_SRVCC_STATE_CHANGED));
-                Looper.loop();
-            }
-        });
-
         assertThat(mSrvccStateChangedCalled).isFalse();
-        t.start();
 
+        mHandler.post(() -> {
+            mListener = new PhoneStateListener(mSimpleExecutor) {
+                @Override
+                public void onSrvccStateChanged(int state) {
+                    synchronized (mLock) {
+                        mSrvccStateChangedCalled = true;
+                        mLock.notify();
+                    }
+                }
+            };
+            ShellIdentityUtils.invokeMethodWithShellPermissionsNoReturn(mTelephonyManager,
+                    (tm) -> tm.listen(mListener,
+                            PhoneStateListener.LISTEN_SRVCC_STATE_CHANGED));
+        });
         synchronized (mLock) {
             if (!mSrvccStateChangedCalled){
                 mLock.wait(WAIT_TIME);
             }
         }
-        assertThat(mSrvccStateChangedCalled).isTrue();
-        t.checkException();
         Log.d(TAG, "testOnPhoneStateListenerExecutorWithSrvccChanged");
+
+        assertThat(mSrvccStateChangedCalled).isTrue();
     }
 
-    /*
-    * The tests below rely on the framework to immediately call the installed listener upon
-    * registration. There is no simple way to emulate state changes for testing the listeners.
-    */
     @Test
     public void testOnRadioPowerStateChanged() throws Throwable {
         if (mCm.getNetworkInfo(ConnectivityManager.TYPE_MOBILE) == null) {
             Log.d(TAG, "Skipping test that requires ConnectivityManager.TYPE_MOBILE");
             return;
         }
-        TestThread t = new TestThread(new Runnable() {
-            public void run() {
-                Looper.prepare();
-
-                mListener = new PhoneStateListener() {
-                    @Override
-                    public void onRadioPowerStateChanged(int state) {
-                        synchronized(mLock) {
-                            mRadioPowerState = state;
-                            mOnRadioPowerStateChangedCalled = true;
-                            mLock.notify();
-                        }
-                    }
-                };
-                ShellIdentityUtils.invokeMethodWithShellPermissionsNoReturn(mTelephonyManager,
-                        (tm) -> tm.listen(mListener,
-                                PhoneStateListener.LISTEN_RADIO_POWER_STATE_CHANGED));
-                Looper.loop();
-            }
-        });
         assertThat(mOnRadioPowerStateChangedCalled).isFalse();
-        t.start();
 
+        mHandler.post(() -> {
+            mListener = new PhoneStateListener() {
+                @Override
+                public void onRadioPowerStateChanged(int state) {
+                    synchronized (mLock) {
+                        mRadioPowerState = state;
+                        mOnRadioPowerStateChangedCalled = true;
+                        mLock.notify();
+                    }
+                }
+            };
+            ShellIdentityUtils.invokeMethodWithShellPermissionsNoReturn(mTelephonyManager,
+                    (tm) -> tm.listen(mListener,
+                            PhoneStateListener.LISTEN_RADIO_POWER_STATE_CHANGED));
+        });
         synchronized (mLock) {
             if (!mOnRadioPowerStateChangedCalled){
                 mLock.wait(WAIT_TIME);
             }
         }
-        t.checkException();
         Log.d(TAG, "testOnRadioPowerStateChanged: " + mRadioPowerState);
+
         assertThat(mTelephonyManager.getRadioPowerState()).isEqualTo(mRadioPowerState);
     }
 
-    /*
-     * The tests below rely on the framework to immediately call the installed listener upon
-     * registration. There is no simple way to emulate state changes for testing the listeners.
-     */
     @Test
     public void testOnVoiceActivationStateChanged() throws Throwable {
         if (mCm.getNetworkInfo(ConnectivityManager.TYPE_MOBILE) == null) {
             Log.d(TAG, "Skipping test that requires ConnectivityManager.TYPE_MOBILE");
             return;
         }
-        TestThread t = new TestThread(new Runnable() {
-            public void run() {
-                Looper.prepare();
-
-                mListener = new PhoneStateListener() {
-                    @Override
-                    public void onVoiceActivationStateChanged(int state) {
-                        synchronized(mLock) {
-                            mVoiceActivationState = state;
-                            mVoiceActivationStateChangedCalled = true;
-                            mLock.notify();
-                        }
-                    }
-                };
-                ShellIdentityUtils.invokeMethodWithShellPermissionsNoReturn(mTelephonyManager,
-                        (tm) -> tm.listen(mListener,
-                                PhoneStateListener.LISTEN_VOICE_ACTIVATION_STATE));
-                Looper.loop();
-            }
-        });
         assertThat(mVoiceActivationStateChangedCalled).isFalse();
-        t.start();
 
+        mHandler.post(() -> {
+            mListener = new PhoneStateListener() {
+                @Override
+                public void onVoiceActivationStateChanged(int state) {
+                    synchronized (mLock) {
+                        mVoiceActivationState = state;
+                        mVoiceActivationStateChangedCalled = true;
+                        mLock.notify();
+                    }
+                }
+            };
+            ShellIdentityUtils.invokeMethodWithShellPermissionsNoReturn(mTelephonyManager,
+                    (tm) -> tm.listen(mListener,
+                            PhoneStateListener.LISTEN_VOICE_ACTIVATION_STATE));
+        });
         synchronized (mLock) {
             if (!mVoiceActivationStateChangedCalled){
                 mLock.wait(WAIT_TIME);
             }
         }
-        t.checkException();
         Log.d(TAG, "onVoiceActivationStateChanged: " + mVoiceActivationState);
         int state = ShellIdentityUtils.invokeMethodWithShellPermissions(mTelephonyManager,
                 (tm) -> tm.getVoiceActivationState());
+
         assertEquals(state, mVoiceActivationState);
     }
 
-    /*
-    * The tests below rely on the framework to immediately call the installed listener upon
-    * registration. There is no simple way to emulate state changes for testing the listeners.
-    */
     @Test
     public void testOnPreciseDataConnectionStateChanged() throws Throwable {
         if (mCm.getNetworkInfo(ConnectivityManager.TYPE_MOBILE) == null) {
             Log.d(TAG, "Skipping test that requires ConnectivityManager.TYPE_MOBILE");
             return;
         }
-
-        TestThread t = new TestThread(new Runnable() {
-            public void run() {
-                Looper.prepare();
-
-                mListener = new PhoneStateListener() {
-                    @Override
-                    public void onPreciseDataConnectionStateChanged(
-                            PreciseDataConnectionState state) {
-                        synchronized(mLock) {
-                            mOnPreciseDataConnectionStateChanged = true;
-                            mPreciseDataConnectionState = state;
-                            mLock.notify();
-                        }
-                    }
-                };
-                ShellIdentityUtils.invokeMethodWithShellPermissionsNoReturn(mTelephonyManager,
-                        (tm) -> tm.listen(mListener,
-                                PhoneStateListener.LISTEN_PRECISE_DATA_CONNECTION_STATE));
-                Looper.loop();
-            }
-        });
-
         assertThat(mOnCallDisconnectCauseChangedCalled).isFalse();
-        t.start();
 
+        mHandler.post(() -> {
+            mListener = new PhoneStateListener() {
+                @Override
+                public void onPreciseDataConnectionStateChanged(
+                        PreciseDataConnectionState state) {
+                    synchronized (mLock) {
+                        mOnPreciseDataConnectionStateChanged = true;
+                        mPreciseDataConnectionState = state;
+                        mLock.notify();
+                    }
+                }
+            };
+            ShellIdentityUtils.invokeMethodWithShellPermissionsNoReturn(mTelephonyManager,
+                    (tm) -> tm.listen(mListener,
+                            PhoneStateListener.LISTEN_PRECISE_DATA_CONNECTION_STATE));
+        });
         synchronized (mLock) {
             if (!mOnPreciseDataConnectionStateChanged){
                 mLock.wait(WAIT_TIME);
             }
         }
-        t.checkException();
+
         assertThat(mOnPreciseDataConnectionStateChanged).isTrue();
         assertThat(mPreciseDataConnectionState.getState())
                 .isIn(DATA_CONNECTION_STATE);
@@ -816,37 +698,27 @@
             Log.d(TAG, "Skipping test that requires ConnectivityManager.TYPE_MOBILE");
             return;
         }
-
-        TestThread t = new TestThread(new Runnable() {
-            @Override
-            public void run() {
-                Looper.prepare();
-
-                mListener = new PhoneStateListener() {
-                    @Override
-                    public void onCallForwardingIndicatorChanged(boolean cfi) {
-                        synchronized(mLock) {
-                            mOnCallForwardingIndicatorChangedCalled = true;
-                            mLock.notify();
-                        }
-                    }
-                };
-                mTelephonyManager.listen(
-                        mListener, PhoneStateListener.LISTEN_CALL_FORWARDING_INDICATOR);
-
-                Looper.loop();
-            }
-        });
-
         assertFalse(mOnCallForwardingIndicatorChangedCalled);
-        t.start();
 
+        mHandler.post(() -> {
+            mListener = new PhoneStateListener() {
+                @Override
+                public void onCallForwardingIndicatorChanged(boolean cfi) {
+                    synchronized (mLock) {
+                        mOnCallForwardingIndicatorChangedCalled = true;
+                        mLock.notify();
+                    }
+                }
+            };
+            mTelephonyManager.listen(
+                    mListener, PhoneStateListener.LISTEN_CALL_FORWARDING_INDICATOR);
+        });
         synchronized (mLock) {
             if (!mOnCallForwardingIndicatorChangedCalled){
                 mLock.wait(WAIT_TIME);
             }
         }
-        t.checkException();
+
         assertTrue(mOnCallForwardingIndicatorChangedCalled);
     }
 
@@ -856,37 +728,27 @@
             Log.d(TAG, "Skipping test that requires ConnectivityManager.TYPE_MOBILE");
             return;
         }
+        assertFalse(mOnCellLocationChangedCalled);
 
         TelephonyManagerTest.grantLocationPermissions();
-
-        TestThread t = new TestThread(new Runnable() {
-            public void run() {
-                Looper.prepare();
-
-                mListener = new PhoneStateListener() {
-                    @Override
-                    public void onCellLocationChanged(CellLocation location) {
-                        synchronized(mLock) {
-                            mOnCellLocationChangedCalled = true;
-                            mLock.notify();
-                        }
+        mHandler.post(() -> {
+            mListener = new PhoneStateListener() {
+                @Override
+                public void onCellLocationChanged(CellLocation location) {
+                    synchronized (mLock) {
+                        mOnCellLocationChangedCalled = true;
+                        mLock.notify();
                     }
-                };
-                mTelephonyManager.listen(mListener, PhoneStateListener.LISTEN_CELL_LOCATION);
-
-                Looper.loop();
-            }
+                }
+            };
+            mTelephonyManager.listen(mListener, PhoneStateListener.LISTEN_CELL_LOCATION);
         });
-
-        assertFalse(mOnCellLocationChangedCalled);
-        t.start();
-
         synchronized (mLock) {
             if (!mOnCellLocationChangedCalled){
                 mLock.wait(WAIT_TIME);
             }
         }
-        t.checkException();
+
         assertTrue(mOnCellLocationChangedCalled);
     }
 
@@ -896,35 +758,26 @@
             Log.d(TAG, "Skipping test that requires ConnectivityManager.TYPE_MOBILE");
             return;
         }
-
-        TestThread t = new TestThread(new Runnable() {
-            public void run() {
-                Looper.prepare();
-
-                mListener = new PhoneStateListener() {
-                    @Override
-                    public void onCallStateChanged(int state, String incomingNumber) {
-                        synchronized(mLock) {
-                            mOnCallStateChangedCalled = true;
-                            mLock.notify();
-                        }
-                    }
-                };
-                mTelephonyManager.listen(mListener, PhoneStateListener.LISTEN_CALL_STATE);
-
-                Looper.loop();
-            }
-        });
-
         assertFalse(mOnCallStateChangedCalled);
-        t.start();
 
+        mHandler.post(() -> {
+            mListener = new PhoneStateListener() {
+                @Override
+                public void onCallStateChanged(int state, String incomingNumber) {
+                    synchronized (mLock) {
+                        mOnCallStateChangedCalled = true;
+                        mLock.notify();
+                    }
+                }
+            };
+            mTelephonyManager.listen(mListener, PhoneStateListener.LISTEN_CALL_STATE);
+        });
         synchronized (mLock) {
             if (!mOnCallStateChangedCalled){
                 mLock.wait(WAIT_TIME);
             }
         }
-        t.checkException();
+
         assertTrue(mOnCallStateChangedCalled);
     }
 
@@ -934,51 +787,42 @@
             Log.d(TAG, "Skipping test that requires ConnectivityManager.TYPE_MOBILE");
             return;
         }
-
-        TestThread t = new TestThread(new Runnable() {
-            public void run() {
-                Looper.prepare();
-
-                mListener = new PhoneStateListener() {
-                    @Override
-                    public void onDataConnectionStateChanged(int state) {
-                        synchronized(mLock) {
-                            mOnDataConnectionStateChangedCalled = true;
-                            if (mOnDataConnectionStateChangedCalled
-                                    && mOnDataConnectionStateChangedWithNetworkTypeCalled) {
-                                mLock.notify();
-                            }
-                        }
-                    }
-                    @Override
-                    public void onDataConnectionStateChanged(int state, int networkType) {
-                        synchronized(mLock) {
-                            mOnDataConnectionStateChangedWithNetworkTypeCalled = true;
-                            if (mOnDataConnectionStateChangedCalled
-                                    && mOnDataConnectionStateChangedWithNetworkTypeCalled) {
-                                mLock.notify();
-                            }
-                        }
-                    }
-                };
-                mTelephonyManager.listen(
-                        mListener, PhoneStateListener.LISTEN_DATA_CONNECTION_STATE);
-
-                Looper.loop();
-            }
-        });
-
         assertFalse(mOnDataConnectionStateChangedCalled);
         assertFalse(mOnDataConnectionStateChangedWithNetworkTypeCalled);
-        t.start();
 
+        mHandler.post(() -> {
+            mListener = new PhoneStateListener() {
+                @Override
+                public void onDataConnectionStateChanged(int state) {
+                    synchronized (mLock) {
+                        mOnDataConnectionStateChangedCalled = true;
+                        if (mOnDataConnectionStateChangedCalled
+                                && mOnDataConnectionStateChangedWithNetworkTypeCalled) {
+                            mLock.notify();
+                        }
+                    }
+                }
+                @Override
+                public void onDataConnectionStateChanged(int state, int networkType) {
+                    synchronized (mLock) {
+                        mOnDataConnectionStateChangedWithNetworkTypeCalled = true;
+                        if (mOnDataConnectionStateChangedCalled
+                                && mOnDataConnectionStateChangedWithNetworkTypeCalled) {
+                            mLock.notify();
+                        }
+                    }
+                }
+            };
+            mTelephonyManager.listen(
+                    mListener, PhoneStateListener.LISTEN_DATA_CONNECTION_STATE);
+        });
         synchronized (mLock) {
             if (!mOnDataConnectionStateChangedCalled ||
                     !mOnDataConnectionStateChangedWithNetworkTypeCalled){
                 mLock.wait(WAIT_TIME);
             }
         }
-        t.checkException();
+
         assertTrue(mOnDataConnectionStateChangedCalled);
         assertTrue(mOnDataConnectionStateChangedWithNetworkTypeCalled);
     }
@@ -989,35 +833,26 @@
             Log.d(TAG, "Skipping test that requires ConnectivityManager.TYPE_MOBILE");
             return;
         }
-
-        TestThread t = new TestThread(new Runnable() {
-            public void run() {
-                Looper.prepare();
-
-                mListener = new PhoneStateListener() {
-                    @Override
-                    public void onDataActivity(int direction) {
-                        synchronized(mLock) {
-                            mOnDataActivityCalled = true;
-                            mLock.notify();
-                        }
-                    }
-                };
-                mTelephonyManager.listen(mListener, PhoneStateListener.LISTEN_DATA_ACTIVITY);
-
-                Looper.loop();
-            }
-        });
-
         assertFalse(mOnDataActivityCalled);
-        t.start();
 
+        mHandler.post(() -> {
+            mListener =  new PhoneStateListener() {
+                @Override
+                public void onDataActivity(int direction) {
+                    synchronized (mLock) {
+                        mOnDataActivityCalled = true;
+                        mLock.notify();
+                    }
+                }
+            };
+            mTelephonyManager.listen(mListener, PhoneStateListener.LISTEN_DATA_ACTIVITY);
+        });
         synchronized (mLock) {
             if (!mOnDataActivityCalled){
                 mLock.wait(WAIT_TIME);
             }
         }
-        t.checkException();
+
         assertTrue(mOnDataActivityCalled);
     }
 
@@ -1027,37 +862,27 @@
             Log.d(TAG, "Skipping test that requires ConnectivityManager.TYPE_MOBILE");
             return;
         }
+        assertFalse(mOnDataActivityCalled);
 
         TelephonyManagerTest.grantLocationPermissions();
-
-        TestThread t = new TestThread(new Runnable() {
-            public void run() {
-                Looper.prepare();
-
-                mListener = new PhoneStateListener() {
-                    @Override
-                    public void onCellInfoChanged(List<CellInfo> cellInfo) {
-                        synchronized(mLock) {
-                            mOnCellInfoChangedCalled = true;
-                            mLock.notify();
-                        }
+        mHandler.post(() -> {
+            mListener = new PhoneStateListener() {
+                @Override
+                public void onCellInfoChanged(List<CellInfo> cellInfo) {
+                    synchronized (mLock) {
+                        mOnCellInfoChangedCalled = true;
+                        mLock.notify();
                     }
-                };
-                mTelephonyManager.listen(mListener, PhoneStateListener.LISTEN_CELL_INFO);
-
-                Looper.loop();
-            }
+                }
+            };
+            mTelephonyManager.listen(mListener, PhoneStateListener.LISTEN_CELL_INFO);
         });
-
-        assertFalse(mOnDataActivityCalled);
-        t.start();
-
         synchronized (mLock) {
             if (!mOnCellInfoChangedCalled){
                 mLock.wait(WAIT_TIME);
             }
         }
-        t.checkException();
+
         assertTrue(mOnCellInfoChangedCalled);
     }
 
@@ -1067,36 +892,27 @@
             Log.d(TAG, "Skipping test that requires ConnectivityManager.TYPE_MOBILE");
             return;
         }
-
-        TestThread t = new TestThread(new Runnable() {
-            public void run() {
-                Looper.prepare();
-
-                mListener = new PhoneStateListener() {
-                    @Override
-                    public void onUserMobileDataStateChanged(boolean state) {
-                        synchronized(mLock) {
-                            mOnUserMobileDataStateChanged = true;
-                            mLock.notify();
-                        }
-                    }
-                };
-                mTelephonyManager.listen(
-                        mListener, PhoneStateListener.LISTEN_USER_MOBILE_DATA_STATE);
-
-                Looper.loop();
-            }
-        });
-
         assertFalse(mOnUserMobileDataStateChanged);
-        t.start();
 
+        mHandler.post(() -> {
+            mListener = new PhoneStateListener() {
+                @Override
+                public void onUserMobileDataStateChanged(boolean state) {
+                    synchronized (mLock) {
+                        mOnUserMobileDataStateChanged = true;
+                        mLock.notify();
+                    }
+                }
+            };
+            mTelephonyManager.listen(
+                    mListener, PhoneStateListener.LISTEN_USER_MOBILE_DATA_STATE);
+        });
         synchronized (mLock) {
             if (!mOnUserMobileDataStateChanged){
                 mLock.wait(WAIT_TIME);
             }
         }
-        t.checkException();
+
         assertTrue(mOnUserMobileDataStateChanged);
     }
 
@@ -1106,45 +922,39 @@
             Log.d(TAG, "Skipping test that requires ConnectivityManager.TYPE_MOBILE");
             return;
         }
+
         TelephonyUtils.addTestEmergencyNumber(
                 InstrumentationRegistry.getInstrumentation(), TEST_EMERGENCY_NUMBER);
-        HandlerThread mPhoneStateListenerThread = new HandlerThread("PhoneStateListenerThread");
-        mPhoneStateListenerThread.start();
-        Handler mPhoneStateListenerHandler = new Handler(mPhoneStateListenerThread.getLooper());
-        final CountDownLatch latch = new CountDownLatch(1);
 
-        mPhoneStateListenerHandler.post(new Runnable() {
-            @Override
-            public void run() {
-                mListener = new PhoneStateListener() {
-                    @Override
-                    public void onOutgoingEmergencySms(EmergencyNumber emergencyNumber) {
+        assertNull(mOnOutgoingSmsEmergencyNumberChanged);
+
+        mHandler.post(() -> {
+            mListener = new PhoneStateListener() {
+                @Override
+                public void onOutgoingEmergencySms(EmergencyNumber emergencyNumber) {
+                    synchronized (mLock) {
                         Log.i(TAG, "onOutgoingEmergencySms: emergencyNumber=" + emergencyNumber);
                         mOnOutgoingSmsEmergencyNumberChanged = emergencyNumber;
-                        latch.countDown();
+                        mLock.notify();
                     }
-                };
-                ShellIdentityUtils.invokeMethodWithShellPermissionsNoReturn(mTelephonyManager,
-                        (tm) -> tm.listen(mListener,
-                                PhoneStateListener.LISTEN_OUTGOING_EMERGENCY_SMS));
-            }
-        });
-        assertNull(mOnOutgoingSmsEmergencyNumberChanged);
-        SmsManager.getDefault().sendTextMessage(
+                }
+            };
+            ShellIdentityUtils.invokeMethodWithShellPermissionsNoReturn(mTelephonyManager,
+                    (tm) -> tm.listen(mListener,
+                            PhoneStateListener.LISTEN_OUTGOING_EMERGENCY_SMS));
+            SmsManager.getDefault().sendTextMessage(
                 TEST_EMERGENCY_NUMBER, null, "testOutgoingSmsListenerCts", null, null);
+        });
 
         try {
-            latch.await(5000, TimeUnit.MILLISECONDS);
+            synchronized (mLock) {
+                if (mOnOutgoingSmsEmergencyNumberChanged == null) {
+                    mLock.wait(WAIT_TIME);
+                }
+            }
         } catch (InterruptedException e) {
             Log.e(TAG, "Operation interrupted.");
         } finally {
-            mPhoneStateListenerHandler.post(new Runnable() {
-                @Override
-                public void run() {
-                    mTelephonyManager.listen(mListener, PhoneStateListener.LISTEN_NONE);
-                }
-            });
-            mPhoneStateListenerThread.quitSafely();
             TelephonyUtils.removeTestEmergencyNumber(
                     InstrumentationRegistry.getInstrumentation(), TEST_EMERGENCY_NUMBER);
         }
@@ -1159,36 +969,27 @@
             Log.d(TAG, "Skipping test that requires ConnectivityManager.TYPE_MOBILE");
             return;
         }
-
-        TestThread t = new TestThread(new Runnable() {
-            public void run() {
-                Looper.prepare();
-
-                mListener = new PhoneStateListener() {
-                    @Override
-                    public void onActiveDataSubscriptionIdChanged(int subId) {
-                        synchronized(mLock) {
-                            mOnActiveDataSubscriptionIdChanged = true;
-                            mLock.notify();
-                        }
-                    }
-                };
-                mTelephonyManager.listen(
-                        mListener, PhoneStateListener.LISTEN_ACTIVE_DATA_SUBSCRIPTION_ID_CHANGE);
-
-                Looper.loop();
-            }
-        });
-
         assertFalse(mOnActiveDataSubscriptionIdChanged);
-        t.start();
 
+        mHandler.post(() -> {
+            mListener = new PhoneStateListener() {
+                @Override
+                public void onActiveDataSubscriptionIdChanged(int subId) {
+                    synchronized (mLock) {
+                        mOnActiveDataSubscriptionIdChanged = true;
+                        mLock.notify();
+                    }
+                }
+            };
+            mTelephonyManager.listen(
+                    mListener, PhoneStateListener.LISTEN_ACTIVE_DATA_SUBSCRIPTION_ID_CHANGE);
+        });
         synchronized (mLock) {
             if (!mOnActiveDataSubscriptionIdChanged){
                 mLock.wait(WAIT_TIME);
             }
         }
-        t.checkException();
+
         assertTrue(mOnActiveDataSubscriptionIdChanged);
     }
 
@@ -1199,37 +1000,27 @@
             return;
         }
 
-        TestThread t = new TestThread(new Runnable() {
-            public void run() {
-                Looper.prepare();
-
-                mListener = new PhoneStateListener() {
-                    @Override
-                    public void onBarringInfoChanged(BarringInfo barringInfo) {
-                        synchronized (mLock) {
-                            mOnBarringInfoChangedCalled = true;
-                            mBarringInfo = barringInfo;
-                            mLock.notify();
-                        }
-                    }
-                };
-
-                ShellIdentityUtils.invokeMethodWithShellPermissionsNoReturn(mTelephonyManager,
-                        (tm) -> tm.listen(mListener, PhoneStateListener.LISTEN_BARRING_INFO));
-
-                Looper.loop();
-            }
-        });
-
         assertFalse(mOnBarringInfoChangedCalled);
-        t.start();
+        mHandler.post(() -> {
+            mListener = new PhoneStateListener() {
+                @Override
+                public void onBarringInfoChanged(BarringInfo barringInfo) {
+                    synchronized (mLock) {
+                        mOnBarringInfoChangedCalled = true;
+                        mBarringInfo = barringInfo;
+                        mLock.notify();
+                    }
+                }
+            };
+            ShellIdentityUtils.invokeMethodWithShellPermissionsNoReturn(mTelephonyManager,
+                    (tm) -> tm.listen(mListener, PhoneStateListener.LISTEN_BARRING_INFO));
+        });
 
         synchronized (mLock) {
             if (!mOnBarringInfoChangedCalled) {
                 mLock.wait(WAIT_TIME);
             }
         }
-        t.checkException();
         assertTrue(mOnBarringInfoChangedCalled);
 
         assertBarringInfoSane(mBarringInfo);
@@ -1299,38 +1090,28 @@
             return;
         }
 
-        TestThread t = new TestThread(new Runnable() {
-            public void run() {
-                Looper.prepare();
-
-                mListener = new PhoneStateListener() {
-                    @Override
-                    public void onRegistrationFailed(CellIdentity cid, String chosenPlmn,
-                            int domain, int causeCode, int additionalCauseCode) {
-                        synchronized (mLock) {
-                            mOnRegistrationFailedCalled = true;
-                            mLock.notify();
-                        }
-                    }
-                };
-
-                ShellIdentityUtils.invokeMethodWithShellPermissionsNoReturn(mTelephonyManager,
-                        (tm) -> tm.listen(mListener,
-                                PhoneStateListener.LISTEN_REGISTRATION_FAILURE));
-
-                Looper.loop();
-            }
-        });
-
         assertFalse(mOnBarringInfoChangedCalled);
-        t.start();
+        mHandler.post(() -> {
+            mListener =  new PhoneStateListener() {
+                @Override
+                public void onRegistrationFailed(CellIdentity cid, String chosenPlmn,
+                        int domain, int causeCode, int additionalCauseCode) {
+                    synchronized (mLock) {
+                        mOnRegistrationFailedCalled = true;
+                        mLock.notify();
+                    }
+                }
+            };
+            ShellIdentityUtils.invokeMethodWithShellPermissionsNoReturn(mTelephonyManager,
+                    (tm) -> tm.listen(mListener,
+                            PhoneStateListener.LISTEN_REGISTRATION_FAILURE));
+        });
 
         synchronized (mLock) {
             if (!mOnBarringInfoChangedCalled) {
                 mLock.wait(WAIT_TIME);
             }
         }
-        t.checkException();
 
         // Assert that in the WAIT_TIME interval, the listener wasn't invoked. While this is
         // **technically** a flaky test, in practice this flake should happen approximately never
diff --git a/tests/tests/telephony/current/src/android/telephony/cts/SmsCbEtwsInfoTest.java b/tests/tests/telephony/current/src/android/telephony/cts/SmsCbEtwsInfoTest.java
new file mode 100644
index 0000000..05cffda
--- /dev/null
+++ b/tests/tests/telephony/current/src/android/telephony/cts/SmsCbEtwsInfoTest.java
@@ -0,0 +1,73 @@
+/*
+ * Copyright (C) 2009 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.telephony.cts;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+
+import android.telephony.SmsCbEtwsInfo;
+
+import com.android.internal.telephony.gsm.SmsCbConstants;
+
+import org.junit.Test;
+
+public class SmsCbEtwsInfoTest {
+
+    private static final int TEST_ETWS_WARNING_TYPE =
+            SmsCbConstants.MESSAGE_ID_ETWS_OTHER_EMERGENCY_TYPE;
+
+    @Test
+    public void testIsPrimary() {
+        SmsCbEtwsInfo info = new SmsCbEtwsInfo(TEST_ETWS_WARNING_TYPE,
+                false, false, false, null);
+        assertFalse(info.isPrimary());
+
+        SmsCbEtwsInfo info2 = new SmsCbEtwsInfo(TEST_ETWS_WARNING_TYPE,
+                false, false, true, null);
+        assertTrue(info2.isPrimary());
+    }
+
+    @Test
+    public void testIsPopupAlert() {
+        SmsCbEtwsInfo info = new SmsCbEtwsInfo(TEST_ETWS_WARNING_TYPE,
+                false, false, false, null);
+        assertFalse(info.isPopupAlert());
+
+        SmsCbEtwsInfo info2 = new SmsCbEtwsInfo(TEST_ETWS_WARNING_TYPE,
+                false, true, false, null);
+        assertTrue(info2.isPopupAlert());
+    }
+
+    @Test
+    public void testIsEmergencyUserAlert() {
+        SmsCbEtwsInfo info = new SmsCbEtwsInfo(TEST_ETWS_WARNING_TYPE,
+                false, false, false, null);
+        assertFalse(info.isEmergencyUserAlert());
+
+        SmsCbEtwsInfo info2 = new SmsCbEtwsInfo(TEST_ETWS_WARNING_TYPE,
+                true, false, false, null);
+        assertTrue(info2.isEmergencyUserAlert());
+    }
+
+    @Test
+    public void testGetWarningType() {
+        SmsCbEtwsInfo info = new SmsCbEtwsInfo(TEST_ETWS_WARNING_TYPE,
+                false, false, false, null);
+        assertEquals(TEST_ETWS_WARNING_TYPE, info.getWarningType());
+    }
+}
diff --git a/tests/tests/telephony/current/src/android/telephony/cts/SmsCbLocationTest.java b/tests/tests/telephony/current/src/android/telephony/cts/SmsCbLocationTest.java
index 69c851f..0544fbc 100644
--- a/tests/tests/telephony/current/src/android/telephony/cts/SmsCbLocationTest.java
+++ b/tests/tests/telephony/current/src/android/telephony/cts/SmsCbLocationTest.java
@@ -16,12 +16,19 @@
 package android.telephony.cts;
 
 import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
 
 import android.telephony.SmsCbLocation;
 
 import org.junit.Test;
 
 public class SmsCbLocationTest {
+    private static final String PLMN = "TEST_PLMN";
+    private static final String PLMN2 = "TEST_PLMN 2";
+    private static final int LAC = -1;
+    private static final int CID = -1;
+
     @Test
     public void testSmsCbLocation() throws Throwable {
         SmsCbLocation cbLocation = new SmsCbLocation("94040", 1234, 5678);
@@ -29,4 +36,15 @@
         assertEquals(1234, cbLocation.getLac());
         assertEquals(5678, cbLocation.getCid());
     }
+
+    @Test
+    public void testIsInLocationArea() {
+        SmsCbLocation cbLocation = new SmsCbLocation(PLMN, LAC, CID);
+
+        SmsCbLocation area = new SmsCbLocation(PLMN, LAC, CID);
+        assertTrue(cbLocation.isInLocationArea(area));
+
+        SmsCbLocation area2 = new SmsCbLocation(PLMN2, LAC, CID);
+        assertFalse(cbLocation.isInLocationArea(area2));
+    }
 }
diff --git a/tests/tests/telephony/current/src/android/telephony/cts/SmsCbMessageTest.java b/tests/tests/telephony/current/src/android/telephony/cts/SmsCbMessageTest.java
index c74332c..6b2ddbb 100644
--- a/tests/tests/telephony/current/src/android/telephony/cts/SmsCbMessageTest.java
+++ b/tests/tests/telephony/current/src/android/telephony/cts/SmsCbMessageTest.java
@@ -18,8 +18,13 @@
 package android.telephony.cts;
 
 import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNull;
+import static org.mockito.ArgumentMatchers.eq;
+import static org.mockito.Mockito.doReturn;
+import static org.mockito.Mockito.mock;
 
 import android.content.ContentValues;
+import android.database.Cursor;
 import android.provider.Telephony;
 import android.telephony.CbGeoUtils;
 import android.telephony.SmsCbCmasInfo;
@@ -61,7 +66,7 @@
 
     private static final int TEST_MAX_WAIT_TIME = 0;
     private static final List<CbGeoUtils.Geometry> TEST_GEOS = new ArrayList<>();
-    private static final int TEST_RECEIVED_TIME = 11000;
+    private static final long TEST_RECEIVED_TIME = 11000;
     private static final int TEST_SLOT = 0;
     private static final int TEST_SUB_ID = 1;
 
@@ -229,4 +234,78 @@
         int serial = cv.getAsInteger(Telephony.CellBroadcasts.SERIAL_NUMBER);
         assertEquals(TEST_SERIAL, serial);
     }
+
+    @Test
+    public void testCreateFromCursor() {
+        Cursor cursor = mock(Cursor.class);
+        doReturn(0).when(cursor).getColumnIndexOrThrow(eq(
+                Telephony.CellBroadcasts.GEOGRAPHICAL_SCOPE));
+        doReturn(TEST_GEO_SCOPE).when(cursor).getInt(0);
+
+        doReturn(1).when(cursor).getColumnIndexOrThrow(eq(
+                Telephony.CellBroadcasts.SERIAL_NUMBER));
+        doReturn(TEST_SERIAL).when(cursor).getInt(1);
+
+        doReturn(2).when(cursor).getColumnIndexOrThrow(eq(
+                Telephony.CellBroadcasts.SERVICE_CATEGORY));
+        doReturn(TEST_SERVICE_CATEGORY).when(cursor).getInt(2);
+
+        doReturn(3).when(cursor).getColumnIndexOrThrow(eq(
+                Telephony.CellBroadcasts.LANGUAGE_CODE));
+        doReturn(TEST_LANGUAGE).when(cursor).getString(3);
+
+        doReturn(4).when(cursor).getColumnIndexOrThrow(eq(
+                Telephony.CellBroadcasts.MESSAGE_BODY));
+        doReturn(TEST_BODY).when(cursor).getString(4);
+
+        doReturn(5).when(cursor).getColumnIndexOrThrow(eq(
+                Telephony.CellBroadcasts.MESSAGE_FORMAT));
+        doReturn(TEST_MESSAGE_FORMAT).when(cursor).getInt(5);
+
+        doReturn(6).when(cursor).getColumnIndexOrThrow(eq(
+                Telephony.CellBroadcasts.MESSAGE_PRIORITY));
+        doReturn(TEST_PRIORITY).when(cursor).getInt(6);
+
+        doReturn(7).when(cursor).getColumnIndexOrThrow(eq(
+                Telephony.CellBroadcasts.SLOT_INDEX));
+        doReturn(TEST_SLOT).when(cursor).getInt(7);
+
+        doReturn(8).when(cursor).getColumnIndexOrThrow(eq(
+                Telephony.CellBroadcasts.SUBSCRIPTION_ID));
+        doReturn(TEST_SUB_ID).when(cursor).getInt(8);
+
+        doReturn(-1).when(cursor).getColumnIndexOrThrow(eq(
+                Telephony.CellBroadcasts.PLMN));
+
+        doReturn(-1).when(cursor).getColumnIndexOrThrow(eq(
+                Telephony.CellBroadcasts.LAC));
+
+        doReturn(-1).when(cursor).getColumnIndexOrThrow(eq(
+                Telephony.CellBroadcasts.CID));
+
+        doReturn(-1).when(cursor).getColumnIndex(eq(
+                Telephony.CellBroadcasts.ETWS_WARNING_TYPE));
+
+        doReturn(-1).when(cursor).getColumnIndex(eq(
+                Telephony.CellBroadcasts.CMAS_MESSAGE_CLASS));
+
+        doReturn(9).when(cursor).getColumnIndex(eq(
+                Telephony.CellBroadcasts.GEOMETRIES));
+        // return empty string here to be parsed into empty array list
+        doReturn("").when(cursor).getString(9);
+
+        doReturn(10).when(cursor).getColumnIndexOrThrow(eq(
+                Telephony.CellBroadcasts.RECEIVED_TIME));
+        doReturn(TEST_RECEIVED_TIME).when(cursor).getLong(10);
+
+        doReturn(11).when(cursor).getColumnIndexOrThrow(eq(
+                Telephony.CellBroadcasts.MAXIMUM_WAIT_TIME));
+        doReturn(TEST_MAX_WAIT_TIME).when(cursor).getInt(11);
+
+        SmsCbMessage cbMessage = SmsCbMessage.createFromCursor(cursor);
+        assertEquals(TEST_SERIAL, cbMessage.getSerialNumber());
+        assertEquals(TEST_BODY, cbMessage.getMessageBody());
+        assertNull(cbMessage.getEtwsWarningInfo());
+        assertNull(cbMessage.getCmasWarningInfo());
+    }
 }
diff --git a/tests/tests/telephony/current/src/android/telephony/cts/SubscriptionManagerTest.java b/tests/tests/telephony/current/src/android/telephony/cts/SubscriptionManagerTest.java
index b330597..cf58926 100644
--- a/tests/tests/telephony/current/src/android/telephony/cts/SubscriptionManagerTest.java
+++ b/tests/tests/telephony/current/src/android/telephony/cts/SubscriptionManagerTest.java
@@ -32,6 +32,7 @@
 
 import android.annotation.Nullable;
 import android.content.pm.PackageManager;
+import android.content.res.Resources;
 import android.net.ConnectivityManager;
 import android.net.ConnectivityManager.NetworkCallback;
 import android.net.Network;
@@ -189,6 +190,17 @@
     }
 
     @Test
+    public void testGetResourcesForSubId() {
+        if (!isSupported()) return;
+        Resources r = ShellIdentityUtils.invokeMethodWithShellPermissions(mSm,
+                (sm) -> sm.getResourcesForSubId(InstrumentationRegistry.getContext(), mSubId));
+        // this is an old method which returns mcc/mnc as ints, so use the old SM.getMcc/Mnc methods
+        // because they also use ints
+        assertEquals(mSm.getActiveSubscriptionInfo(mSubId).getMcc(), r.getConfiguration().mcc);
+        assertEquals(mSm.getActiveSubscriptionInfo(mSubId).getMnc(), r.getConfiguration().mnc);
+    }
+
+    @Test
     public void testIsUsableSubscriptionId() throws Exception {
         if (!isSupported()) return;
         assertTrue(SubscriptionManager.isUsableSubscriptionId(mSubId));
@@ -674,7 +686,7 @@
             setPreferredDataSubId(SubscriptionManager.DEFAULT_SUBSCRIPTION_ID);
         }
 
-        List<SubscriptionInfo> subscriptionInfos = mSm.getActiveAndHiddenSubscriptionInfoList();
+        List<SubscriptionInfo> subscriptionInfos = mSm.getCompleteActiveSubscriptionInfoList();
 
         for (SubscriptionInfo subInfo : subscriptionInfos) {
             // Only test on opportunistic subscriptions.
diff --git a/tests/tests/telephony/current/src/android/telephony/cts/TelephonyManagerTest.java b/tests/tests/telephony/current/src/android/telephony/cts/TelephonyManagerTest.java
index 95fb410..cabc0e1 100644
--- a/tests/tests/telephony/current/src/android/telephony/cts/TelephonyManagerTest.java
+++ b/tests/tests/telephony/current/src/android/telephony/cts/TelephonyManagerTest.java
@@ -46,6 +46,7 @@
 import android.os.IBinder;
 import android.os.Looper;
 import android.os.PersistableBundle;
+import android.os.Process;
 import android.os.RemoteException;
 import android.telecom.PhoneAccount;
 import android.telecom.PhoneAccountHandle;
@@ -54,7 +55,6 @@
 import android.telephony.Annotation.RadioPowerState;
 import android.telephony.AvailableNetworkInfo;
 import android.telephony.CallAttributes;
-import android.telephony.CallForwardingInfo;
 import android.telephony.CallQuality;
 import android.telephony.CarrierConfigManager;
 import android.telephony.CellLocation;
@@ -84,6 +84,7 @@
 
 import org.junit.After;
 import org.junit.Before;
+import org.junit.Ignore;
 import org.junit.Test;
 
 import java.security.MessageDigest;
@@ -530,12 +531,24 @@
         mTelephonyManager.getSubscriptionId(defaultAccount);
         mTelephonyManager.getCarrierConfig();
         ShellIdentityUtils.invokeMethodWithShellPermissions(mTelephonyManager,
-                (tm) -> tm.isDataConnectionEnabled());
+                (tm) -> tm.isDataConnectionAllowed());
         ShellIdentityUtils.invokeMethodWithShellPermissions(mTelephonyManager,
                 (tm) -> tm.isAnyRadioPoweredOn());
         ShellIdentityUtils.invokeMethodWithShellPermissionsNoReturn(mTelephonyManager,
                 (tm) -> tm.resetIms(tm.getSlotIndex()));
 
+        // Verify TelephonyManager.getCarrierPrivilegeStatus
+        List<Integer> validCarrierPrivilegeStatus = new ArrayList<>();
+        validCarrierPrivilegeStatus.add(TelephonyManager.CARRIER_PRIVILEGE_STATUS_HAS_ACCESS);
+        validCarrierPrivilegeStatus.add(TelephonyManager.CARRIER_PRIVILEGE_STATUS_NO_ACCESS);
+        validCarrierPrivilegeStatus.add(
+                TelephonyManager.CARRIER_PRIVILEGE_STATUS_RULES_NOT_LOADED);
+        validCarrierPrivilegeStatus.add(
+                TelephonyManager.CARRIER_PRIVILEGE_STATUS_ERROR_LOADING_RULES);
+        int carrierPrivilegeStatusResult = ShellIdentityUtils.invokeMethodWithShellPermissions(
+                mTelephonyManager, (tm) -> tm.getCarrierPrivilegeStatus(Process.myUid()));
+        assertTrue(validCarrierPrivilegeStatus.contains(carrierPrivilegeStatusResult));
+
         // Verify TelephonyManager.getCarrierPrivilegedPackagesForAllActiveSubscriptions
         List<String> resultForGetCarrierPrivilegedApis =
                 ShellIdentityUtils.invokeMethodWithShellPermissions(mTelephonyManager,
@@ -545,9 +558,14 @@
             assertFalse(TextUtils.isEmpty(result));
         }
 
-        TelephonyManager.getDefaultRespondViaMessageApplication(getContext(), false);
+        mTelephonyManager.getDefaultRespondViaMessageApplication();
+        mTelephonyManager.getAndUpdateDefaultRespondViaMessageApplication();
     }
 
+    /**
+     * Due to the corresponding API is hidden in R and will be public in S, this test
+     * is commented and will be un-commented in Android S.
+     *
     @Test
     public void testGetCallForwarding() {
         List<Integer> callForwardingReasons = new ArrayList<>();
@@ -579,7 +597,12 @@
             assertTrue(callForwardingInfo.getTimeoutSeconds() >= 0);
         }
     }
+     */
 
+    /**
+     * Due to the corresponding API is hidden in R and will be public in S, this test
+     * is commented and will be un-commented in Android S.
+     *
     @Test
     public void testSetCallForwarding() {
         List<Integer> callForwardingReasons = new ArrayList<>();
@@ -596,10 +619,12 @@
                     CallForwardingInfo.STATUS_ACTIVE,
                     callForwardingReasonToEnable,
                     TEST_FORWARD_NUMBER,
-                    1 /** time seconds */);
+                    // time seconds
+                    1);
             Log.d(TAG, "[testSetCallForwarding] Enable Call Forwarding. Status: "
-                    + CallForwardingInfo.STATUS_ACTIVE + " Reason: " + callForwardingReasonToEnable
-                    + " Number: " + TEST_FORWARD_NUMBER + " Time Seconds: 1");
+                    + CallForwardingInfo.STATUS_ACTIVE + " Reason: "
+                    + callForwardingReasonToEnable + " Number: " + TEST_FORWARD_NUMBER
+                    + " Time Seconds: 1");
             ShellIdentityUtils.invokeMethodWithShellPermissions(mTelephonyManager,
                     (tm) -> tm.setCallForwarding(callForwardingInfoToEnable));
         }
@@ -610,7 +635,8 @@
                     CallForwardingInfo.STATUS_INACTIVE,
                     callForwardingReasonToDisable,
                     TEST_FORWARD_NUMBER,
-                    1 /** time seconds */);
+                    // time seconds
+                    1);
             Log.d(TAG, "[testSetCallForwarding] Disable Call Forwarding. Status: "
                     + CallForwardingInfo.STATUS_INACTIVE + " Reason: "
                     + callForwardingReasonToDisable + " Number: " + TEST_FORWARD_NUMBER
@@ -619,7 +645,12 @@
                     (tm) -> tm.setCallForwarding(callForwardingInfoToDisable));
         }
     }
+    */
 
+    /**
+     * Due to the corresponding API is hidden in R and will be public in S, this test
+     * is commented and will be un-commented in Android S.
+     *
     @Test
     public void testGetCallWaitingStatus() {
         Set<Integer> callWaitingStatus = new HashSet<Integer>();
@@ -632,7 +663,12 @@
                 mTelephonyManager, (tm) -> tm.getCallWaitingStatus());
         assertTrue(callWaitingStatus.contains(status));
     }
+     */
 
+    /**
+     * Due to the corresponding API is hidden in R and will be public in S, this test
+     * is commented and will be un-commented in Android S.
+     *
     @Test
     public void testSetCallWaitingStatus() {
         ShellIdentityUtils.invokeMethodWithShellPermissions(mTelephonyManager,
@@ -640,6 +676,7 @@
         ShellIdentityUtils.invokeMethodWithShellPermissions(mTelephonyManager,
                 (tm) -> tm.setCallWaitingStatus(false));
     }
+     */
 
     @Test
     public void testCellLocationFinePermission() {
@@ -1448,6 +1485,7 @@
      * Verifies that {@link TelephonyManager#getIsimImpu()} does not throw any exception when called
      * and has the correct permissions.
      */
+    @Ignore("API moved back to @hide for Android R.")
     @Test
     public void testGetIsimImpu() {
         if (!mPackageManager.hasSystemFeature(PackageManager.FEATURE_TELEPHONY)) {
diff --git a/tests/tests/telephony/current/src/android/telephony/ims/cts/ImsCallProfileTest.java b/tests/tests/telephony/current/src/android/telephony/ims/cts/ImsCallProfileTest.java
index 5b16d71..a35dfd7 100644
--- a/tests/tests/telephony/current/src/android/telephony/ims/cts/ImsCallProfileTest.java
+++ b/tests/tests/telephony/current/src/android/telephony/ims/cts/ImsCallProfileTest.java
@@ -106,6 +106,47 @@
     }
 
     @Test
+    public void testProprietaryExtrasNullCallExtras() {
+        if (!ImsUtils.shouldTestImsService()) {
+            return;
+        }
+        ImsStreamMediaProfile testProfile = new ImsStreamMediaProfile(1, 1, 1, 1, 1);
+        // pass in null for bundle
+        ImsCallProfile data = new ImsCallProfile(ImsCallProfile.SERVICE_TYPE_NORMAL,
+                ImsCallProfile.CALL_TYPE_VOICE_N_VIDEO, null /*bundle*/, testProfile);
+
+        Parcel dataParceled = Parcel.obtain();
+        data.writeToParcel(dataParceled, 0);
+        dataParceled.setDataPosition(0);
+        ImsCallProfile unparceledData =
+                ImsCallProfile.CREATOR.createFromParcel(dataParceled);
+        dataParceled.recycle();
+
+        assertNotNull(unparceledData.getProprietaryCallExtras());
+    }
+
+    @Test
+    public void testProprietaryExtrasEmptyExtras() {
+        if (!ImsUtils.shouldTestImsService()) {
+            return;
+        }
+        // Empty bundle
+        Bundle testBundle = new Bundle();
+        ImsStreamMediaProfile testProfile = new ImsStreamMediaProfile(1, 1, 1, 1, 1);
+        ImsCallProfile data = new ImsCallProfile(ImsCallProfile.SERVICE_TYPE_NORMAL,
+                ImsCallProfile.CALL_TYPE_VOICE_N_VIDEO, testBundle, testProfile);
+
+        Parcel dataParceled = Parcel.obtain();
+        data.writeToParcel(dataParceled, 0);
+        dataParceled.setDataPosition(0);
+        ImsCallProfile unparceledData =
+                ImsCallProfile.CREATOR.createFromParcel(dataParceled);
+        dataParceled.recycle();
+
+        assertNotNull(unparceledData.getProprietaryCallExtras());
+    }
+
+    @Test
     public void testCallExtras() {
         if (!ImsUtils.shouldTestImsService()) {
             return;
diff --git a/tests/tests/telephony/current/src/android/telephony/ims/cts/ImsServiceTest.java b/tests/tests/telephony/current/src/android/telephony/ims/cts/ImsServiceTest.java
index fc478ef..5e28767 100644
--- a/tests/tests/telephony/current/src/android/telephony/ims/cts/ImsServiceTest.java
+++ b/tests/tests/telephony/current/src/android/telephony/ims/cts/ImsServiceTest.java
@@ -722,8 +722,8 @@
         };
 
         final UiAutomation automan = InstrumentationRegistry.getInstrumentation().getUiAutomation();
-        // Latch will count down here (we callback on the state during registration).
         try {
+            // First try without the correct permissions.
             ImsManager imsManager = getContext().getSystemService(ImsManager.class);
             ImsMmTelManager mmTelManager = imsManager.getImsMmTelManager(sTestSub);
             mmTelManager.registerImsRegistrationCallback(getContext().getMainExecutor(), callback);
@@ -732,6 +732,7 @@
             //expected
         }
 
+        // Latch will count down here (we callback on the state during registration).
         try {
             automan.adoptShellPermissionIdentity();
             ImsManager imsManager = getContext().getSystemService(ImsManager.class);
@@ -761,6 +762,16 @@
         assertEquals(AccessNetworkConstants.TRANSPORT_TYPE_WLAN, waitForIntResult(mQueue));
         assertEquals(ImsReasonInfo.CODE_LOCAL_HO_NOT_FEASIBLE, waitForIntResult(mQueue));
 
+        // Ensure null ImsReasonInfo still results in non-null callback value.
+        sServiceConnector.getCarrierService().getImsRegistration().onTechnologyChangeFailed(
+                ImsRegistrationImplBase.REGISTRATION_TECH_IWLAN, null);
+        assertEquals(AccessNetworkConstants.TRANSPORT_TYPE_WLAN, waitForIntResult(mQueue));
+        assertEquals(ImsReasonInfo.CODE_UNSPECIFIED, waitForIntResult(mQueue));
+
+        // Ensure null ImsReasonInfo still results in non-null callback.
+        sServiceConnector.getCarrierService().getImsRegistration().onDeregistered(null);
+        assertEquals(ImsReasonInfo.CODE_UNSPECIFIED, waitForIntResult(mQueue));
+
         try {
             automan.adoptShellPermissionIdentity();
             ImsManager imsManager = getContext().getSystemService(ImsManager.class);
@@ -778,7 +789,6 @@
         } catch (SecurityException e) {
             //expected
         }
-
     }
 
     @Ignore("RCS APIs not public yet")
@@ -1136,12 +1146,117 @@
         }
     }
 
+    /**
+     * We are specifically testing a race case here such that IsAvailable returns the correct
+     * capability status during the callback.
+     */
+    @Test
+    public void testCapabilityStatusWithIsAvailableDuringCallback() throws Exception {
+        if (!ImsUtils.shouldTestImsService()) {
+            return;
+        }
+
+        ImsManager imsManager = getContext().getSystemService(ImsManager.class);
+        ImsMmTelManager mmTelManager = imsManager.getImsMmTelManager(sTestSub);
+
+        triggerFrameworkConnectToCarrierImsService();
+
+        // Wait for the framework to set the capabilities on the ImsService
+        sServiceConnector.getCarrierService().waitForLatchCountdown(
+                TestImsService.LATCH_MMTEL_CAP_SET);
+
+
+        // Make sure we start off with every capability unavailable
+        sServiceConnector.getCarrierService().getImsRegistration().onRegistered(
+                ImsRegistrationImplBase.REGISTRATION_TECH_LTE);
+        MmTelFeature.MmTelCapabilities stdCapabilities = new MmTelFeature.MmTelCapabilities();
+        sServiceConnector.getCarrierService().getMmTelFeature()
+                .notifyCapabilitiesStatusChanged(stdCapabilities);
+
+
+        // Make sure the capabilities match the API getter for capabilities
+        final UiAutomation automan = InstrumentationRegistry.getInstrumentation().getUiAutomation();
+
+        //This lock is to keep the shell permissions from being dropped on a different thread
+        //causing a permission error.
+        Object lockObj = new Object();
+
+        synchronized (lockObj) {
+            try {
+                automan.adoptShellPermissionIdentity();
+                boolean isAvailableBeforeStatusChange = mmTelManager.isAvailable(
+                        MmTelFeature.MmTelCapabilities.CAPABILITY_TYPE_VOICE,
+                        ImsRegistrationImplBase.REGISTRATION_TECH_LTE);
+                assertFalse(isAvailableBeforeStatusChange);
+            } finally {
+                automan.dropShellPermissionIdentity();
+            }
+        }
+
+        LinkedBlockingQueue<Boolean> voiceIsAvailable = new LinkedBlockingQueue<>();
+        ImsMmTelManager.CapabilityCallback verifyCapabilityStatusCallaback =
+                new ImsMmTelManager.CapabilityCallback() {
+            @Override
+            public void onCapabilitiesStatusChanged(MmTelFeature.MmTelCapabilities capabilities) {
+                synchronized (lockObj) {
+                    try {
+                        automan.adoptShellPermissionIdentity();
+                        boolean isVoiceAvailable = mmTelManager
+                                .isAvailable(MmTelFeature.MmTelCapabilities.CAPABILITY_TYPE_VOICE,
+                                        ImsRegistrationImplBase.REGISTRATION_TECH_LTE);
+
+                        voiceIsAvailable.offer(isVoiceAvailable);
+                    } finally {
+                        automan.dropShellPermissionIdentity();
+                    }
+                }
+            }
+        };
+
+        synchronized (lockObj) {
+            // Latch will count down here (we callback on the state during registration).
+            try {
+                automan.adoptShellPermissionIdentity();
+                mmTelManager.registerMmTelCapabilityCallback(getContext().getMainExecutor(),
+                        verifyCapabilityStatusCallaback);
+            } finally {
+                automan.dropShellPermissionIdentity();
+            }
+        }
+
+        // Now enable voice availability
+        Boolean isAvailableDuringRegister = waitForResult(voiceIsAvailable);
+        assertNotNull(isAvailableDuringRegister);
+        assertFalse(isAvailableDuringRegister);
+        sServiceConnector.getCarrierService().getMmTelFeature()
+                .notifyCapabilitiesStatusChanged(new MmTelFeature.MmTelCapabilities(
+                        MmTelFeature.MmTelCapabilities.CAPABILITY_TYPE_VOICE));
+        Boolean isAvailableAfterStatusChange = waitForResult(voiceIsAvailable);
+        assertNotNull(isAvailableAfterStatusChange);
+        assertTrue(isAvailableAfterStatusChange);
+
+        synchronized (lockObj) {
+            try {
+                automan.adoptShellPermissionIdentity();
+                mmTelManager.unregisterMmTelCapabilityCallback(verifyCapabilityStatusCallaback);
+            } finally {
+                automan.dropShellPermissionIdentity();
+            }
+        }
+    }
+
     @Test
     public void testProvisioningManagerNotifyAutoConfig() throws Exception {
         if (!ImsUtils.shouldTestImsService()) {
             return;
         }
 
+        // Trigger carrier config changed
+        PersistableBundle bundle = new PersistableBundle();
+        bundle.putBoolean(CarrierConfigManager.KEY_USE_RCS_SIP_OPTIONS_BOOL, true);
+        bundle.putBoolean(CarrierConfigManager.KEY_USE_RCS_PRESENCE_BOOL, true);
+        overrideCarrierConfig(bundle);
+
         triggerFrameworkConnectToLocalImsServiceBindRcsFeature();
 
         ProvisioningManager provisioningManager =
@@ -1321,6 +1436,49 @@
             assertEquals(TEST_CONFIG_VALUE_STRING,
                     provisioningManager.getProvisioningStringValue(TEST_CONFIG_KEY));
 
+            automan.adoptShellPermissionIdentity();
+            provisioningManager.unregisterProvisioningChangedCallback(callback);
+        } finally {
+            automan.dropShellPermissionIdentity();
+        }
+    }
+
+    @Ignore("The ProvisioningManager constants were moved back to @hide for now, don't want to "
+            + "completely remove test.")
+    @Test
+    public void testProvisioningManagerConstants() throws Exception {
+        if (!ImsUtils.shouldTestImsService()) {
+            return;
+        }
+
+        triggerFrameworkConnectToCarrierImsService();
+
+        ProvisioningManager provisioningManager =
+                ProvisioningManager.createForSubscriptionId(sTestSub);
+
+        // This is a little bit gross looking, but on P devices, I can not define classes that
+        // extend ProvisioningManager.Callback (because it doesn't exist), so this has to
+        // happen as an anon class here.
+        LinkedBlockingQueue<Pair<Integer, Integer>> mIntQueue = new LinkedBlockingQueue<>();
+        LinkedBlockingQueue<Pair<Integer, String>> mStringQueue = new LinkedBlockingQueue<>();
+        ProvisioningManager.Callback callback = new ProvisioningManager.Callback() {
+            @Override
+            public void onProvisioningIntChanged(int item, int value) {
+                mIntQueue.offer(new Pair<>(item, value));
+            }
+
+            @Override
+            public void onProvisioningStringChanged(int item, String value) {
+                mStringQueue.offer(new Pair<>(item, value));
+            }
+        };
+
+        final UiAutomation automan = InstrumentationRegistry.getInstrumentation().getUiAutomation();
+        try {
+            automan.adoptShellPermissionIdentity();
+            provisioningManager.registerProvisioningChangedCallback(getContext().getMainExecutor(),
+                    callback);
+
             verifyStringKey(provisioningManager, mStringQueue,
                     ProvisioningManager.KEY_AMR_CODEC_MODE_SET_VALUES, "1,2");
             verifyStringKey(provisioningManager, mStringQueue,
@@ -1356,7 +1514,7 @@
             verifyIntKey(provisioningManager, mIntQueue,
                     ProvisioningManager.KEY_RCS_PUBLISH_TIMER_SEC, 5);
             verifyIntKey(provisioningManager, mIntQueue,
-                    ProvisioningManager.KEY_RCS_PUBLISH_TIMER_EXTENDED_SEC, 5);
+                    ProvisioningManager.KEY_RCS_PUBLISH_OFFLINE_AVAILABILITY_TIMER_SEC, 5);
             verifyIntKey(provisioningManager, mIntQueue,
                     ProvisioningManager.KEY_RCS_CAPABILITY_DISCOVERY_ENABLED, 0);
             verifyIntKey(provisioningManager, mIntQueue,
diff --git a/tests/tests/text/res/layout/webview_layout.xml b/tests/tests/text/res/layout/webview_layout.xml
index 7a0ed0d..d266d21 100644
--- a/tests/tests/text/res/layout/webview_layout.xml
+++ b/tests/tests/text/res/layout/webview_layout.xml
@@ -17,9 +17,9 @@
 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
     android:orientation="vertical"
     android:layout_width="match_parent"
-    android:layout_height="wrap_content">
+    android:layout_height="match_parent">
 
     <WebView android:id="@+id/web_page"
-        android:layout_width="wrap_content"
-        android:layout_height="wrap_content" />
+        android:layout_width="match_parent"
+        android:layout_height="match_parent" />
 </LinearLayout>
diff --git a/tests/tests/text/src/android/text/cts/EmojiCtsActivity.java b/tests/tests/text/src/android/text/cts/EmojiCtsActivity.java
index fcbc510..e93a224 100644
--- a/tests/tests/text/src/android/text/cts/EmojiCtsActivity.java
+++ b/tests/tests/text/src/android/text/cts/EmojiCtsActivity.java
@@ -18,6 +18,8 @@
 
 import android.app.Activity;
 import android.os.Bundle;
+import android.view.ViewGroup;
+import android.view.ViewParent;
 import android.webkit.WebView;
 
 import com.android.compatibility.common.util.NullWebViewUtils;
@@ -27,13 +29,13 @@
 
     @Override
     public void onCreate(Bundle savedInstanceState) {
-        try {
-            super.onCreate(savedInstanceState);
-            setContentView(R.layout.webview_layout);
-            mWebView = (WebView) findViewById(R.id.web_page);
-        } catch (Exception e) {
-            NullWebViewUtils.determineIfWebViewAvailable(this, e);
-        }
+        super.onCreate(savedInstanceState);
+
+        // Only inflate the layout if the device is supposed to have a WebView implementation.
+        if (!NullWebViewUtils.isWebViewAvailable()) return;
+
+        setContentView(R.layout.webview_layout);
+        mWebView = (WebView) findViewById(R.id.web_page);
     }
 
     public WebView getWebView() {
@@ -43,6 +45,10 @@
     @Override
     public void onDestroy() {
         if (mWebView != null) {
+            ViewParent parent =  mWebView.getParent();
+            if (parent instanceof ViewGroup) {
+                ((ViewGroup) parent).removeView(mWebView);
+            }
             mWebView.destroy();
         }
         super.onDestroy();
diff --git a/tests/tests/uirendering/src/android/uirendering/cts/testclasses/AutofillHighlightTests.java b/tests/tests/uirendering/src/android/uirendering/cts/testclasses/AutofillHighlightTests.java
index e02506f..a936dfa 100644
--- a/tests/tests/uirendering/src/android/uirendering/cts/testclasses/AutofillHighlightTests.java
+++ b/tests/tests/uirendering/src/android/uirendering/cts/testclasses/AutofillHighlightTests.java
@@ -56,7 +56,8 @@
                 ActivityTestBase.TEST_HEIGHT);
         autofilledDrawable.draw(canvas);
 
-        createTest().addLayout(R.layout.simple_white_layout, view -> view.setAutofilled(true))
+        createTest()
+                .addLayout(R.layout.simple_white_layout, view -> view.setAutofilled(true, false))
                 .runWithVerifier(new GoldenImageVerifier(goldenBitmap, new MSSIMComparer(0.99)));
     }
 }
diff --git a/tests/tests/util/Android.bp b/tests/tests/util/Android.bp
index 0ea529e..f84238d 100644
--- a/tests/tests/util/Android.bp
+++ b/tests/tests/util/Android.bp
@@ -27,6 +27,7 @@
         "androidx.test.rules",
         "ctstestrunner-axt",
         "cts-install-lib",
+        "core-test-rules", // for libcore.dalvik.system.CloseGuardSupport
     ],
     srcs: ["src/**/*.java"],
     platform_apis: true,
diff --git a/tests/tests/util/src/android/util/cts/CloseGuardTest.java b/tests/tests/util/src/android/util/cts/CloseGuardTest.java
new file mode 100644
index 0000000..5945280
--- /dev/null
+++ b/tests/tests/util/src/android/util/cts/CloseGuardTest.java
@@ -0,0 +1,106 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.util.cts;
+
+import android.util.CloseGuard;
+
+import androidx.test.filters.SmallTest;
+import androidx.test.runner.AndroidJUnit4;
+
+import libcore.dalvik.system.CloseGuardSupport;
+
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.rules.TestRule;
+import org.junit.runner.RunWith;
+
+/** CTS tests for {@link CloseGuard} */
+@SmallTest
+@RunWith(AndroidJUnit4.class)
+public class CloseGuardTest {
+
+    @Rule
+    public final TestRule rule = CloseGuardSupport.getRule();
+
+    @Test
+    public void testEnabled_NotOpen() throws Throwable {
+        ResourceOwner owner = new ResourceOwner();
+        assertUnreleasedResources(owner, 0);
+    }
+
+    @Test
+    public void testEnabled_OpenNotClosed() throws Throwable {
+        ResourceOwner owner = new ResourceOwner();
+        owner.open();
+        assertUnreleasedResources(owner, 1);
+    }
+
+    @Test
+    public void testEnabled_OpenThenClosed() throws Throwable {
+        ResourceOwner owner = new ResourceOwner();
+        owner.open();
+        owner.close();
+        assertUnreleasedResources(owner, 0);
+    }
+
+    @Test(expected = NullPointerException.class)
+    public void testOpen_withNullMethodName_throwsNPE() throws Throwable {
+        CloseGuard closeGuard = new CloseGuard();
+        closeGuard.open(null);
+    }
+
+    private void assertUnreleasedResources(ResourceOwner owner, int expectedCount)
+            throws Throwable {
+        try {
+            CloseGuardSupport.getFinalizerChecker().accept(owner, expectedCount);
+        } finally {
+            // Close the resource so that CloseGuard does not generate a warning for real when it
+            // is actually finalized.
+            owner.close();
+        }
+    }
+
+    /**
+     * A test user of {@link CloseGuard}.
+     */
+    private static class ResourceOwner {
+
+        private final CloseGuard mCloseGuard;
+
+        ResourceOwner() {
+            mCloseGuard = new CloseGuard();
+        }
+
+        public void open() {
+            mCloseGuard.open("close");
+        }
+
+        public void close() {
+            mCloseGuard.close();
+        }
+
+        /**
+         * Make finalize public so that it can be tested directly without relying on garbage
+         * collection to trigger it.
+         */
+        @Override
+        public void finalize() throws Throwable {
+            mCloseGuard.warnIfOpen();
+            super.finalize();
+        }
+    }
+}
diff --git a/tests/tests/util/src/android/util/cts/LruCacheTest.java b/tests/tests/util/src/android/util/cts/LruCacheTest.java
new file mode 100644
index 0000000..610443e
--- /dev/null
+++ b/tests/tests/util/src/android/util/cts/LruCacheTest.java
@@ -0,0 +1,526 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.util.cts;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.fail;
+
+import android.util.LruCache;
+
+import androidx.test.filters.SmallTest;
+import androidx.test.runner.AndroidJUnit4;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.List;
+import java.util.Map;
+
+/** CTS tests for {@link android.util.LruCache} */
+@SmallTest
+@RunWith(AndroidJUnit4.class)
+public final class LruCacheTest {
+    private int expectedCreateCount;
+    private int expectedPutCount;
+    private int expectedHitCount;
+    private int expectedMissCount;
+    private int expectedEvictionCount;
+
+    @Test
+    public void testStatistics() {
+        LruCache<String, String> cache = new LruCache<String, String>(3);
+        assertStatistics(cache);
+
+        assertEquals(null, cache.put("a", "A"));
+        expectedPutCount++;
+        assertStatistics(cache);
+        assertHit(cache, "a", "A");
+        assertSnapshot(cache, "a", "A");
+
+        assertEquals(null, cache.put("b", "B"));
+        expectedPutCount++;
+        assertStatistics(cache);
+        assertHit(cache, "a", "A");
+        assertHit(cache, "b", "B");
+        assertSnapshot(cache, "a", "A", "b", "B");
+
+        assertEquals(null, cache.put("c", "C"));
+        expectedPutCount++;
+        assertStatistics(cache);
+        assertHit(cache, "a", "A");
+        assertHit(cache, "b", "B");
+        assertHit(cache, "c", "C");
+        assertSnapshot(cache, "a", "A", "b", "B", "c", "C");
+
+        assertEquals(null, cache.put("d", "D"));
+        expectedPutCount++;
+        expectedEvictionCount++; // a should have been evicted
+        assertStatistics(cache);
+        assertMiss(cache, "a");
+        assertHit(cache, "b", "B");
+        assertHit(cache, "c", "C");
+        assertHit(cache, "d", "D");
+        assertHit(cache, "b", "B");
+        assertHit(cache, "c", "C");
+        assertSnapshot(cache, "d", "D", "b", "B", "c", "C");
+
+        assertEquals(null, cache.put("e", "E"));
+        expectedPutCount++;
+        expectedEvictionCount++; // d should have been evicted
+        assertStatistics(cache);
+        assertMiss(cache, "d");
+        assertMiss(cache, "a");
+        assertHit(cache, "e", "E");
+        assertHit(cache, "b", "B");
+        assertHit(cache, "c", "C");
+        assertSnapshot(cache, "e", "E", "b", "B", "c", "C");
+    }
+
+    @Test
+    public void testStatisticsWithCreate() {
+        LruCache<String, String> cache = newCreatingCache();
+        assertStatistics(cache);
+
+        assertCreated(cache, "aa", "created-aa");
+        assertHit(cache, "aa", "created-aa");
+        assertSnapshot(cache, "aa", "created-aa");
+
+        assertCreated(cache, "bb", "created-bb");
+        assertMiss(cache, "c");
+        assertSnapshot(cache, "aa", "created-aa", "bb", "created-bb");
+
+        assertCreated(cache, "cc", "created-cc");
+        assertSnapshot(cache, "aa", "created-aa", "bb", "created-bb", "cc", "created-cc");
+
+        expectedEvictionCount++; // aa will be evicted
+        assertCreated(cache, "dd", "created-dd");
+        assertSnapshot(cache, "bb", "created-bb",  "cc", "created-cc", "dd", "created-dd");
+
+        expectedEvictionCount++; // bb will be evicted
+        assertCreated(cache, "aa", "created-aa");
+        assertSnapshot(cache, "cc", "created-cc", "dd", "created-dd", "aa", "created-aa");
+    }
+
+    @Test
+    public void testCreateOnCacheMiss() {
+        LruCache<String, String> cache = newCreatingCache();
+        String created = cache.get("aa");
+        assertEquals("created-aa", created);
+    }
+
+    @Test
+    public void testNoCreateOnCacheHit() {
+        LruCache<String, String> cache = newCreatingCache();
+        cache.put("aa", "put-aa");
+        assertEquals("put-aa", cache.get("aa"));
+    }
+
+    @Test
+    public void testConstructorDoesNotAllowZeroCacheSize() {
+        try {
+            new LruCache<String, String>(0);
+            fail();
+        } catch (IllegalArgumentException expected) {
+        }
+    }
+
+    @Test
+    public void testCannotPutNullKey() {
+        LruCache<String, String> cache = new LruCache<String, String>(3);
+        try {
+            cache.put(null, "A");
+            fail();
+        } catch (NullPointerException expected) {
+        }
+    }
+
+    @Test
+    public void testCannotPutNullValue() {
+        LruCache<String, String> cache = new LruCache<String, String>(3);
+        try {
+            cache.put("a", null);
+            fail();
+        } catch (NullPointerException expected) {
+        }
+    }
+
+    @Test
+    public void testEvictionWithSingletonCache() {
+        LruCache<String, String> cache = new LruCache<String, String>(1);
+        cache.put("a", "A");
+        cache.put("b", "B");
+        assertSnapshot(cache, "b", "B");
+    }
+
+    @Test
+    public void testEntryEvictedWhenFull() {
+        List<String> log = new ArrayList<String>();
+        LruCache<String, String> cache = newRemovalLogCache(log);
+
+        cache.put("a", "A");
+        cache.put("b", "B");
+        cache.put("c", "C");
+        assertEquals(Collections.<String>emptyList(), log);
+
+        cache.put("d", "D");
+        assertEquals(Arrays.asList("a=A"), log);
+    }
+
+    /**
+     * Replacing the value for a key doesn't cause an eviction but it does bring
+     * the replaced entry to the front of the queue.
+     */
+    @Test
+    public void testPutCauseEviction() {
+        List<String> log = new ArrayList<String>();
+        LruCache<String, String> cache = newRemovalLogCache(log);
+
+        cache.put("a", "A");
+        cache.put("b", "B");
+        cache.put("c", "C");
+        cache.put("b", "B2");
+        assertEquals(Arrays.asList("b=B>B2"), log);
+        assertSnapshot(cache, "a", "A", "c", "C", "b", "B2");
+    }
+
+    @Test
+    public void testCustomSizesImpactsSize() {
+        LruCache<String, String> cache = new LruCache<String, String>(10) {
+            @Override protected int sizeOf(String key, String value) {
+                return key.length() + value.length();
+            }
+        };
+
+        assertEquals(0, cache.size());
+        cache.put("a", "AA");
+        assertEquals(3, cache.size());
+        cache.put("b", "BBBB");
+        assertEquals(8, cache.size());
+        cache.put("a", "");
+        assertEquals(6, cache.size());
+    }
+
+    @Test
+    public void testEvictionWithCustomSizes() {
+        LruCache<String, String> cache = new LruCache<String, String>(4) {
+            @Override protected int sizeOf(String key, String value) {
+                return value.length();
+            }
+        };
+
+        cache.put("a", "AAAA");
+        assertSnapshot(cache, "a", "AAAA");
+        cache.put("b", "BBBB"); // should evict a
+        assertSnapshot(cache, "b", "BBBB");
+        cache.put("c", "CC"); // should evict b
+        assertSnapshot(cache, "c", "CC");
+        cache.put("d", "DD");
+        assertSnapshot(cache, "c", "CC", "d", "DD");
+        cache.put("e", "E"); // should evict c
+        assertSnapshot(cache, "d", "DD", "e", "E");
+        cache.put("f", "F");
+        assertSnapshot(cache, "d", "DD", "e", "E", "f", "F");
+        cache.put("g", "G"); // should evict d
+        assertSnapshot(cache, "e", "E", "f", "F", "g", "G");
+        cache.put("h", "H");
+        assertSnapshot(cache, "e", "E", "f", "F", "g", "G", "h", "H");
+        cache.put("i", "III"); // should evict e, f, and g
+        assertSnapshot(cache, "h", "H", "i", "III");
+        cache.put("j", "JJJ"); // should evict h and i
+        assertSnapshot(cache, "j", "JJJ");
+    }
+
+    @Test
+    public void testEvictionThrowsWhenSizesAreInconsistent() {
+        LruCache<String, int[]> cache = new LruCache<String, int[]>(4) {
+            @Override protected int sizeOf(String key, int[] value) {
+                return value[0];
+            }
+        };
+
+        int[] a = { 4 };
+        cache.put("a", a);
+
+        // get the cache size out of sync
+        a[0] = 1;
+        assertEquals(4, cache.size());
+
+        // evict something
+        try {
+            cache.put("b", new int[] { 2 });
+            fail();
+        } catch (IllegalStateException expected) {
+        }
+    }
+
+    @Test
+    public void testEvictionThrowsWhenSizesAreNegative() {
+        LruCache<String, String> cache = new LruCache<String, String>(4) {
+            @Override protected int sizeOf(String key, String value) {
+                return -1;
+            }
+        };
+
+        try {
+            cache.put("a", "A");
+            fail();
+        } catch (IllegalStateException expected) {
+        }
+    }
+
+    /**
+     * Naive caches evict at most one element at a time. This is problematic
+     * because evicting a small element may be insufficient to make room for a
+     * large element.
+     */
+    @Test
+    public void testDifferentElementSizes() {
+        LruCache<String, String> cache = new LruCache<String, String>(10) {
+            @Override protected int sizeOf(String key, String value) {
+                return value.length();
+            }
+        };
+
+        cache.put("a", "1");
+        cache.put("b", "12345678");
+        cache.put("c", "1");
+        assertSnapshot(cache, "a", "1", "b", "12345678", "c", "1");
+        cache.put("d", "12345678"); // should evict a and b
+        assertSnapshot(cache, "c", "1", "d", "12345678");
+        cache.put("e", "12345678"); // should evict c and d
+        assertSnapshot(cache, "e", "12345678");
+    }
+
+    @Test
+    public void testEvictAll() {
+        List<String> log = new ArrayList<String>();
+        LruCache<String, String> cache = newRemovalLogCache(log);
+        cache.put("a", "A");
+        cache.put("b", "B");
+        cache.put("c", "C");
+        cache.evictAll();
+        assertEquals(0, cache.size());
+        assertEquals(Arrays.asList("a=A", "b=B", "c=C"), log);
+    }
+
+    @Test
+    public void testEvictAllEvictsSizeZeroElements() {
+        LruCache<String, String> cache = new LruCache<String, String>(10) {
+            @Override protected int sizeOf(String key, String value) {
+                return 0;
+            }
+        };
+
+        cache.put("a", "A");
+        cache.put("b", "B");
+        cache.evictAll();
+        assertSnapshot(cache);
+    }
+
+    @Test
+    public void testRemoveWithCustomSizes() {
+        LruCache<String, String> cache = new LruCache<String, String>(10) {
+            @Override protected int sizeOf(String key, String value) {
+                return value.length();
+            }
+        };
+        cache.put("a", "123456");
+        cache.put("b", "1234");
+        cache.remove("a");
+        assertEquals(4, cache.size());
+    }
+
+    @Test
+    public void testRemoveAbsentElement() {
+        LruCache<String, String> cache = new LruCache<String, String>(10);
+        cache.put("a", "A");
+        cache.put("b", "B");
+        assertEquals(null, cache.remove("c"));
+        assertEquals(2, cache.size());
+    }
+
+    @Test
+    public void testRemoveNullThrows() {
+        LruCache<String, String> cache = new LruCache<String, String>(10);
+        try {
+            cache.remove(null);
+            fail();
+        } catch (NullPointerException expected) {
+        }
+    }
+
+    @Test
+    public void testRemoveCallsEntryRemoved() {
+        List<String> log = new ArrayList<String>();
+        LruCache<String, String> cache = newRemovalLogCache(log);
+        cache.put("a", "A");
+        cache.remove("a");
+        assertEquals(Arrays.asList("a=A>null"), log);
+    }
+
+    @Test
+    public void testPutCallsEntryRemoved() {
+        List<String> log = new ArrayList<String>();
+        LruCache<String, String> cache = newRemovalLogCache(log);
+        cache.put("a", "A");
+        cache.put("a", "A2");
+        assertEquals(Arrays.asList("a=A>A2"), log);
+    }
+
+    @Test
+    public void testEntryRemovedIsCalledWithoutSynchronization() {
+        LruCache<String, String> cache = new LruCache<String, String>(3) {
+            @Override protected void entryRemoved(
+                    boolean evicted, String key, String oldValue, String newValue) {
+                assertFalse(Thread.holdsLock(this));
+            }
+        };
+
+        cache.put("a", "A");
+        cache.put("a", "A2"); // replaced
+        cache.put("b", "B");
+        cache.put("c", "C");
+        cache.put("d", "D");  // single eviction
+        cache.remove("a");    // removed
+        cache.evictAll();     // multiple eviction
+    }
+
+    @Test
+    public void testCreateIsCalledWithoutSynchronization() {
+        LruCache<String, String> cache = new LruCache<String, String>(3) {
+            @Override protected String create(String key) {
+                assertFalse(Thread.holdsLock(this));
+                return null;
+            }
+        };
+
+        cache.get("a");
+    }
+
+    /**
+     * Test what happens when a value is added to the map while create is
+     * working. The map value should be returned by get(), and the created value
+     * should be released with entryRemoved().
+     */
+    @Test
+    public void testCreateWithConcurrentPut() {
+        final List<String> log = new ArrayList<String>();
+        LruCache<String, String> cache = new LruCache<String, String>(3) {
+            @Override protected String create(String key) {
+                put(key, "B");
+                return "A";
+            }
+            @Override protected void entryRemoved(
+                    boolean evicted, String key, String oldValue, String newValue) {
+                log.add(key + "=" + oldValue + ">" + newValue);
+            }
+        };
+
+        assertEquals("B", cache.get("a"));
+        assertEquals(Arrays.asList("a=A>B"), log);
+    }
+
+    /**
+     * Test what happens when two creates happen concurrently. The result from
+     * the first create to return is returned by both gets. The other created
+     * values should be released with entryRemove().
+     */
+    @Test
+    public void testCreateWithConcurrentCreate() {
+        final List<String> log = new ArrayList<String>();
+        LruCache<String, Integer> cache = new LruCache<String, Integer>(3) {
+            int callCount = 0;
+            @Override protected Integer create(String key) {
+                if (callCount++ == 0) {
+                    assertEquals(2, get(key).intValue());
+                    return 1;
+                } else {
+                    return 2;
+                }
+            }
+            @Override protected void entryRemoved(
+                    boolean evicted, String key, Integer oldValue, Integer newValue) {
+                log.add(key + "=" + oldValue + ">" + newValue);
+            }
+        };
+
+        assertEquals(2, cache.get("a").intValue());
+        assertEquals(Arrays.asList("a=1>2"), log);
+    }
+
+    private LruCache<String, String> newCreatingCache() {
+        return new LruCache<String, String>(3) {
+            @Override protected String create(String key) {
+                return (key.length() > 1) ? ("created-" + key) : null;
+            }
+        };
+    }
+
+    private LruCache<String, String> newRemovalLogCache(final List<String> log) {
+        return new LruCache<String, String>(3) {
+            @Override protected void entryRemoved(
+                    boolean evicted, String key, String oldValue, String newValue) {
+                String message = evicted
+                        ? (key + "=" + oldValue)
+                        : (key + "=" + oldValue + ">" + newValue);
+                log.add(message);
+            }
+        };
+    }
+
+    private void assertHit(LruCache<String, String> cache, String key, String value) {
+        assertEquals(value, cache.get(key));
+        expectedHitCount++;
+        assertStatistics(cache);
+    }
+
+    private void assertMiss(LruCache<String, String> cache, String key) {
+        assertEquals(null, cache.get(key));
+        expectedMissCount++;
+        assertStatistics(cache);
+    }
+
+    private void assertCreated(LruCache<String, String> cache, String key, String value) {
+        assertEquals(value, cache.get(key));
+        expectedMissCount++;
+        expectedCreateCount++;
+        assertStatistics(cache);
+    }
+
+    private void assertStatistics(LruCache<?, ?> cache) {
+        assertEquals("create count", expectedCreateCount, cache.createCount());
+        assertEquals("put count", expectedPutCount, cache.putCount());
+        assertEquals("hit count", expectedHitCount, cache.hitCount());
+        assertEquals("miss count", expectedMissCount, cache.missCount());
+        assertEquals("eviction count", expectedEvictionCount, cache.evictionCount());
+    }
+
+    private <T> void assertSnapshot(LruCache<T, T> cache, T... keysAndValues) {
+        List<T> actualKeysAndValues = new ArrayList<T>();
+        for (Map.Entry<T, T> entry : cache.snapshot().entrySet()) {
+            actualKeysAndValues.add(entry.getKey());
+            actualKeysAndValues.add(entry.getValue());
+        }
+
+        // assert using lists because order is important for LRUs
+        assertEquals(Arrays.asList(keysAndValues), actualKeysAndValues);
+    }
+}
diff --git a/tests/tests/view/src/android/view/cts/PixelCopyTest.java b/tests/tests/view/src/android/view/cts/PixelCopyTest.java
index 51288cf..85c4094 100644
--- a/tests/tests/view/src/android/view/cts/PixelCopyTest.java
+++ b/tests/tests/view/src/android/view/cts/PixelCopyTest.java
@@ -796,12 +796,12 @@
         assertBitmapNotColor("Left edge", bitmap, edgeColor, 2, bitmap.getHeight() / 2);
 
         assertBitmapColor("Bottom edge", bitmap, edgeColor,
-                bitmap.getWidth() / 2, bitmap.getHeight() - 1);
+                bitmap.getWidth() / 2, bitmap.getHeight() - 2);
         assertBitmapNotColor("Bottom edge", bitmap, edgeColor,
                 bitmap.getWidth() / 2, bitmap.getHeight() - 3);
 
         assertBitmapColor("Right edge", bitmap, edgeColor,
-                bitmap.getWidth() - 1, bitmap.getHeight() / 2);
+                bitmap.getWidth() - 2, bitmap.getHeight() / 2);
         assertBitmapNotColor("Right edge", bitmap, edgeColor,
                 bitmap.getWidth() - 3, bitmap.getHeight() / 2);
     }
diff --git a/tests/tests/view/src/android/view/cts/VerifyInputEventTest.java b/tests/tests/view/src/android/view/cts/VerifyInputEventTest.java
index fdda4e3..9262dfc 100644
--- a/tests/tests/view/src/android/view/cts/VerifyInputEventTest.java
+++ b/tests/tests/view/src/android/view/cts/VerifyInputEventTest.java
@@ -163,8 +163,8 @@
         compareMotions(downEvent, verified);
 
         // Send UP event for consistency
-        MotionEvent upEvent = MotionEvent.obtain(downTime, downTime, MotionEvent.ACTION_UP,
-                point.x, point.y, 0 /*metaState*/);
+        MotionEvent upEvent = MotionEvent.obtain(downTime, SystemClock.uptimeMillis(),
+                MotionEvent.ACTION_UP, point.x, point.y, 0 /*metaState*/);
         mAutomation.injectInputEvent(upEvent, true);
         waitForMotion();
     }
@@ -212,8 +212,67 @@
         assertNull(verified);
 
         // Send UP event for consistency
-        MotionEvent upEvent = MotionEvent.obtain(downTime, downTime, MotionEvent.ACTION_UP,
-                point.x, point.y, 0 /*metaState*/);
+        MotionEvent upEvent = MotionEvent.obtain(downTime, SystemClock.uptimeMillis(),
+                MotionEvent.ACTION_UP, point.x, point.y, 0 /*metaState*/);
+        mAutomation.injectInputEvent(upEvent, true);
+        waitForMotion();
+    }
+
+    /**
+     * Ensure that injected key events that contain a real device id get injected as virtual
+     * device events, to prevent misrepresentation of actual hardware.
+     * The verified events should contain the virtual device id, which is consistent with what the
+     * app receives.
+     */
+    @Test
+    public void testDeviceIdBecomesVirtualForInjectedKeys() {
+        final long downTime = SystemClock.uptimeMillis();
+        KeyEvent downEvent = new KeyEvent(downTime, downTime, KeyEvent.ACTION_DOWN,
+                KeyEvent.KEYCODE_A, 0 /*repeat*/, 0 /*metaState*/,
+                1/*deviceId*/, 0 /*scanCode*/);
+        mAutomation.injectInputEvent(downEvent, true);
+        KeyEvent received = waitForKey();
+        assertEquals(INJECTED_EVENT_DEVICE_ID, received.getDeviceId());
+
+        // This event can still be verified, however.
+        VerifiedInputEvent verified = mInputManager.verifyInputEvent(received);
+        assertEquals(INJECTED_EVENT_DEVICE_ID, verified.getDeviceId());
+
+        // Send UP event for consistency
+        KeyEvent upEvent = new KeyEvent(downTime, SystemClock.uptimeMillis(), KeyEvent.ACTION_UP,
+                KeyEvent.KEYCODE_A, 0 /*repeat*/, 0 /*metaState*/,
+                1/*deviceId*/, 0 /*scanCode*/);
+        mAutomation.injectInputEvent(upEvent, true);
+        waitForKey();
+    }
+
+    /**
+     * Ensure that injected motion events that contain a real device id get injected as virtual
+     * device events, to prevent misrepresentation of actual hardware.
+     * The verified events should contain the virtual device id, which is consistent with what the
+     * app receives.
+     */
+    @Test
+    public void testDeviceIdBecomesVirtualForInjectedMotions() {
+        final View view = mActivity.getWindow().getDecorView();
+        final Point point = getViewCenterOnScreen(view);
+        final long downTime = SystemClock.uptimeMillis();
+        MotionEvent downEvent = MotionEvent.obtain(downTime, downTime, MotionEvent.ACTION_DOWN,
+                point.x, point.y, 1 /*pressure*/, 1 /*size*/, 0 /*metaState*/,
+                0 /*xPrecision*/, 0 /*yPrecision*/, 1 /*deviceId*/, 0 /*edgeFlags*/);
+        mAutomation.injectInputEvent(downEvent, true);
+        MotionEvent received = waitForMotion();
+        assertEquals(INJECTED_EVENT_DEVICE_ID, received.getDeviceId());
+
+        // This event can still be verified, however.
+        VerifiedInputEvent verified = mInputManager.verifyInputEvent(received);
+        assertEquals(INJECTED_EVENT_DEVICE_ID, verified.getDeviceId());
+
+        // Send UP event for consistency
+        MotionEvent upEvent = MotionEvent.obtain(downTime, SystemClock.uptimeMillis(),
+                MotionEvent.ACTION_UP, point.x, point.y, 0 /*pressure*/, 1 /*size*/,
+                0 /*metaState*/, 0 /*xPrecision*/, 0 /*yPrecision*/,
+                1 /*deviceId*/, 0 /*edgeFlags*/);
         mAutomation.injectInputEvent(upEvent, true);
         waitForMotion();
     }
diff --git a/tests/tests/view/src/android/view/cts/ViewTest.java b/tests/tests/view/src/android/view/cts/ViewTest.java
index 267bd3e..d0ce0f0 100644
--- a/tests/tests/view/src/android/view/cts/ViewTest.java
+++ b/tests/tests/view/src/android/view/cts/ViewTest.java
@@ -3923,29 +3923,26 @@
         assertFalse(mockView.isInTouchMode());
         assertFalse(fitWindowsView.isInTouchMode());
 
-        // Mouse events should not affect touch mode.
+        // Mouse events should trigger touch mode.
         final MotionEvent event =
                 CtsMouseUtil.obtainMouseEvent(MotionEvent.ACTION_SCROLL, mockView, 0, 0);
         mInstrumentation.sendPointerSync(event);
-        assertFalse(fitWindowsView.isInTouchMode());
-
-        event.setAction(MotionEvent.ACTION_DOWN);
-        mInstrumentation.sendPointerSync(event);
-        assertFalse(fitWindowsView.isInTouchMode());
-
-        // Stylus events should not affect touch mode.
-        event.setSource(InputDevice.SOURCE_STYLUS);
-        mInstrumentation.sendPointerSync(event);
-        assertFalse(fitWindowsView.isInTouchMode());
-
-        CtsTouchUtils.emulateTapOnViewCenter(mInstrumentation, mActivityRule, mockView);
         assertTrue(fitWindowsView.isInTouchMode());
 
-        // Mouse events should not affect touch mode.
-        event.setSource(InputDevice.SOURCE_MOUSE);
+        mInstrumentation.sendKeySync(keyEvent);
+        assertFalse(fitWindowsView.isInTouchMode());
+
         event.setAction(MotionEvent.ACTION_DOWN);
         mInstrumentation.sendPointerSync(event);
         assertTrue(fitWindowsView.isInTouchMode());
+
+        mInstrumentation.sendKeySync(keyEvent);
+        assertFalse(fitWindowsView.isInTouchMode());
+
+        // Stylus events should trigger touch mode.
+        event.setSource(InputDevice.SOURCE_STYLUS);
+        mInstrumentation.sendPointerSync(event);
+        assertTrue(fitWindowsView.isInTouchMode());
     }
 
     @UiThreadTest
diff --git a/tests/tests/webkit/src/android/webkit/cts/CookieSyncManagerCtsActivity.java b/tests/tests/webkit/src/android/webkit/cts/CookieSyncManagerCtsActivity.java
index 7661013..bc052ec 100644
--- a/tests/tests/webkit/src/android/webkit/cts/CookieSyncManagerCtsActivity.java
+++ b/tests/tests/webkit/src/android/webkit/cts/CookieSyncManagerCtsActivity.java
@@ -32,23 +32,19 @@
     public void onCreate(Bundle savedInstanceState) {
         super.onCreate(savedInstanceState);
 
-        try {
-            CookieSyncManager.createInstance(this);
+        // Only do the rest of setup if the device is supposed to have a WebView implementation.
+        if (!NullWebViewUtils.isWebViewAvailable()) return;
 
-            mWebView = new WebView(this);
-            setContentView(mWebView);
-        } catch (Exception e) {
-            NullWebViewUtils.determineIfWebViewAvailable(this, e);
-        }
+        CookieSyncManager.createInstance(this);
+        mWebView = new WebView(this);
+        setContentView(mWebView);
     }
 
     @Override
     protected void onResume() {
         super.onResume();
-        try {
+        if (NullWebViewUtils.isWebViewAvailable()) {
             CookieSyncManager.getInstance().startSync();
-        } catch (Exception e) {
-            // May throw on a device with no webview, OK to ignore at this point.
         }
     }
 
@@ -67,14 +63,12 @@
     @Override
     protected void onStop() {
         super.onStop();
-        try {
+        if (NullWebViewUtils.isWebViewAvailable()) {
             CookieSyncManager.getInstance().stopSync();
-        } catch (Exception e) {
-            // May throw on a device with no webview, OK to ignore at this point.
         }
     }
 
-    public WebView getWebView(){
+    public WebView getWebView() {
         return mWebView;
     }
 }
diff --git a/tests/tests/webkit/src/android/webkit/cts/WebViewCtsActivity.java b/tests/tests/webkit/src/android/webkit/cts/WebViewCtsActivity.java
index 2724580..953d2cb 100644
--- a/tests/tests/webkit/src/android/webkit/cts/WebViewCtsActivity.java
+++ b/tests/tests/webkit/src/android/webkit/cts/WebViewCtsActivity.java
@@ -16,11 +16,7 @@
 
 package android.webkit.cts;
 
-import android.webkit.cts.R;
-
 import android.app.Activity;
-import android.app.ActivityManager;
-import android.os.Build;
 import android.os.Bundle;
 import android.view.ViewGroup;
 import android.view.ViewParent;
@@ -30,28 +26,19 @@
 
 public class WebViewCtsActivity extends Activity {
     private WebView mWebView;
-    private Exception mInflationException;
 
     @Override
     public void onCreate(Bundle savedInstanceState) {
-        try {
-            super.onCreate(savedInstanceState);
-            setContentView(R.layout.webview_layout);
-            mWebView = (WebView) findViewById(R.id.web_page);
-            mInflationException = null;
-        } catch (Exception e) {
-            NullWebViewUtils.determineIfWebViewAvailable(this, e);
-            // If WebView is available, then the exception we just caught should be propagated.
-            if (NullWebViewUtils.isWebViewAvailable()) {
-                mInflationException = e;
-           }
-        }
+        super.onCreate(savedInstanceState);
+
+        // Only inflate the layout if the device is supposed to have a WebView implementation.
+        if (!NullWebViewUtils.isWebViewAvailable()) return;
+
+        setContentView(R.layout.webview_layout);
+        mWebView = (WebView) findViewById(R.id.web_page);
     }
 
     public WebView getWebView() {
-        if (mInflationException != null) {
-            throw new RuntimeException("Exception caught in onCreate", mInflationException);
-        }
         return mWebView;
     }
 
diff --git a/tests/tests/widget/src/android/widget/cts/TextClockTest.java b/tests/tests/widget/src/android/widget/cts/TextClockTest.java
index 9438ed1..6c35b33 100644
--- a/tests/tests/widget/src/android/widget/cts/TextClockTest.java
+++ b/tests/tests/widget/src/android/widget/cts/TextClockTest.java
@@ -197,11 +197,6 @@
                             countDownAndRemove();
                         }
 
-                        @Override
-                        public void onChange(boolean selfChange, Uri uri, int userId) {
-                            countDownAndRemove();
-                        }
-
                         private void countDownAndRemove() {
                             latch.countDown();
                             resolver.unregisterContentObserver(this);
diff --git a/tools/cts-device-info/Android.mk b/tools/cts-device-info/Android.mk
index fc55328..acaaef6 100644
--- a/tools/cts-device-info/Android.mk
+++ b/tools/cts-device-info/Android.mk
@@ -27,6 +27,8 @@
 DEVICE_INFO_MIN_SDK := 23
 DEVICE_INFO_TARGET_SDK := 23
 
+LOCAL_MIN_SDK_VERSION := 23
+
 DEVICE_INFO_PERMISSIONS :=
 
 DEVICE_INFO_ACTIVITIES := \
diff --git a/tools/cts-media-preparer-app/Android.bp b/tools/cts-media-preparer-app/Android.bp
index 400dac7..5991f8b 100644
--- a/tools/cts-media-preparer-app/Android.bp
+++ b/tools/cts-media-preparer-app/Android.bp
@@ -34,4 +34,5 @@
         "mts",
     ],
     sdk_version: "test_current",
+    min_sdk_version: "29",
 }
diff --git a/tools/cts-media-preparer-app/AndroidManifest.xml b/tools/cts-media-preparer-app/AndroidManifest.xml
index 15afba4..789ea99 100644
--- a/tools/cts-media-preparer-app/AndroidManifest.xml
+++ b/tools/cts-media-preparer-app/AndroidManifest.xml
@@ -22,7 +22,7 @@
     <application>
         <uses-library android:name="android.test.runner" />
     </application>
-
+    <uses-sdk android:minSdkVersion="29"   android:targetSdkVersion="29" />
     <instrumentation android:name="androidx.test.runner.AndroidJUnitRunner"
             android:targetPackage="android.mediastress.cts.preconditions.app"
             android:label="Device-side CTS mediastress preparation" />