Merge "Catch exception from MediaExtractor.selectTrack" into lmp-dev am: c67ccf397a am: d98ab4cd39  -s ours am: 5de77f2443 am: dd307689d5 am: bd4218ffc6 am: 72545740c5 am: 39c3882c86
am: 929f30de26

Change-Id: I4459e4f125b27a85c88f7259e32359da7866bbb5
diff --git a/.gitignore b/.gitignore
index 07a80d6..dbd5bcf 100644
--- a/.gitignore
+++ b/.gitignore
@@ -7,3 +7,5 @@
 /bin
 .idea/*
 .idea/
+gen/
+*.iml
diff --git a/apps/CameraITS/build/envsetup.sh b/apps/CameraITS/build/envsetup.sh
index de50ad8..03b45d1 100644
--- a/apps/CameraITS/build/envsetup.sh
+++ b/apps/CameraITS/build/envsetup.sh
@@ -31,12 +31,23 @@
 python -V 2>&1 | grep -q "Python 2.7" || \
     echo ">> Require python 2.7" >&2
 
-for M in numpy PIL Image matplotlib pylab cv2 scipy.stats scipy.spatial
+for M in numpy PIL Image matplotlib pylab scipy.stats scipy.spatial
 do
     python -c "import $M" >/dev/null 2>&1 || \
         echo ">> Require Python $M module" >&2
 done
 
+CV2_VER=$(python -c "\
+try:
+    import cv2
+    print cv2.__version__
+except:
+    print \"N/A\"
+")
+
+echo $CV2_VER | grep -q "^2.4" || \
+    echo ">> Require python opencv 2.4. Got $CV2_VER" >&2
+
 export PYTHONPATH="$PWD/pymodules:$PYTHONPATH"
 
 for M in device objects image caps dng target error
diff --git a/apps/CameraITS/pymodules/its/caps.py b/apps/CameraITS/pymodules/its/caps.py
index d9270f7..e6f096f 100644
--- a/apps/CameraITS/pymodules/its/caps.py
+++ b/apps/CameraITS/pymodules/its/caps.py
@@ -447,6 +447,18 @@
         props["android.lens.info.minimumFocusDistance"] == 0
 
 
+def debug_mode():
+    """Returns True/False for whether test is run in debug mode.
+
+    Returns:
+        Boolean.
+    """
+    for s in sys.argv[1:]:
+        if s[:6] == "debug=" and s[6:] == "True":
+            return True
+    return False
+
+
 class __UnitTest(unittest.TestCase):
     """Run a suite of unit tests on this module.
     """
diff --git a/apps/CameraITS/pymodules/its/objects.py b/apps/CameraITS/pymodules/its/objects.py
index 9766ab9..0883482 100644
--- a/apps/CameraITS/pymodules/its/objects.py
+++ b/apps/CameraITS/pymodules/its/objects.py
@@ -264,6 +264,39 @@
 
     return req, out_spec
 
+
+def get_smallest_yuv_format(props, match_ar=None):
+    """Return a capture request and format spec for the smallest yuv size.
+
+    Args:
+        props: the object returned from its.device.get_camera_properties().
+
+    Returns:
+        fmt:    an output format specification, for the smallest possible yuv
+        format for this device.
+    """
+    size = get_available_output_sizes("yuv", props, match_ar_size=match_ar)[-1]
+    fmt = {"format":"yuv", "width":size[0], "height":size[1]}
+
+    return fmt
+
+
+def get_largest_yuv_format(props):
+    """Return a capture request and format spec for the smallest yuv size.
+
+    Args:
+        props: the object returned from its.device.get_camera_properties().
+
+    Returns:
+        fmt:    an output format specification, for the smallest possible yuv
+        format for this device.
+    """
+    size = get_available_output_sizes("yuv", props)[0]
+    fmt = {"format":"yuv", "width":size[0], "height":size[1]}
+
+    return fmt
+
+
 def get_max_digital_zoom(props):
     """Returns the maximum amount of zooming possible by the camera device.
 
diff --git a/apps/CameraITS/tests/scene0/test_metadata.py b/apps/CameraITS/tests/scene0/test_metadata.py
index ed1426b..e5fbba5 100644
--- a/apps/CameraITS/tests/scene0/test_metadata.py
+++ b/apps/CameraITS/tests/scene0/test_metadata.py
@@ -97,9 +97,12 @@
         print "Assert field of view: %.1f degrees" % fov
         assert 30 <= fov <= 130
 
-        hyperfocal = 1.0 / props["android.lens.info.hyperfocalDistance"]
-        print "Assert hyperfocal distance: %.2f m" % hyperfocal
-        assert 0.02 <= hyperfocal
+        if its.caps.lens_approx_calibrated(props):
+            diopter_hyperfocal = props["android.lens.info.hyperfocalDistance"]
+            if diopter_hyperfocal != 0.0:
+                hyperfocal = 1.0 / diopter_hyperfocal
+                print "Assert hyperfocal distance: %.2f m" % hyperfocal
+                assert 0.02 <= hyperfocal
 
 
 def getval(expr, default=None):
diff --git a/apps/CameraITS/tests/scene1/test_auto_vs_manual.py b/apps/CameraITS/tests/scene1/test_auto_vs_manual.py
index c5f5e29..849c720 100644
--- a/apps/CameraITS/tests/scene1/test_auto_vs_manual.py
+++ b/apps/CameraITS/tests/scene1/test_auto_vs_manual.py
@@ -37,6 +37,13 @@
                              its.caps.per_frame_control(props))
 
         # Converge 3A and get the estimates.
+        debug = its.caps.debug_mode()
+        largest_yuv = its.objects.get_largest_yuv_format(props)
+        if debug:
+            fmt = largest_yuv
+        else:
+            match_ar = (largest_yuv['width'], largest_yuv['height'])
+            fmt = its.objects.get_smallest_yuv_format(props, match_ar=match_ar)
         sens, exp, gains, xform, focus = cam.do_3a(get_results=True)
         xform_rat = its.objects.float_to_rational(xform)
         print "AE sensitivity %d, exposure %dms" % (sens, exp/1000000.0)
@@ -46,7 +53,7 @@
 
         # Auto capture.
         req = its.objects.auto_capture_request()
-        cap_auto = cam.do_capture(req)
+        cap_auto = cam.do_capture(req, fmt)
         img_auto = its.image.convert_capture_to_rgb_image(cap_auto)
         its.image.write_image(img_auto, "%s_auto.jpg" % (NAME))
         xform_a = its.objects.rational_to_float(
@@ -59,7 +66,7 @@
         req = its.objects.manual_capture_request(sens, exp, focus)
         req["android.colorCorrection.transform"] = xform_rat
         req["android.colorCorrection.gains"] = gains
-        cap_man1 = cam.do_capture(req)
+        cap_man1 = cam.do_capture(req, fmt)
         img_man1 = its.image.convert_capture_to_rgb_image(cap_man1)
         its.image.write_image(img_man1, "%s_manual_wb.jpg" % (NAME))
         xform_m1 = its.objects.rational_to_float(
@@ -74,7 +81,7 @@
         req["android.tonemap.curveRed"] = gamma
         req["android.tonemap.curveGreen"] = gamma
         req["android.tonemap.curveBlue"] = gamma
-        cap_man2 = cam.do_capture(req)
+        cap_man2 = cam.do_capture(req, fmt)
         img_man2 = its.image.convert_capture_to_rgb_image(cap_man2)
         its.image.write_image(img_man2, "%s_manual_wb_tm.jpg" % (NAME))
         xform_m2 = its.objects.rational_to_float(
diff --git a/apps/CameraITS/tests/scene1/test_black_white.py b/apps/CameraITS/tests/scene1/test_black_white.py
index 68d7de6..e2de71e 100644
--- a/apps/CameraITS/tests/scene1/test_black_white.py
+++ b/apps/CameraITS/tests/scene1/test_black_white.py
@@ -35,6 +35,14 @@
         its.caps.skip_unless(its.caps.manual_sensor(props) and
                              its.caps.per_frame_control(props))
 
+        debug = its.caps.debug_mode()
+        largest_yuv = its.objects.get_largest_yuv_format(props)
+        if debug:
+            fmt = largest_yuv
+        else:
+            match_ar = (largest_yuv['width'], largest_yuv['height'])
+            fmt = its.objects.get_smallest_yuv_format(props, match_ar=match_ar)
+
         expt_range = props['android.sensor.info.exposureTimeRange']
         sens_range = props['android.sensor.info.sensitivityRange']
 
@@ -43,7 +51,7 @@
         print "Black shot: sens = %d, exp time = %.4fms" % (
                 sens_range[0], expt_range[0]/1000000.0)
         req = its.objects.manual_capture_request(sens_range[0], expt_range[0])
-        cap = cam.do_capture(req)
+        cap = cam.do_capture(req, fmt)
         img = its.image.convert_capture_to_rgb_image(cap)
         its.image.write_image(img, "%s_black.jpg" % (NAME))
         tile = its.image.get_image_patch(img, 0.45, 0.45, 0.1, 0.1)
@@ -58,7 +66,7 @@
         print "White shot: sens = %d, exp time = %.2fms" % (
                 sens_range[1], expt_range[1]/1000000.0)
         req = its.objects.manual_capture_request(sens_range[1], expt_range[1])
-        cap = cam.do_capture(req)
+        cap = cam.do_capture(req, fmt)
         img = its.image.convert_capture_to_rgb_image(cap)
         its.image.write_image(img, "%s_white.jpg" % (NAME))
         tile = its.image.get_image_patch(img, 0.45, 0.45, 0.1, 0.1)
diff --git a/apps/CameraITS/tests/scene1/test_ev_compensation_advanced.py b/apps/CameraITS/tests/scene1/test_ev_compensation_advanced.py
index c14f5a9..d355cd8 100644
--- a/apps/CameraITS/tests/scene1/test_ev_compensation_advanced.py
+++ b/apps/CameraITS/tests/scene1/test_ev_compensation_advanced.py
@@ -41,6 +41,14 @@
                              its.caps.per_frame_control(props) and
                              its.caps.ev_compensation(props))
 
+        debug = its.caps.debug_mode()
+        largest_yuv = its.objects.get_largest_yuv_format(props)
+        if debug:
+            fmt = largest_yuv
+        else:
+            match_ar = (largest_yuv['width'], largest_yuv['height'])
+            fmt = its.objects.get_smallest_yuv_format(props, match_ar=match_ar)
+
         ev_compensation_range = props['android.control.aeCompensationRange']
         range_min = ev_compensation_range[0]
         range_max = ev_compensation_range[1]
@@ -69,7 +77,7 @@
             req["android.tonemap.curveRed"] = [0.0,0.0, 1.0,1.0]
             req["android.tonemap.curveGreen"] = [0.0,0.0, 1.0,1.0]
             req["android.tonemap.curveBlue"] = [0.0,0.0, 1.0,1.0]
-            caps = cam.do_capture([req]*THREASH_CONVERGE_FOR_EV)
+            caps = cam.do_capture([req]*THREASH_CONVERGE_FOR_EV, fmt)
 
             for cap in caps:
                 if (cap['metadata']['android.control.aeState'] == LOCKED):
diff --git a/apps/CameraITS/tests/scene1/test_ev_compensation_basic.py b/apps/CameraITS/tests/scene1/test_ev_compensation_basic.py
index cb69607..9992667 100644
--- a/apps/CameraITS/tests/scene1/test_ev_compensation_basic.py
+++ b/apps/CameraITS/tests/scene1/test_ev_compensation_basic.py
@@ -41,6 +41,14 @@
         its.caps.skip_unless(its.caps.ev_compensation(props) and
                              its.caps.ae_lock(props))
 
+        debug = its.caps.debug_mode()
+        largest_yuv = its.objects.get_largest_yuv_format(props)
+        if debug:
+            fmt = largest_yuv
+        else:
+            match_ar = (largest_yuv['width'], largest_yuv['height'])
+            fmt = its.objects.get_smallest_yuv_format(props, match_ar=match_ar)
+
         ev_per_step = its.objects.rational_to_float(
                 props['android.control.aeCompensationStep'])
         steps_per_ev = int(1.0 / ev_per_step)
@@ -61,7 +69,7 @@
             req = its.objects.auto_capture_request()
             req['android.control.aeExposureCompensation'] = ev
             req["android.control.aeLock"] = True
-            caps = cam.do_capture([req]*THRESH_CONVERGE_FOR_EV)
+            caps = cam.do_capture([req]*THRESH_CONVERGE_FOR_EV, fmt)
             for cap in caps:
                 if (cap['metadata']['android.control.aeState'] == LOCKED):
                     y = its.image.convert_capture_to_planes(cap)[0]
diff --git a/apps/CameraITS/tests/scene1/test_exposure.py b/apps/CameraITS/tests/scene1/test_exposure.py
index e53af21..26e3f4d 100644
--- a/apps/CameraITS/tests/scene1/test_exposure.py
+++ b/apps/CameraITS/tests/scene1/test_exposure.py
@@ -51,6 +51,14 @@
         its.caps.skip_unless(its.caps.compute_target_exposure(props) and
                              its.caps.per_frame_control(props))
 
+        debug = its.caps.debug_mode()
+        largest_yuv = its.objects.get_largest_yuv_format(props)
+        if debug:
+            fmt = largest_yuv
+        else:
+            match_ar = (largest_yuv['width'], largest_yuv['height'])
+            fmt = its.objects.get_smallest_yuv_format(props, match_ar=match_ar)
+
         e,s = its.target.get_target_exposure_combos(cam)["minSensitivity"]
         s_e_product = s*e
         expt_range = props['android.sensor.info.exposureTimeRange']
@@ -64,7 +72,7 @@
             print "Testing s:", s_test, "e:", e_test
             req = its.objects.manual_capture_request(
                     s_test, e_test, 0.0, True, props)
-            cap = cam.do_capture(req)
+            cap = cam.do_capture(req, fmt)
             s_res = cap["metadata"]["android.sensor.sensitivity"]
             e_res = cap["metadata"]["android.sensor.exposureTime"]
             assert(0 <= s_test - s_res < s_test * THRESHOLD_ROUND_DOWN_GAIN)
diff --git a/apps/CameraITS/tests/scene1/test_format_combos.py b/apps/CameraITS/tests/scene1/test_format_combos.py
index 1b40826..1519237 100644
--- a/apps/CameraITS/tests/scene1/test_format_combos.py
+++ b/apps/CameraITS/tests/scene1/test_format_combos.py
@@ -38,6 +38,7 @@
 
         successes = []
         failures = []
+        debug = its.caps.debug_mode()
 
         # Two different requests: auto, and manual.
         e, s = its.target.get_target_exposure_combos(cam)["midExposureTime"]
@@ -89,7 +90,8 @@
                         for c,cap in enumerate(caps):
                             img = its.image.convert_capture_to_rgb_image(cap,
                                     props=props)
-                            its.image.write_image(img,
+                            if debug:
+                                its.image.write_image(img,
                                     "%s_n%02d_r%d_f%d_b%d_c%d.jpg"%(NAME,n,r,f,b,c))
 
                     except Exception as e:
diff --git a/apps/CameraITS/tests/scene1/test_linearity.py b/apps/CameraITS/tests/scene1/test_linearity.py
index 2176f5e..9de1af3 100644
--- a/apps/CameraITS/tests/scene1/test_linearity.py
+++ b/apps/CameraITS/tests/scene1/test_linearity.py
@@ -50,6 +50,14 @@
         its.caps.skip_unless(its.caps.compute_target_exposure(props) and
                              its.caps.per_frame_control(props))
 
+        debug = its.caps.debug_mode()
+        largest_yuv = its.objects.get_largest_yuv_format(props)
+        if debug:
+            fmt = largest_yuv
+        else:
+            match_ar = (largest_yuv['width'], largest_yuv['height'])
+            fmt = its.objects.get_smallest_yuv_format(props, match_ar=match_ar)
+
         e,s = its.target.get_target_exposure_combos(cam)["midSensitivity"]
         s /= 2
         sens_range = props['android.sensor.info.sensitivityRange']
@@ -70,7 +78,7 @@
 
         for sens in sensitivities:
             req["android.sensor.sensitivity"] = sens
-            cap = cam.do_capture(req)
+            cap = cam.do_capture(req, fmt)
             img = its.image.convert_capture_to_rgb_image(cap)
             its.image.write_image(
                     img, "%s_sens=%04d.jpg" % (NAME, sens))
diff --git a/apps/CameraITS/tests/scene1/test_locked_burst.py b/apps/CameraITS/tests/scene1/test_locked_burst.py
index daefb6b..5308010 100644
--- a/apps/CameraITS/tests/scene1/test_locked_burst.py
+++ b/apps/CameraITS/tests/scene1/test_locked_burst.py
@@ -44,6 +44,8 @@
         # Converge 3A prior to capture.
         cam.do_3a(do_af=True, lock_ae=True, lock_awb=True)
 
+        fmt = its.objects.get_largest_yuv_format(props)
+
         # After 3A has converged, lock AE+AWB for the duration of the test.
         req = its.objects.fastest_auto_capture_request(props)
         req["android.control.awbLock"] = True
@@ -54,7 +56,7 @@
         r_means = []
         g_means = []
         b_means = []
-        caps = cam.do_capture([req]*BURST_LEN)
+        caps = cam.do_capture([req]*BURST_LEN, fmt)
         for i,cap in enumerate(caps):
             img = its.image.convert_capture_to_rgb_image(cap)
             its.image.write_image(img, "%s_frame%d.jpg"%(NAME,i))
diff --git a/apps/CameraITS/tests/scene1/test_param_color_correction.py b/apps/CameraITS/tests/scene1/test_param_color_correction.py
index 8623426..4ce8933 100644
--- a/apps/CameraITS/tests/scene1/test_param_color_correction.py
+++ b/apps/CameraITS/tests/scene1/test_param_color_correction.py
@@ -41,6 +41,14 @@
                              its.caps.per_frame_control(props))
 
         # Baseline request
+        debug = its.caps.debug_mode()
+        largest_yuv = its.objects.get_largest_yuv_format(props)
+        if debug:
+            fmt = largest_yuv
+        else:
+            match_ar = (largest_yuv['width'], largest_yuv['height'])
+            fmt = its.objects.get_smallest_yuv_format(props, match_ar=match_ar)
+
         e, s = its.target.get_target_exposure_combos(cam)["midSensitivity"]
         req = its.objects.manual_capture_request(s, e, 0.0, True, props)
         req["android.colorCorrection.mode"] = 0
@@ -70,7 +78,7 @@
         for i in range(len(transforms)):
             req["android.colorCorrection.transform"] = transforms[i]
             req["android.colorCorrection.gains"] = gains[i]
-            cap = cam.do_capture(req)
+            cap = cam.do_capture(req, fmt)
             img = its.image.convert_capture_to_rgb_image(cap)
             its.image.write_image(img, "%s_req=%d.jpg" % (NAME, i))
             tile = its.image.get_image_patch(img, 0.45, 0.45, 0.1, 0.1)
diff --git a/apps/CameraITS/tests/scene1/test_param_exposure_time.py b/apps/CameraITS/tests/scene1/test_param_exposure_time.py
index 576516c..fafde9d 100644
--- a/apps/CameraITS/tests/scene1/test_param_exposure_time.py
+++ b/apps/CameraITS/tests/scene1/test_param_exposure_time.py
@@ -37,10 +37,18 @@
         its.caps.skip_unless(its.caps.compute_target_exposure(props) and
                              its.caps.per_frame_control(props))
 
+        debug = its.caps.debug_mode()
+        largest_yuv = its.objects.get_largest_yuv_format(props)
+        if debug:
+            fmt = largest_yuv
+        else:
+            match_ar = (largest_yuv['width'], largest_yuv['height'])
+            fmt = its.objects.get_smallest_yuv_format(props, match_ar=match_ar)
+
         e,s = its.target.get_target_exposure_combos(cam)["midExposureTime"]
         for i,e_mult in enumerate([0.8, 0.9, 1.0, 1.1, 1.2]):
             req = its.objects.manual_capture_request(s, e * e_mult, 0.0, True, props)
-            cap = cam.do_capture(req)
+            cap = cam.do_capture(req, fmt)
             img = its.image.convert_capture_to_rgb_image(cap)
             its.image.write_image(
                     img, "%s_frame%d.jpg" % (NAME, i))
diff --git a/apps/CameraITS/tests/scene1/test_param_flash_mode.py b/apps/CameraITS/tests/scene1/test_param_flash_mode.py
index 5ef6fd6..2d8c678 100644
--- a/apps/CameraITS/tests/scene1/test_param_flash_mode.py
+++ b/apps/CameraITS/tests/scene1/test_param_flash_mode.py
@@ -37,13 +37,21 @@
         # Manually set the exposure to be a little on the dark side, so that
         # it should be obvious whether the flash fired or not, and use a
         # linear tonemap.
+        debug = its.caps.debug_mode()
+        largest_yuv = its.objects.get_largest_yuv_format(props)
+        if debug:
+            fmt = largest_yuv
+        else:
+            match_ar = (largest_yuv['width'], largest_yuv['height'])
+            fmt = its.objects.get_smallest_yuv_format(props, match_ar=match_ar)
+
         e, s = its.target.get_target_exposure_combos(cam)["midExposureTime"]
         e /= 4
         req = its.objects.manual_capture_request(s, e, 0.0, True, props)
 
         for f in [0,1,2]:
             req["android.flash.mode"] = f
-            cap = cam.do_capture(req)
+            cap = cam.do_capture(req, fmt)
             flash_modes_reported.append(cap["metadata"]["android.flash.mode"])
             flash_states_reported.append(cap["metadata"]["android.flash.state"])
             img = its.image.convert_capture_to_rgb_image(cap)
diff --git a/apps/CameraITS/tests/scene1/test_param_sensitivity.py b/apps/CameraITS/tests/scene1/test_param_sensitivity.py
index d6b44a2..32b764d 100644
--- a/apps/CameraITS/tests/scene1/test_param_sensitivity.py
+++ b/apps/CameraITS/tests/scene1/test_param_sensitivity.py
@@ -39,6 +39,14 @@
         its.caps.skip_unless(its.caps.compute_target_exposure(props) and
                              its.caps.per_frame_control(props))
 
+        debug = its.caps.debug_mode()
+        largest_yuv = its.objects.get_largest_yuv_format(props)
+        if debug:
+            fmt = largest_yuv
+        else:
+            match_ar = (largest_yuv['width'], largest_yuv['height'])
+            fmt = its.objects.get_smallest_yuv_format(props, match_ar=match_ar)
+
         expt,_ = its.target.get_target_exposure_combos(cam)["midSensitivity"]
         sens_range = props['android.sensor.info.sensitivityRange']
         sens_step = (sens_range[1] - sens_range[0]) / float(NUM_STEPS-1)
@@ -46,7 +54,7 @@
 
         for s in sensitivities:
             req = its.objects.manual_capture_request(s, expt)
-            cap = cam.do_capture(req)
+            cap = cam.do_capture(req, fmt)
             img = its.image.convert_capture_to_rgb_image(cap)
             its.image.write_image(
                     img, "%s_iso=%04d.jpg" % (NAME, s))
diff --git a/apps/CameraITS/tests/scene1/test_param_tonemap_mode.py b/apps/CameraITS/tests/scene1/test_param_tonemap_mode.py
index 8c8e626..1229f90 100644
--- a/apps/CameraITS/tests/scene1/test_param_tonemap_mode.py
+++ b/apps/CameraITS/tests/scene1/test_param_tonemap_mode.py
@@ -41,6 +41,14 @@
         its.caps.skip_unless(its.caps.compute_target_exposure(props) and
                              its.caps.per_frame_control(props))
 
+        debug = its.caps.debug_mode()
+        largest_yuv = its.objects.get_largest_yuv_format(props)
+        if debug:
+            fmt = largest_yuv
+        else:
+            match_ar = (largest_yuv['width'], largest_yuv['height'])
+            fmt = its.objects.get_smallest_yuv_format(props, match_ar=match_ar)
+
         e, s = its.target.get_target_exposure_combos(cam)["midExposureTime"]
         e /= 2
 
@@ -60,7 +68,7 @@
                     sum([[i/LM1, min(1.0,(1+1.0*n)*i/LM1)] for i in range(L)], []))
             req["android.tonemap.curveBlue"] = (
                     sum([[i/LM1, min(1.0,(1+1.5*n)*i/LM1)] for i in range(L)], []))
-            cap = cam.do_capture(req)
+            cap = cam.do_capture(req, fmt)
             img = its.image.convert_capture_to_rgb_image(cap)
             its.image.write_image(
                     img, "%s_n=%d.jpg" %(NAME, n))
diff --git a/apps/CameraITS/tests/scene1/test_tonemap_sequence.py b/apps/CameraITS/tests/scene1/test_tonemap_sequence.py
index 0db70b8..2b5f094 100644
--- a/apps/CameraITS/tests/scene1/test_tonemap_sequence.py
+++ b/apps/CameraITS/tests/scene1/test_tonemap_sequence.py
@@ -26,7 +26,7 @@
 
     # There should be 3 identical frames followed by a different set of
     # 3 identical frames.
-    MAX_SAME_DELTA = 0.015
+    MAX_SAME_DELTA = 0.03  # match number in test_burst_sameness_manual
     MIN_DIFF_DELTA = 0.10
 
     with its.device.ItsSession() as cam:
@@ -35,6 +35,14 @@
                              its.caps.manual_post_proc(props) and
                              its.caps.per_frame_control(props))
 
+        debug = its.caps.debug_mode()
+        largest_yuv = its.objects.get_largest_yuv_format(props)
+        if debug:
+            fmt = largest_yuv
+        else:
+            match_ar = (largest_yuv['width'], largest_yuv['height'])
+            fmt = its.objects.get_smallest_yuv_format(props, match_ar=match_ar)
+
         sens, exp_time, _,_,f_dist = cam.do_3a(do_af=True,get_results=True)
 
         means = []
@@ -42,7 +50,7 @@
         # Capture 3 manual shots with a linear tonemap.
         req = its.objects.manual_capture_request(sens, exp_time, f_dist, True, props)
         for i in [0,1,2]:
-            cap = cam.do_capture(req)
+            cap = cam.do_capture(req, fmt)
             img = its.image.convert_capture_to_rgb_image(cap)
             its.image.write_image(img, "%s_i=%d.jpg" % (NAME, i))
             tile = its.image.get_image_patch(img, 0.45, 0.45, 0.1, 0.1)
@@ -51,7 +59,7 @@
         # Capture 3 manual shots with the default tonemap.
         req = its.objects.manual_capture_request(sens, exp_time, f_dist, False)
         for i in [3,4,5]:
-            cap = cam.do_capture(req)
+            cap = cam.do_capture(req, fmt)
             img = its.image.convert_capture_to_rgb_image(cap)
             its.image.write_image(img, "%s_i=%d.jpg" % (NAME, i))
             tile = its.image.get_image_patch(img, 0.45, 0.45, 0.1, 0.1)
diff --git a/apps/CameraITS/tests/scene1/test_yuv_plus_raw.py b/apps/CameraITS/tests/scene1/test_yuv_plus_raw.py
index a5ceaba..10e100d 100644
--- a/apps/CameraITS/tests/scene1/test_yuv_plus_raw.py
+++ b/apps/CameraITS/tests/scene1/test_yuv_plus_raw.py
@@ -51,11 +51,11 @@
         tile = its.image.get_image_patch(img, 0.45, 0.45, 0.1, 0.1)
         rgb0 = its.image.compute_image_means(tile)
 
-        # Raw shots are 1/2 x 1/2 smaller after conversion to RGB, so scale the
-        # tile appropriately.
+        # Raw shots are 1/2 x 1/2 smaller after conversion to RGB, but tile
+        # cropping is relative.
         img = its.image.convert_capture_to_rgb_image(cap_raw, props=props)
         its.image.write_image(img, "%s_raw.jpg" % (NAME), True)
-        tile = its.image.get_image_patch(img, 0.475, 0.475, 0.05, 0.05)
+        tile = its.image.get_image_patch(img, 0.45, 0.45, 0.1, 0.1)
         rgb1 = its.image.compute_image_means(tile)
 
         rms_diff = math.sqrt(
diff --git a/apps/CameraITS/tests/scene1/test_yuv_plus_raw10.py b/apps/CameraITS/tests/scene1/test_yuv_plus_raw10.py
index f281089..be5f701 100644
--- a/apps/CameraITS/tests/scene1/test_yuv_plus_raw10.py
+++ b/apps/CameraITS/tests/scene1/test_yuv_plus_raw10.py
@@ -51,11 +51,11 @@
         tile = its.image.get_image_patch(img, 0.45, 0.45, 0.1, 0.1)
         rgb0 = its.image.compute_image_means(tile)
 
-        # Raw shots are 1/2 x 1/2 smaller after conversion to RGB, so scale the
-        # tile appropriately.
+        # Raw shots are 1/2 x 1/2 smaller after conversion to RGB, but tile
+        # cropping is relative.
         img = its.image.convert_capture_to_rgb_image(cap_raw, props=props)
         its.image.write_image(img, "%s_raw.jpg" % (NAME), True)
-        tile = its.image.get_image_patch(img, 0.475, 0.475, 0.05, 0.05)
+        tile = its.image.get_image_patch(img, 0.45, 0.45, 0.1, 0.1)
         rgb1 = its.image.compute_image_means(tile)
 
         rms_diff = math.sqrt(
diff --git a/apps/CameraITS/tests/scene1/test_yuv_plus_raw12.py b/apps/CameraITS/tests/scene1/test_yuv_plus_raw12.py
index 5b6051a..8070785 100644
--- a/apps/CameraITS/tests/scene1/test_yuv_plus_raw12.py
+++ b/apps/CameraITS/tests/scene1/test_yuv_plus_raw12.py
@@ -51,11 +51,11 @@
         tile = its.image.get_image_patch(img, 0.45, 0.45, 0.1, 0.1)
         rgb0 = its.image.compute_image_means(tile)
 
-        # Raw shots are 1/2 x 1/2 smaller after conversion to RGB, so scale the
-        # tile appropriately.
+        # Raw shots are 1/2 x 1/2 smaller after conversion to RGB, but tile
+        # cropping is relative.
         img = its.image.convert_capture_to_rgb_image(cap_raw, props=props)
         its.image.write_image(img, "%s_raw.jpg" % (NAME), True)
-        tile = its.image.get_image_patch(img, 0.475, 0.475, 0.05, 0.05)
+        tile = its.image.get_image_patch(img, 0.45, 0.45, 0.1, 0.1)
         rgb1 = its.image.compute_image_means(tile)
 
         rms_diff = math.sqrt(
diff --git a/apps/CameraITS/tests/scene4/test_aspect_ratio_and_crop.py b/apps/CameraITS/tests/scene4/test_aspect_ratio_and_crop.py
index 9d212cc..13dbe84 100644
--- a/apps/CameraITS/tests/scene4/test_aspect_ratio_and_crop.py
+++ b/apps/CameraITS/tests/scene4/test_aspect_ratio_and_crop.py
@@ -79,6 +79,7 @@
         run_crop_test = (level3_device or full_device) and raw_avlb
         if not run_crop_test:
             print "Crop test skipped"
+        debug = its.caps.debug_mode()
         # Converge 3A and get the estimates.
         sens, exp, gains, xform, focus = cam.do_3a(get_results=True,
                                                    lock_ae=True, lock_awb=True)
@@ -106,7 +107,8 @@
             img_name = "%s_%s_w%d_h%d.png" \
                        % (NAME, "raw", size_raw[1], size_raw[0])
             aspect_ratio_gt, cc_ct_gt, circle_size_raw = measure_aspect_ratio(
-                                                         img_raw, 1, img_name)
+                                                         img_raw, 1, img_name,
+                                                         debug)
             # Normalize the circle size to 1/4 of the image size, so that
             # circle size won"t affect the crop test result
             factor_cp_thres = (min(size_raw[0:1])/4.0) / max(circle_size_raw)
@@ -157,7 +159,8 @@
                 img_name = "%s_%s_with_%s_w%d_h%d.png" \
                            % (NAME, fmt_iter, fmt_cmpr, w_iter, h_iter)
                 aspect_ratio, cc_ct, (cc_w, cc_h) = \
-                        measure_aspect_ratio(img, raw_avlb, img_name)
+                        measure_aspect_ratio(img, raw_avlb, img_name,
+                                             debug)
                 # check pass/fail for aspect ratio
                 # image size >= LARGE_SIZE: use THRES_L_AR_TEST
                 # image size == 0 (extreme case): THRES_XS_AR_TEST
@@ -245,7 +248,7 @@
             assert (failed_image_number_for_crop_test == 0)
 
 
-def measure_aspect_ratio(img, raw_avlb, img_name):
+def measure_aspect_ratio(img, raw_avlb, img_name, debug):
     """ Measure the aspect ratio of the black circle in the test image.
 
     Args:
@@ -253,6 +256,7 @@
         raw_avlb: True: raw capture is available; False: raw capture is not
              available.
         img_name: string with image info of format and size.
+        debug: boolean for whether in debug mode.
     Returns:
         aspect_ratio: aspect ratio number in float.
         cc_ct: circle center position relative to the center of image.
@@ -382,7 +386,8 @@
     cv2.putText(img, "image center", (text_imgct_x, text_imgct_y),
                 cv2.FONT_HERSHEY_SIMPLEX, line_width/2.0, (255, 0, 0),
                 line_width)
-    its.image.write_image(img/255, img_name, True)
+    if debug:
+        its.image.write_image(img/255, img_name, True)
 
     print "Aspect ratio: %.3f" % aspect_ratio
     print "Circle center position regarding to image center: %.3fx%.3f" % \
diff --git a/apps/CtsVerifier/Android.mk b/apps/CtsVerifier/Android.mk
index 304c982..cafb855 100644
--- a/apps/CtsVerifier/Android.mk
+++ b/apps/CtsVerifier/Android.mk
@@ -26,7 +26,6 @@
 LOCAL_SRC_FILES := $(call all-java-files-under, src) $(call all-Iaidl-files-under, src)
 
 LOCAL_STATIC_JAVA_LIBRARIES := android-ex-camera2 \
-                               android-support-v4 \
                                compatibility-common-util-devicesidelib \
                                cts-sensors-tests \
                                cts-location-tests \
diff --git a/apps/CtsVerifier/AndroidManifest.xml b/apps/CtsVerifier/AndroidManifest.xml
index fc07ae1..38231cd 100644
--- a/apps/CtsVerifier/AndroidManifest.xml
+++ b/apps/CtsVerifier/AndroidManifest.xml
@@ -18,7 +18,7 @@
 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
       package="com.android.cts.verifier"
       android:versionCode="5"
-      android:versionName="7.1_r1">
+      android:versionName="7.1_r201703s">
 
     <uses-sdk android:minSdkVersion="19" android:targetSdkVersion="25"/>
 
@@ -69,7 +69,8 @@
             android:icon="@drawable/icon"
             android:backupAgent="VerifierBackupAgent"
             android:debuggable="true"
-            android:largeHeap="true">
+            android:largeHeap="true"
+            android:theme="@android:style/Theme.DeviceDefault">
 
         <meta-data android:name="SuiteName" android:value="CTS_VERIFIER" />
 
@@ -153,6 +154,8 @@
             <meta-data android:name="test_category" android:value="@string/test_category_device_admin" />
             <meta-data android:name="test_required_features"
                     android:value="android.software.device_admin" />
+            <meta-data android:name="test_excluded_features"
+                    android:value="android.hardware.type.watch" />
         </activity>
 
         <activity android:name=".admin.ScreenLockTestActivity"
@@ -516,6 +519,17 @@
             <meta-data android:name="test_required_features" android:value="android.hardware.location.gps" />
         </activity>
 
+        <!--  activity android:name=".location.GnssStatusTestsActivity"
+            android:label="@string/location_gnss_status_test"
+            android:screenOrientation="locked">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN"/>
+                <category android:name="android.cts.intent.category.MANUAL_TEST"/>
+            </intent-filter>
+            <meta-data android:name="test_category" android:value="@string/test_category_hardware"/>
+            <meta-data android:name="test_required_features" android:value="android.hardware.location.gps" />
+        </activity -->
+
         <activity android:name=".location.LocationListenerActivity"
                 android:label="@string/location_listener_activity"
                 android:configChanges="keyboardHidden|orientation|screenSize">
@@ -1259,6 +1273,18 @@
             </intent-filter>
         </service>
 
+        <activity android:name=".notifications.ShortcutThrottlingResetActivity"
+            android:label="@string/shortcut_reset_test"
+            android:configChanges="mcc|mnc|locale|touchscreen|keyboard|keyboardHidden|navigation|screenLayout|fontScale|uiMode|orientation|screenSize|smallestScreenSize|layoutDirection">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+                <category android:name="android.cts.intent.category.MANUAL_TEST" />
+            </intent-filter>
+            <meta-data android:name="test_category" android:value="@string/test_category_notifications" />
+            <meta-data android:name="test_excluded_features"
+                android:value="android.hardware.type.watch:android.software.leanback" />
+        </activity>
+
         <activity android:name=".vr.VrListenerVerifierActivity"
             android:label="@string/vr_tests">
             <intent-filter>
@@ -1714,6 +1740,10 @@
                 <action android:name="com.android.cts.verifier.managedprovisioning.BYOD_STATUS" />
                 <category android:name="android.intent.category.DEFAULT"></category>
             </intent-filter>
+            <intent-filter>
+                <action android:name="com.android.cts.verifier.managedprovisioning.action.BYOD_DISK_ENCRYPTION_STATUS" />
+                <category android:name="android.intent.category.DEFAULT"></category>
+            </intent-filter>
             <meta-data android:name="test_category" android:value="@string/test_category_managed_provisioning" />
             <meta-data android:name="test_required_features" android:value="android.software.managed_users:android.software.device_admin" />
         </activity>
@@ -1735,6 +1765,7 @@
                 <action android:name="com.android.cts.verifier.managedprovisioning.BYOD_QUERY" />
                 <action android:name="com.android.cts.verifier.managedprovisioning.BYOD_REMOVE" />
                 <action android:name="com.android.cts.verifier.managedprovisioning.BYOD_INSTALL_APK" />
+                <action android:name="com.android.cts.verifier.managedprovisioning.action.BYOD_CHECK_DISK_ENCRYPTION" />
                 <action android:name="com.android.cts.verifier.managedprovisioning.action.CHECK_INTENT_FILTERS" />
                 <action android:name="com.android.cts.verifier.managedprovisioning.BYOD_CAPTURE_AND_CHECK_IMAGE" />
                 <action android:name="com.android.cts.verifier.managedprovisioning.BYOD_CAPTURE_AND_CHECK_VIDEO_WITH_EXTRA_OUTPUT" />
diff --git a/apps/CtsVerifier/res/layout-port/gnss_test.xml b/apps/CtsVerifier/res/layout-port/gnss_test.xml
index 560133a..1838e88 100644
--- a/apps/CtsVerifier/res/layout-port/gnss_test.xml
+++ b/apps/CtsVerifier/res/layout-port/gnss_test.xml
@@ -1,5 +1,4 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2016 The Android Open Source Project
+<?xml version="1.0" encoding="utf-8"?><!-- Copyright (C) 2016 The Android Open Source Project
 
      Licensed under the Apache License, Version 2.0 (the "License");
      you may not use this file except in compliance with the License.
@@ -13,45 +12,32 @@
      See the License for the specific language governing permissions and
      limitations under the License.
 -->
-<com.android.cts.verifier.BoxInsetLayout xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:app="http://schemas.android.com/apk/res-auto"
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    style="@style/RootLayoutPadding"
     android:layout_width="match_parent"
-    android:layout_height="match_parent">
-    <LinearLayout app:ctsv_layout_box="all"
-        android:orientation="vertical"
+    android:layout_height="match_parent"
+    android:orientation="vertical">
+
+    <TextView
+        android:id="@+id/text"
         android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:textSize="14sp" />
+
+    <ScrollView
+        android:id="@+id/log_scroll_view"
+        android:layout_width="0dp"
         android:layout_height="match_parent"
-        >
+        android:layout_weight="1"
+        android:fillViewport="true">
 
         <LinearLayout
-            android:orientation="horizontal"
+            android:id="@+id/log_layout"
             android:layout_width="match_parent"
-            android:layout_height="0dp"
-            android:layout_weight="1">
+            android:layout_height="match_parent"
+            android:orientation="vertical" />
 
-            <TextView android:id="@+id/text"
-                android:textSize="14sp"
-                android:layout_width="match_parent"
-                android:layout_height="wrap_content"/>
+    </ScrollView>
 
-            <ScrollView
-                android:id="@+id/log_scroll_view"
-                android:fillViewport="true"
-                android:layout_height="match_parent"
-                android:layout_width="0dp"
-                android:layout_weight="1">
-
-                <LinearLayout
-                    android:id="@+id/log_layout"
-                    android:orientation="vertical"
-                    android:layout_width="match_parent"
-                    android:layout_height="match_parent"/>
-
-            </ScrollView>
-
-        </LinearLayout>
-
-        <include layout="@layout/snsr_next_button" />
-
-    </LinearLayout>
-</com.android.cts.verifier.BoxInsetLayout>
+    <include layout="@layout/snsr_next_button" />
+</LinearLayout>
diff --git a/apps/CtsVerifier/res/layout-round/provisioning_byod.xml b/apps/CtsVerifier/res/layout-round/provisioning_byod.xml
new file mode 100644
index 0000000..d2b6e0e
--- /dev/null
+++ b/apps/CtsVerifier/res/layout-round/provisioning_byod.xml
@@ -0,0 +1,42 @@
+<?xml version="1.0" encoding="utf-8"?><!-- Copyright (C) 2016 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+<android.support.v4.widget.NestedScrollView xmlns:android="http://schemas.android.com/apk/res/android"
+    android:id="@+id/main_layout"
+    style="@style/RootLayoutPadding"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent"
+    android:orientation="vertical">
+
+    <LinearLayout
+        android:layout_width="match_parent"
+        android:layout_height="match_parent"
+        android:orientation="vertical">
+        <TextView
+            android:id="@+id/test_instructions"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:padding="10dip"/>
+        <Button
+            android:id="@+id/prepare_test_button"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"/>
+        <ListView
+            android:id="@+id/android:list"
+            android:layout_width="match_parent"
+            android:layout_height="0dip"
+            android:layout_weight="3"/>
+        <include layout="@layout/pass_fail_buttons"/>
+    </LinearLayout>
+</android.support.v4.widget.NestedScrollView>
diff --git a/apps/CtsVerifier/res/layout-small/gnss_test.xml b/apps/CtsVerifier/res/layout-small/gnss_test.xml
index 5caea07..e36bf26 100644
--- a/apps/CtsVerifier/res/layout-small/gnss_test.xml
+++ b/apps/CtsVerifier/res/layout-small/gnss_test.xml
@@ -1,5 +1,4 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2016 The Android Open Source Project
+<?xml version="1.0" encoding="utf-8"?><!-- Copyright (C) 2016 The Android Open Source Project
 
      Licensed under the Apache License, Version 2.0 (the "License");
      you may not use this file except in compliance with the License.
@@ -13,32 +12,34 @@
      See the License for the specific language governing permissions and
      limitations under the License.
 -->
-<com.android.cts.verifier.BoxInsetLayout xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:app="http://schemas.android.com/apk/res-auto"
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    style="@style/RootLayoutPadding"
     android:layout_width="match_parent"
     android:layout_height="match_parent">
-    <ScrollView android:id="@+id/log_scroll_view"
-        app:ctsv_layout_box="all"
-        android:fillViewport="true"
+    <ScrollView
+        android:id="@+id/log_scroll_view"
+        android:layout_width="match_parent"
         android:layout_height="match_parent"
-        android:layout_width="match_parent">
+        android:fillViewport="true">
         <LinearLayout
-            android:orientation="vertical"
+            android:layout_width="match_parent"
             android:layout_height="wrap_content"
-            android:layout_width="match_parent">
+            android:orientation="vertical">
 
-            <TextView android:id="@+id/text"
-                android:textSize="14sp"
+            <TextView
+                android:id="@+id/text"
                 android:layout_width="match_parent"
-                android:layout_height="wrap_content"/>
-
-            <LinearLayout android:id="@+id/log_layout"
-                android:orientation="vertical"
                 android:layout_height="wrap_content"
-                android:layout_width="match_parent"/>
+                android:textSize="14sp" />
 
-            <include layout="@layout/snsr_next_button"/>
+            <LinearLayout
+                android:id="@+id/log_layout"
+                android:layout_width="match_parent"
+                android:layout_height="wrap_content"
+                android:orientation="vertical" />
+
+            <include layout="@layout/snsr_next_button" />
         </LinearLayout>
 
     </ScrollView>
-</com.android.cts.verifier.BoxInsetLayout>
+</LinearLayout>
diff --git a/apps/CtsVerifier/res/layout-small/intent_driven_test.xml b/apps/CtsVerifier/res/layout-small/intent_driven_test.xml
new file mode 100644
index 0000000..0a8cab6
--- /dev/null
+++ b/apps/CtsVerifier/res/layout-small/intent_driven_test.xml
@@ -0,0 +1,35 @@
+<?xml version="1.0" encoding="utf-8"?>
+
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent"
+    android:orientation="vertical"
+    style="@style/RootLayoutPadding">
+
+    <ScrollView
+        android:layout_width="match_parent"
+        android:layout_height="match_parent">
+	<LinearLayout
+	android:layout_width="match_parent"
+	android:layout_height="match_parent"
+	android:orientation="vertical">
+        <TextView android:id="@+id/info"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:textSize="12dip"
+            android:padding="2dip"
+            android:text="@string/dc_start_alarm_test_info"/>
+
+    <LinearLayout android:id="@+id/buttons"
+        android:orientation="vertical"
+        android:layout_width="match_parent"
+        android:layout_height="match_parent"/>
+
+    <LinearLayout
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content">
+        <include layout="@layout/pass_fail_buttons"/>
+    </LinearLayout>
+</LinearLayout>
+</ScrollView>
+</LinearLayout>
diff --git a/apps/CtsVerifier/res/layout-small/policy_transparency_test.xml b/apps/CtsVerifier/res/layout-small/policy_transparency_test.xml
new file mode 100644
index 0000000..1c5e448
--- /dev/null
+++ b/apps/CtsVerifier/res/layout-small/policy_transparency_test.xml
@@ -0,0 +1,82 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2016 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+        android:id="@+id/root_view"
+	style="@style/RootLayoutPadding"
+        android:orientation="vertical"
+        android:layout_width="match_parent"
+        android:layout_height="match_parent"
+        android:descendantFocusability="beforeDescendants"
+        android:focusableInTouchMode="true">
+    <ScrollView
+            android:layout_width="match_parent"
+            android:layout_height="match_parent">
+	<LinearLayout
+		android:layout_width="match_parent"
+		android:layout_height="match_parent"
+		android:orientation="vertical">
+        <TextView
+                android:id="@+id/test_instructions"
+                android:layout_width="match_parent"
+                android:layout_height="wrap_content"
+                android:textSize="12dip"/>
+
+    <LinearLayout
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:orientation="vertical"
+            android:paddingTop="8dp">
+        <TextView android:id="@+id/widget_label"
+                android:layout_width="match_parent"
+                android:layout_height="wrap_content"
+                android:textSize="12dip"
+                android:paddingStart="16dp"
+                android:paddingEnd="8dp" />
+        <Switch android:id="@+id/switch_widget"
+                android:layout_width="match_parent"
+                android:layout_height="wrap_content"
+                android:paddingStart="8dp"
+                android:paddingEnd="16dp"
+                android:visibility="gone" />
+        <EditText android:id="@+id/edit_text_widget"
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:ems="6"
+                android:singleLine="true"
+                android:gravity="center"
+                android:visibility="gone" />
+        <Button android:id="@+id/update_button"
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:text="@string/policy_transparency_update_button_label"
+                android:paddingStart="8dp"
+                android:paddingEnd="16dp"
+                android:visibility="gone" />
+        <Spinner android:id="@+id/spinner_widget"
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:visibility="gone" />
+    </LinearLayout>
+
+    <Button android:id="@+id/open_settings_button"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="@string/policy_transparency_open_settings_label" />
+
+    <include layout="@layout/pass_fail_buttons"/>
+</LinearLayout>
+</ScrollView>
+</LinearLayout>
diff --git a/apps/CtsVerifier/res/layout-small/policy_transparency_test_list.xml b/apps/CtsVerifier/res/layout-small/policy_transparency_test_list.xml
new file mode 100644
index 0000000..0835cb1
--- /dev/null
+++ b/apps/CtsVerifier/res/layout-small/policy_transparency_test_list.xml
@@ -0,0 +1,63 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2016 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+<com.android.cts.verifier.BoxInsetLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:app="http://schemas.android.com/apk/res-auto"
+    style="@style/RootLayoutPadding"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent">
+
+<ScrollView
+	android:layout_width="match_parent"
+	android:layout_height="match_parent">
+    <LinearLayout app:ctsv_layout_box="all"
+            android:orientation="vertical"
+            android:layout_width="match_parent"
+            android:layout_height="match_parent"
+            >
+
+        <ListView android:id="@id/android:list"
+                android:layout_width="match_parent"
+                android:layout_height="1000dip"
+		android:layout_marginTop="10dip"
+		android:layout_marginBottom="10dip"
+                />
+
+        <TextView android:id="@id/android:empty"
+                android:layout_width="match_parent"
+                android:layout_height="8dip"
+                />
+
+        <LinearLayout
+                android:layout_width="match_parent"
+                android:layout_height="wrap_content">
+            <Button android:id="@+id/short_msg_button"
+                    android:layout_width="0dp"
+                    android:layout_height="wrap_content"
+                    android:layout_weight="1"
+		    android:textSize="8dip"
+                    android:text="@string/policy_transparency_short_support_msg_label" />
+            <Button android:id="@+id/long_msg_button"
+                    android:layout_width="0dp"
+                    android:layout_height="wrap_content"
+                    android:layout_weight="1"
+		    android:textSize="8dip"
+                    android:text="@string/policy_transparency_long_support_msg_label" />
+        </LinearLayout>
+        <include layout="@layout/pass_fail_buttons" />
+
+    </LinearLayout>
+</ScrollView>
+</com.android.cts.verifier.BoxInsetLayout>
diff --git a/apps/CtsVerifier/res/layout-small/positive_device_owner.xml b/apps/CtsVerifier/res/layout-small/positive_device_owner.xml
new file mode 100644
index 0000000..82f11a2
--- /dev/null
+++ b/apps/CtsVerifier/res/layout-small/positive_device_owner.xml
@@ -0,0 +1,50 @@
+<?xml version="1.0" encoding="utf-8"?><!-- 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.
+-->
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    style="@style/RootLayoutPadding"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent"
+    android:orientation="vertical">
+
+    <ScrollView
+        android:layout_width="match_parent"
+        android:layout_height="match_parent">
+        <LinearLayout
+            android:layout_width="match_parent"
+            android:layout_height="match_parent"
+            android:orientation="vertical">
+
+            <TextView
+                android:id="@+id/positive_device_owner_instructions"
+                android:layout_width="match_parent"
+                android:layout_height="wrap_content"
+                android:text="@string/device_owner_positive_tests_instructions"
+                android:textSize="16dip" />
+
+            <Button
+                android:id="@+id/set_device_owner_button"
+                android:layout_width="match_parent"
+                android:layout_height="wrap_content"
+                android:text="@string/set_device_owner_button_label" />
+
+            <ListView
+                android:id="@+id/android:list"
+                android:layout_width="match_parent"
+                android:layout_height="800dip" />
+
+            <include layout="@layout/pass_fail_buttons" />
+        </LinearLayout>
+    </ScrollView>
+</LinearLayout>
diff --git a/apps/CtsVerifier/res/layout-small/wifi_lockdown.xml b/apps/CtsVerifier/res/layout-small/wifi_lockdown.xml
new file mode 100644
index 0000000..f158976
--- /dev/null
+++ b/apps/CtsVerifier/res/layout-small/wifi_lockdown.xml
@@ -0,0 +1,81 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- 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.
+-->
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+	style="@style/RootLayoutPadding"
+        android:orientation="vertical"
+        android:layout_width="match_parent"
+        android:layout_height="match_parent">
+
+    <ScrollView
+            android:layout_width="match_parent"
+            android:layout_height="match_parent">
+	<LinearLayout
+	android:layout_width="match_parent"
+	android:layout_height="match_parent"
+	android:orientation="vertical">
+        <TextView
+                android:id="@+id/device_owner_wifi_lockdown_info"
+                android:layout_width="match_parent"
+                android:layout_height="wrap_content"
+                android:padding="2dip"
+                android:text="@string/device_owner_wifi_lockdown_info"
+                android:textSize="12dip" />
+
+    <EditText
+        android:id="@+id/device_owner_wifi_ssid"
+        android:hint="(SSID)"
+	android:layout_marginLeft="50dip"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content" />
+
+    <RadioGroup
+        android:id="@+id/device_owner_keyManagementMethods"
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:orientation="vertical">
+        <RadioButton
+            android:id="@+id/device_owner_keymgmnt_none"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:text="@string/device_owner_wifi_key_management_none_button" />
+        <RadioButton
+            android:id="@+id/device_owner_keymgmnt_wpa"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:text="@string/device_owner_wifi_key_management_wpa_button" />
+        <RadioButton
+            android:id="@+id/device_owner_keymgmnt_wep"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:text="@string/device_owner_wifi_key_management_wep_button" />
+    </RadioGroup>
+
+    <Button
+        android:id="@+id/create_wifi_config_button"
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+	android:textSize="12dip"
+        android:text="@string/create_wifi_config_button_label" />
+
+    <ListView
+        android:id="@+id/android:list"
+        android:layout_width="match_parent"
+        android:layout_height="200dip"/>
+
+    <include layout="@layout/pass_fail_buttons" />
+</LinearLayout>
+</ScrollView>
+</LinearLayout>
diff --git a/apps/CtsVerifier/res/layout-watch/da_policy_main.xml b/apps/CtsVerifier/res/layout-watch/da_policy_main.xml
new file mode 100644
index 0000000..abc2f74
--- /dev/null
+++ b/apps/CtsVerifier/res/layout-watch/da_policy_main.xml
@@ -0,0 +1,61 @@
+<?xml version="2.0" encoding="utf-8"?>
+<!-- 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.
+-->
+<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
+    style="@style/RootLayoutPadding"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent">
+
+    <LinearLayout
+        android:layout_width="match_parent"
+        android:layout_height="match_parent"
+        android:orientation="vertical">
+        <ListView
+            android:id="@id/android:list"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:layout_weight="1"/>
+
+        <TextView
+            android:id="@id/android:empty"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:layout_gravity="center_vertical"
+            android:layout_weight="1"
+            android:padding="10dip"
+            android:text="@string/da_no_policy"
+            android:textSize="18dip"/>
+
+        <LinearLayout
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:orientation="horizontal">
+            <Button
+                android:id="@+id/generate_policy_button"
+                android:layout_width="1dip"
+                android:layout_height="wrap_content"
+                android:layout_weight="1"
+                android:text="@string/da_generate_policy"/>
+            <Button
+                android:id="@+id/apply_policy_button"
+                android:layout_width="1dip"
+                android:layout_height="wrap_content"
+                android:layout_weight="1"
+                android:text="@string/da_apply_policy"/>
+        </LinearLayout>
+
+        <include layout="@layout/pass_fail_buttons"/>
+    </LinearLayout>
+</ScrollView>
diff --git a/apps/CtsVerifier/res/layout-watch/provisioning_byod.xml b/apps/CtsVerifier/res/layout-watch/provisioning_byod.xml
new file mode 100644
index 0000000..75cc90a
--- /dev/null
+++ b/apps/CtsVerifier/res/layout-watch/provisioning_byod.xml
@@ -0,0 +1,44 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2011 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.support.v4.widget.NestedScrollView xmlns:android="http://schemas.android.com/apk/res/android"
+    style="@style/RootLayoutPadding"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent">
+
+    <LinearLayout
+        android:layout_width="match_parent"
+        android:layout_height="match_parent"
+        android:orientation="vertical">
+        <TextView
+            android:id="@+id/test_instructions"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:padding="10dip"
+            android:textSize="18dip"/>
+
+        <Button
+            android:id="@+id/prepare_test_button"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"/>
+
+        <ListView
+            android:id="@+id/android:list"
+            android:layout_width="match_parent"
+            android:layout_height="200dip"/>
+
+        <include layout="@layout/pass_fail_buttons"/>
+    </LinearLayout>
+</android.support.v4.widget.NestedScrollView>
diff --git a/apps/CtsVerifier/res/layout-watch/requesting_bugreport_device_owner.xml b/apps/CtsVerifier/res/layout-watch/requesting_bugreport_device_owner.xml
new file mode 100644
index 0000000..4d4cf5d
--- /dev/null
+++ b/apps/CtsVerifier/res/layout-watch/requesting_bugreport_device_owner.xml
@@ -0,0 +1,46 @@
+<?xml version="2.0" encoding="utf-8"?>
+<!-- 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.
+-->
+<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
+    style="@style/RootLayoutPadding"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent"
+    android:orientation="vertical">
+    <LinearLayout
+        android:layout_width="match_parent"
+        android:layout_height="match_parent"
+        android:orientation="vertical">
+
+        <TextView
+            android:id="@+id/requesting_bugreport_device_owner_instructions"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="@string/device_owner_requesting_bugreport_tests_info"
+            android:textSize="18dip"/>
+
+        <Button
+            android:id="@+id/set_device_owner_button"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="@string/set_device_owner_button_label"/>
+
+        <ListView
+            android:id="@+id/android:list"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"/>
+
+        <include layout="@layout/pass_fail_buttons"/>
+    </LinearLayout>
+</ScrollView>
diff --git a/apps/CtsVerifier/res/layout/audio_dev_notify.xml b/apps/CtsVerifier/res/layout/audio_dev_notify.xml
index ceedf1c..aa6d3c4 100644
--- a/apps/CtsVerifier/res/layout/audio_dev_notify.xml
+++ b/apps/CtsVerifier/res/layout/audio_dev_notify.xml
@@ -18,12 +18,11 @@
         android:layout_width="match_parent"
         android:layout_height="match_parent"
         android:id="@+id/scrollView"
-    >
+        style="@style/RootLayoutPadding">
 
-<LinearLayout
+        <LinearLayout
         android:layout_width="match_parent"
         android:layout_height="wrap_content"
-        android:padding="20dp"
         android:orientation="vertical">
 
         <TextView
diff --git a/apps/CtsVerifier/res/layout/audio_frequency_line_activity.xml b/apps/CtsVerifier/res/layout/audio_frequency_line_activity.xml
index 6a755d5..41292d1 100644
--- a/apps/CtsVerifier/res/layout/audio_frequency_line_activity.xml
+++ b/apps/CtsVerifier/res/layout/audio_frequency_line_activity.xml
@@ -17,9 +17,8 @@
     xmlns:android="http://schemas.android.com/apk/res/android"
     android:layout_width="match_parent"
     android:layout_height="wrap_content"
-    android:padding="10dip"
     android:orientation="vertical"
->
+    style="@style/RootLayoutPadding">
     <ScrollView
         android:layout_width="match_parent"
         android:layout_height="match_parent"
@@ -131,4 +130,4 @@
         </LinearLayout>
     </ScrollView>
 
-</LinearLayout>
\ No newline at end of file
+</LinearLayout>
diff --git a/apps/CtsVerifier/res/layout/audio_frequency_mic_activity.xml b/apps/CtsVerifier/res/layout/audio_frequency_mic_activity.xml
index 8722f1d..bdf9e7c 100644
--- a/apps/CtsVerifier/res/layout/audio_frequency_mic_activity.xml
+++ b/apps/CtsVerifier/res/layout/audio_frequency_mic_activity.xml
@@ -17,9 +17,8 @@
     xmlns:android="http://schemas.android.com/apk/res/android"
     android:layout_width="match_parent"
     android:layout_height="wrap_content"
-    android:padding="10dip"
     android:orientation="vertical"
->
+    style="@style/RootLayoutPadding">
 
     <ScrollView
         android:layout_width="match_parent"
@@ -192,4 +191,4 @@
         </LinearLayout>
     </ScrollView>
 
-</LinearLayout>
\ No newline at end of file
+</LinearLayout>
diff --git a/apps/CtsVerifier/res/layout/audio_frequency_speaker_activity.xml b/apps/CtsVerifier/res/layout/audio_frequency_speaker_activity.xml
index 926a4c7..435f5a7 100644
--- a/apps/CtsVerifier/res/layout/audio_frequency_speaker_activity.xml
+++ b/apps/CtsVerifier/res/layout/audio_frequency_speaker_activity.xml
@@ -17,8 +17,8 @@
     xmlns:android="http://schemas.android.com/apk/res/android"
     android:layout_width="match_parent"
     android:layout_height="wrap_content"
-    android:padding="10dip"
-    android:orientation="vertical">
+    android:orientation="vertical"
+    style="@style/RootLayoutPadding">
 
     <ScrollView
        android:layout_width="match_parent"
@@ -97,4 +97,4 @@
         </LinearLayout>
       </ScrollView>
 
-</LinearLayout>
\ No newline at end of file
+</LinearLayout>
diff --git a/apps/CtsVerifier/res/layout/audio_frequency_unprocessed_activity.xml b/apps/CtsVerifier/res/layout/audio_frequency_unprocessed_activity.xml
index 142ffff..d02ef0b 100644
--- a/apps/CtsVerifier/res/layout/audio_frequency_unprocessed_activity.xml
+++ b/apps/CtsVerifier/res/layout/audio_frequency_unprocessed_activity.xml
@@ -10,9 +10,8 @@
     xmlns:android="http://schemas.android.com/apk/res/android"
     android:layout_width="match_parent"
     android:layout_height="wrap_content"
-    android:padding="10dip"
     android:orientation="vertical"
->
+    style="@style/RootLayoutPadding">
 
     <ScrollView
         android:layout_width="match_parent"
@@ -301,4 +300,4 @@
         </LinearLayout>
     </ScrollView>
 
-</LinearLayout>
\ No newline at end of file
+</LinearLayout>
diff --git a/apps/CtsVerifier/res/layout/audio_input_routingnotifications_test.xml b/apps/CtsVerifier/res/layout/audio_input_routingnotifications_test.xml
index 60a12ef..e09475c 100644
--- a/apps/CtsVerifier/res/layout/audio_input_routingnotifications_test.xml
+++ b/apps/CtsVerifier/res/layout/audio_input_routingnotifications_test.xml
@@ -18,12 +18,11 @@
         android:layout_width="match_parent"
         android:layout_height="match_parent"
         android:id="@+id/scrollView"
-    >
+        style="@style/RootLayoutPadding">
 
 <LinearLayout
         android:layout_width="match_parent"
         android:layout_height="wrap_content"
-        android:padding = "20dp"
         android:orientation="vertical">
 
         <TextView
diff --git a/apps/CtsVerifier/res/layout/audio_loopback_activity.xml b/apps/CtsVerifier/res/layout/audio_loopback_activity.xml
index 350f428..89d2e19 100644
--- a/apps/CtsVerifier/res/layout/audio_loopback_activity.xml
+++ b/apps/CtsVerifier/res/layout/audio_loopback_activity.xml
@@ -17,9 +17,8 @@
     xmlns:android="http://schemas.android.com/apk/res/android"
     android:layout_width="match_parent"
     android:layout_height="wrap_content"
-    android:padding="10dip"
     android:orientation="vertical"
->
+    style="@style/RootLayoutPadding">
 
     <ScrollView
         android:layout_width="match_parent"
@@ -151,4 +150,4 @@
         </LinearLayout>
     </ScrollView>
 
-</LinearLayout>
\ No newline at end of file
+</LinearLayout>
diff --git a/apps/CtsVerifier/res/layout/audio_output_routingnotifications_test.xml b/apps/CtsVerifier/res/layout/audio_output_routingnotifications_test.xml
index d039691..dc55e2a 100644
--- a/apps/CtsVerifier/res/layout/audio_output_routingnotifications_test.xml
+++ b/apps/CtsVerifier/res/layout/audio_output_routingnotifications_test.xml
@@ -18,12 +18,11 @@
         android:layout_width="match_parent"
         android:layout_height="match_parent"
         android:id="@+id/scrollView"
-    >
+        style="@style/RootLayoutPadding">
 
     <LinearLayout
         android:layout_width="match_parent"
         android:layout_height="wrap_content"
-        android:padding="20dp"
         android:orientation="vertical">
 
         <TextView
diff --git a/apps/CtsVerifier/res/layout/ble_advertiser_hardware_scan_filter.xml b/apps/CtsVerifier/res/layout/ble_advertiser_hardware_scan_filter.xml
index a545727..a20dea4 100644
--- a/apps/CtsVerifier/res/layout/ble_advertiser_hardware_scan_filter.xml
+++ b/apps/CtsVerifier/res/layout/ble_advertiser_hardware_scan_filter.xml
@@ -17,8 +17,7 @@
         android:layout_width="match_parent"
         android:layout_height="match_parent"
         android:orientation="vertical"
-        android:padding="10dip"
-        >
+        style="@style/RootLayoutPadding">
     <ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
             android:layout_width="match_parent"
             android:layout_height="wrap_content"
diff --git a/apps/CtsVerifier/res/layout/ble_advertiser_power_level.xml b/apps/CtsVerifier/res/layout/ble_advertiser_power_level.xml
index c8e0133..5a4ef24 100644
--- a/apps/CtsVerifier/res/layout/ble_advertiser_power_level.xml
+++ b/apps/CtsVerifier/res/layout/ble_advertiser_power_level.xml
@@ -17,8 +17,7 @@
         android:layout_width="match_parent"
         android:layout_height="match_parent"
         android:orientation="vertical"
-        android:padding="10dip"
-        >
+        style="@style/RootLayoutPadding">
     <ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
             android:layout_width="fill_parent"
             android:layout_height="wrap_content">
diff --git a/apps/CtsVerifier/res/layout/ble_advertiser_test.xml b/apps/CtsVerifier/res/layout/ble_advertiser_test.xml
index 7db2b4e..58b7e56 100644
--- a/apps/CtsVerifier/res/layout/ble_advertiser_test.xml
+++ b/apps/CtsVerifier/res/layout/ble_advertiser_test.xml
@@ -17,8 +17,7 @@
         android:layout_width="match_parent"
         android:layout_height="match_parent"
         android:orientation="vertical"
-        android:padding="10dip"
-        >
+        style="@style/RootLayoutPadding">
     <ListView android:id="@+id/ble_advertiser_tests"
             android:layout_height="fill_parent"
             android:layout_width="match_parent"
diff --git a/apps/CtsVerifier/res/layout/bt_device_picker.xml b/apps/CtsVerifier/res/layout/bt_device_picker.xml
index 48a4b43..3c0d4bc 100644
--- a/apps/CtsVerifier/res/layout/bt_device_picker.xml
+++ b/apps/CtsVerifier/res/layout/bt_device_picker.xml
@@ -1,5 +1,4 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2011 The Android Open Source Project
+<?xml version="1.0" encoding="utf-8"?><!-- Copyright (C) 2011 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,69 +13,78 @@
      limitations under the License.
 -->
 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    style="@style/RootLayoutPadding"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent"
+    android:orientation="vertical">
+
+    <ProgressBar
+        android:id="@+id/bt_progress_bar"
+        style="@android:style/Widget.DeviceDefault.ProgressBar.Horizontal"
         android:layout_width="match_parent"
-        android:layout_height="match_parent"
-        android:orientation="vertical"
-        >
+        android:layout_height="4dp"
+        android:indeterminate="true" />
 
-    <ProgressBar android:id="@+id/bt_progress_bar"
-            android:indeterminate="true"
-            android:layout_height="4dp"
-            android:layout_width="match_parent"
-            style="@android:style/Widget.DeviceDefault.ProgressBar.Horizontal"
-            />
-
-    <TextView android:layout_width="match_parent"
-            android:layout_height="wrap_content"
-            android:text="@string/bt_paired_devices"
-            style="?android:attr/listSeparatorTextViewStyle"
-            />
-    <FrameLayout android:orientation="vertical"
+    <ScrollView
+        android:layout_width="match_parent"
+        android:layout_height="match_parent">
+        <LinearLayout
             android:layout_width="match_parent"
             android:layout_height="match_parent"
-            android:layout_weight="1"
-            >
-        <ListView android:id="@+id/bt_paired_devices"
+            android:orientation="vertical">
+            <TextView
+                style="?android:attr/listSeparatorTextViewStyle"
                 android:layout_width="match_parent"
-                android:layout_height="match_parent"
-                />
-        <TextView android:id="@+id/bt_empty_paired_devices"
-                android:layout_width="match_parent"
-                android:layout_height="match_parent"
-                android:gravity="center"
-                android:text="@string/bt_no_devices"
-                android:visibility="gone"
-                />
-    </FrameLayout>
-
-    <TextView android:layout_width="match_parent"
-            android:layout_height="wrap_content"
-            android:text="@string/bt_new_devices"
-            style="?android:attr/listSeparatorTextViewStyle"
-            />
-    <FrameLayout android:orientation="vertical"
-            android:layout_width="match_parent"
-            android:layout_height="match_parent"
-            android:layout_weight="1"
-            >
-        <ListView android:id="@+id/bt_new_devices"
-                android:layout_width="match_parent"
-                android:layout_height="match_parent"
-                />
-        <TextView android:id="@+id/bt_empty_new_devices"
+                android:layout_height="wrap_content"
+                android:text="@string/bt_paired_devices" />
+            <FrameLayout
                 android:layout_width="match_parent"
                 android:layout_height="match_parent"
                 android:layout_weight="1"
-                android:gravity="center"
-                android:text="@string/bt_no_devices"
-                android:visibility="gone"
-                />
-    </FrameLayout>
-            
-    <Button android:id="@+id/bt_scan_button"
-            android:layout_width="match_parent"
-            android:layout_height="wrap_content"
-            android:drawableTop="@android:drawable/ic_menu_search"
-            android:text="@string/bt_scan"            
-            />
+                android:orientation="vertical">
+                <ListView
+                    android:id="@+id/bt_paired_devices"
+                    android:layout_width="match_parent"
+                    android:layout_height="match_parent" />
+                <TextView
+                    android:id="@+id/bt_empty_paired_devices"
+                    android:layout_width="match_parent"
+                    android:layout_height="match_parent"
+                    android:gravity="center"
+                    android:text="@string/bt_no_devices"
+                    android:visibility="gone" />
+            </FrameLayout>
+
+            <TextView
+                style="?android:attr/listSeparatorTextViewStyle"
+                android:layout_width="match_parent"
+                android:layout_height="wrap_content"
+                android:text="@string/bt_new_devices" />
+            <FrameLayout
+                android:layout_width="match_parent"
+                android:layout_height="match_parent"
+                android:layout_weight="1"
+                android:orientation="vertical">
+                <ListView
+                    android:id="@+id/bt_new_devices"
+                    android:layout_width="match_parent"
+                    android:layout_height="match_parent" />
+                <TextView
+                    android:id="@+id/bt_empty_new_devices"
+                    android:layout_width="match_parent"
+                    android:layout_height="match_parent"
+                    android:layout_weight="1"
+                    android:gravity="center"
+                    android:text="@string/bt_no_devices"
+                    android:visibility="gone" />
+            </FrameLayout>
+
+            <Button
+                android:id="@+id/bt_scan_button"
+                android:layout_width="match_parent"
+                android:layout_height="wrap_content"
+                android:drawableTop="@android:drawable/ic_menu_search"
+                android:text="@string/bt_scan" />
+        </LinearLayout>
+    </ScrollView>
 </LinearLayout>
diff --git a/apps/CtsVerifier/res/layout/bt_messages.xml b/apps/CtsVerifier/res/layout/bt_messages.xml
index 1504431..0d5100e 100644
--- a/apps/CtsVerifier/res/layout/bt_messages.xml
+++ b/apps/CtsVerifier/res/layout/bt_messages.xml
@@ -1,5 +1,4 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2011 The Android Open Source Project
+<?xml version="1.0" encoding="utf-8"?><!-- Copyright (C) 2011 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,69 +13,78 @@
      limitations under the License.
 -->
 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
-        android:orientation="vertical"
-        android:layout_width="match_parent"
-        android:layout_height="match_parent"
-        >
+    style="@style/RootLayoutPadding"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent"
+    android:orientation="vertical">
 
-    <ProgressBar android:id="@+id/bt_progress_bar"
-        android:indeterminate="true"
-        android:layout_height="4dp"
-        android:layout_width="match_parent"
+    <ProgressBar
+        android:id="@+id/bt_progress_bar"
         style="@android:style/Widget.DeviceDefault.ProgressBar.Horizontal"
-        />
+        android:layout_width="match_parent"
+        android:layout_height="4dp"
+        android:indeterminate="true" />
 
-    <TextView android:layout_width="match_parent"
-            android:layout_height="wrap_content"
-            android:text="@string/bt_sent_messages"
-            style="?android:attr/listSeparatorTextViewStyle"
-            />
-    <FrameLayout android:orientation="vertical"
+    <ScrollView
+        android:layout_width="match_parent"
+        android:layout_height="match_parent">
+        <LinearLayout
             android:layout_width="match_parent"
             android:layout_height="match_parent"
-            android:layout_weight="1"
-            >
-        <ListView android:id="@+id/bt_sent_messages"
-                android:layout_width="match_parent"
-                android:layout_height="match_parent"
-                />
-        <TextView android:id="@+id/bt_empty_sent_messages"
-                android:layout_width="match_parent"
-                android:layout_height="match_parent"
-                android:gravity="center"
-                android:visibility="gone"
-                />
-    </FrameLayout>
+            android:orientation="vertical">
 
-    <TextView android:layout_width="match_parent"
-            android:layout_height="wrap_content"
-            android:text="@string/bt_received_messages"
-            style="?android:attr/listSeparatorTextViewStyle"
-            />
-    <FrameLayout android:orientation="vertical"
-            android:layout_width="match_parent"
-            android:layout_height="match_parent"
-            android:layout_weight="1"
-            >
-        <ListView android:id="@+id/bt_received_messages"
+            <TextView
+                style="?android:attr/listSeparatorTextViewStyle"
+                android:layout_width="match_parent"
+                android:layout_height="wrap_content"
+                android:text="@string/bt_sent_messages" />
+            <FrameLayout
                 android:layout_width="match_parent"
                 android:layout_height="match_parent"
-                />
-        <TextView android:id="@+id/bt_empty_received_messages"
+                android:layout_weight="1"
+                android:orientation="vertical">
+                <ListView
+                    android:id="@+id/bt_sent_messages"
+                    android:layout_width="match_parent"
+                    android:layout_height="match_parent" />
+                <TextView
+                    android:id="@+id/bt_empty_sent_messages"
+                    android:layout_width="match_parent"
+                    android:layout_height="match_parent"
+                    android:gravity="center"
+                    android:visibility="gone" />
+            </FrameLayout>
+
+            <TextView
+                style="?android:attr/listSeparatorTextViewStyle"
+                android:layout_width="match_parent"
+                android:layout_height="wrap_content"
+                android:text="@string/bt_received_messages" />
+            <FrameLayout
                 android:layout_width="match_parent"
                 android:layout_height="match_parent"
-                android:gravity="center"
-                android:visibility="gone"
-                />
-    </FrameLayout>
+                android:layout_weight="1"
+                android:orientation="vertical">
+                <ListView
+                    android:id="@+id/bt_received_messages"
+                    android:layout_width="match_parent"
+                    android:layout_height="match_parent" />
+                <TextView
+                    android:id="@+id/bt_empty_received_messages"
+                    android:layout_width="match_parent"
+                    android:layout_height="match_parent"
+                    android:gravity="center"
+                    android:visibility="gone" />
+            </FrameLayout>
 
-    <Button android:id="@+id/bt_make_discoverable_button"
-            android:layout_width="match_parent"
-            android:layout_height="wrap_content"
-            android:drawableTop="@android:drawable/ic_menu_mylocation"
-            android:text="@string/bt_make_discoverable"
-            />
-            
-    <include layout="@layout/pass_fail_buttons" />
+            <Button
+                android:id="@+id/bt_make_discoverable_button"
+                android:layout_width="match_parent"
+                android:layout_height="wrap_content"
+                android:drawableTop="@android:drawable/ic_menu_mylocation"
+                android:text="@string/bt_make_discoverable" />
 
+            <include layout="@layout/pass_fail_buttons" />
+        </LinearLayout>
+    </ScrollView>
 </LinearLayout>
diff --git a/apps/CtsVerifier/res/layout/bt_toggle.xml b/apps/CtsVerifier/res/layout/bt_toggle.xml
index 71def84..e3c00b7 100644
--- a/apps/CtsVerifier/res/layout/bt_toggle.xml
+++ b/apps/CtsVerifier/res/layout/bt_toggle.xml
@@ -1,5 +1,4 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2011 The Android Open Source Project
+<?xml version="1.0" encoding="utf-8"?><!-- Copyright (C) 2011 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,31 +13,29 @@
      limitations under the License.
 -->
 <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent"
+    android:orientation="vertical">
+    <TextView
+        style="@style/InstructionsFont"
         android:layout_width="match_parent"
-        android:layout_height="match_parent"
-        android:orientation="vertical"
-        android:padding="10dip"
-        >
-    <TextView android:layout_width="match_parent"
-            android:layout_height="wrap_content"
-            android:layout_alignParentTop="true"
-            android:gravity="center"
-            android:text="@string/bt_toggle_instructions"
-            style="@style/InstructionsFont"
-            />
+        android:layout_height="wrap_content"
+        android:layout_alignParentTop="true"
+        android:gravity="center"
+        android:text="@string/bt_toggle_instructions" />
 
-    <ToggleButton android:id="@+id/bt_toggle_button"
-            android:layout_width="wrap_content"
-            android:layout_height="wrap_content"
-            android:layout_centerInParent="true"
-            android:textOn="@string/bt_disable_bluetooth"
-            android:textOff="@string/bt_enable_bluetooth"
-            />
-            
-    <include android:layout_width="match_parent"
-            android:layout_height="wrap_content"
-            android:layout_alignParentBottom="true"
-            layout="@layout/pass_fail_buttons" 
-            />
+    <ToggleButton
+        android:id="@+id/bt_toggle_button"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:layout_centerInParent="true"
+        android:textOff="@string/bt_enable_bluetooth"
+        android:textOn="@string/bt_disable_bluetooth" />
+
+    <include
+        layout="@layout/pass_fail_buttons"
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:layout_alignParentBottom="true" />
 
 </RelativeLayout>
diff --git a/apps/CtsVerifier/res/layout/ca_boot_notify.xml b/apps/CtsVerifier/res/layout/ca_boot_notify.xml
index f56209d..262c6ad 100644
--- a/apps/CtsVerifier/res/layout/ca_boot_notify.xml
+++ b/apps/CtsVerifier/res/layout/ca_boot_notify.xml
@@ -14,60 +14,59 @@
      See the License for the specific language governing permissions and
      limitations under the License.
 -->
-<com.android.cts.verifier.BoxInsetLayout xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:app="http://schemas.android.com/apk/res-auto"
-    android:layout_width="match_parent"
-    android:layout_height="match_parent">
-    <LinearLayout app:ctsv_layout_box="all"
-      android:orientation="vertical" android:layout_width="fill_parent"
-      android:layout_height="fill_parent">
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    style="@style/RootLayoutPadding"
+    android:layout_width="fill_parent"
+    android:layout_height="fill_parent"
+    android:orientation="vertical">
 
-      <ScrollView
+    <ScrollView
         android:layout_width="match_parent"
         android:layout_height="match_parent"
-        android:layout_alignParentTop="true" >
+        android:layout_alignParentTop="true">
 
         <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
-          android:orientation="vertical"
-          android:layout_width="fill_parent"
-          android:layout_height="wrap_content">
+            android:layout_width="fill_parent"
+            android:layout_height="wrap_content"
+            android:orientation="vertical">
 
-          <TextView
-              android:id="@+id/check_cert_desc"
-              android:layout_width="wrap_content"
-              android:layout_height="wrap_content"
-              android:text="@string/caboot_check_cert_installed"/>
+            <TextView
+                android:id="@+id/check_cert_desc"
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:text="@string/caboot_check_cert_installed" />
 
-          <Button android:id="@+id/check_creds"
-              android:layout_width="wrap_content"
-              android:layout_height="wrap_content"
-              android:text="@string/caboot_check_creds" />
+            <Button
+                android:id="@+id/check_creds"
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:text="@string/caboot_check_creds" />
 
-          <TextView
-              android:id="@+id/need_to_install_cert"
-              android:layout_width="wrap_content"
-              android:layout_height="wrap_content"
-              android:text="@string/caboot_if_not_installed"/>
+            <TextView
+                android:id="@+id/need_to_install_cert"
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:text="@string/caboot_if_not_installed" />
 
-          <Button android:id="@+id/install"
-              android:layout_width="wrap_content"
-              android:layout_height="wrap_content"
-              android:text="@string/caboot_install_cert" />
+            <Button
+                android:id="@+id/install"
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:text="@string/caboot_install_cert" />
 
-          <TextView
-              android:id="@+id/reboot"
-              android:layout_width="wrap_content"
-              android:layout_height="wrap_content"
-              android:text="@string/caboot_reboot_desc"/>
+            <TextView
+                android:id="@+id/reboot"
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:text="@string/caboot_reboot_desc" />
 
-          <TextView
-              android:id="@+id/after_reboot"
-              android:layout_width="wrap_content"
-              android:layout_height="wrap_content"
-              android:text="@string/caboot_after_boot"/>
+            <TextView
+                android:id="@+id/after_reboot"
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:text="@string/caboot_after_boot" />
 
-          <include layout="@layout/pass_fail_buttons" />
+            <include layout="@layout/pass_fail_buttons" />
         </LinearLayout>
-      </ScrollView>
-    </LinearLayout>
-</com.android.cts.verifier.BoxInsetLayout>
+    </ScrollView>
+</LinearLayout>
diff --git a/apps/CtsVerifier/res/layout/cainstallnotify_main.xml b/apps/CtsVerifier/res/layout/cainstallnotify_main.xml
index 0182a0f..b5feeea 100644
--- a/apps/CtsVerifier/res/layout/cainstallnotify_main.xml
+++ b/apps/CtsVerifier/res/layout/cainstallnotify_main.xml
@@ -1,5 +1,4 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
+<?xml version="1.0" encoding="utf-8"?><!--
      Copyright (C) 2013 The Android Open Source Project
 
      Licensed under the Apache License, Version 2.0 (the "License");
@@ -14,37 +13,31 @@
      See the License for the specific language governing permissions and
      limitations under the License.
 -->
-<com.android.cts.verifier.BoxInsetLayout xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:app="http://schemas.android.com/apk/res-auto"
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    style="@style/RootLayoutPadding"
     android:layout_width="match_parent"
-    android:layout_height="match_parent">
-    <LinearLayout xmlns:app="http://schemas.android.com/apk/res-auto"
+    android:layout_height="match_parent"
+    android:orientation="vertical">
+
+
+    <ScrollView
+        android:id="@+id/ca_notify_test_scroller"
         android:layout_width="match_parent"
-        android:layout_height="match_parent"
-        android:orientation="vertical"
-        android:padding="10dip" >
+        android:layout_height="0dp"
+        android:layout_weight="1"
+        android:orientation="vertical">
 
-        <ScrollView
-            android:id="@+id/ca_notify_test_scroller"
-            android:layout_width="match_parent"
-            android:layout_height="0dp"
-            android:layout_weight="1"
-            android:orientation="vertical"
-            android:padding="10dip" >
-
-            <LinearLayout
-                android:id="@+id/ca_notify_test_items"
-                android:layout_width="match_parent"
-                android:layout_height="wrap_content"
-                android:orientation="vertical" >
-            </LinearLayout>
-        </ScrollView>
-
-        <include
+        <LinearLayout
+            android:id="@+id/ca_notify_test_items"
             android:layout_width="match_parent"
             android:layout_height="wrap_content"
-            android:layout_weight="0"
-            layout="@layout/pass_fail_buttons" />
+            android:orientation="vertical" />
+    </ScrollView>
 
-    </LinearLayout>
-</com.android.cts.verifier.BoxInsetLayout>
+    <include
+        layout="@layout/pass_fail_buttons"
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:layout_weight="0" />
+
+</LinearLayout>
diff --git a/apps/CtsVerifier/res/layout/da_policy_main.xml b/apps/CtsVerifier/res/layout/da_policy_main.xml
index b80649e..70e277b 100644
--- a/apps/CtsVerifier/res/layout/da_policy_main.xml
+++ b/apps/CtsVerifier/res/layout/da_policy_main.xml
@@ -1,12 +1,9 @@
 <?xml version="1.0" encoding="utf-8"?>
 <!-- Copyright (C) 2011 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.
@@ -14,45 +11,40 @@
      limitations under the License.
 -->
 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
-        android:orientation="vertical"
-        android:layout_width="match_parent"
-        android:layout_height="match_parent"
-        >
-
+    android:orientation="vertical"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent"
+>
     <ListView android:id="@id/android:list"
-            android:layout_width="match_parent"
-            android:layout_height="wrap_content"
-            android:layout_weight="1"
-            />
-
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:layout_weight="1"
+    />
     <TextView android:id="@id/android:empty"
-            android:layout_gravity="center_vertical"
-            android:layout_width="match_parent"
+        android:layout_gravity="center_vertical"
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:layout_weight="1"
+        android:padding="10dip"
+        android:text="@string/da_no_policy"
+        android:textSize="18dip"
+    />
+    <LinearLayout android:orientation="horizontal"
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+    >
+        <Button android:id="@+id/generate_policy_button"
+            android:layout_width="1dip"
             android:layout_height="wrap_content"
             android:layout_weight="1"
-            android:padding="10dip"
-            android:text="@string/da_no_policy"
-            android:textSize="18dip"
-            />
-
-    <LinearLayout android:orientation="horizontal"
-            android:layout_width="match_parent"
-            android:layout_height="wrap_content"
-            >
-        <Button android:id="@+id/generate_policy_button"
-                android:layout_width="1dip"
-                android:layout_height="wrap_content"
-                android:layout_weight="1"
-                android:text="@string/da_generate_policy"
-                />
+            android:text="@string/da_generate_policy"
+        />
         <Button android:id="@+id/apply_policy_button"
-                android:layout_width="1dip"
-                android:layout_height="wrap_content"
-                android:layout_weight="1"
-                android:text="@string/da_apply_policy"
-                />
+            android:layout_width="1dip"
+            android:layout_height="wrap_content"
+            android:layout_weight="1"
+            android:text="@string/da_apply_policy"
+        />
     </LinearLayout>
-
-    <include layout="@layout/pass_fail_buttons" />
-
+    <include layout="@layout/pass_fail_buttons"/>
 </LinearLayout>
diff --git a/apps/CtsVerifier/res/layout/fs_main.xml b/apps/CtsVerifier/res/layout/fs_main.xml
index 40b74e9..90d48e5 100644
--- a/apps/CtsVerifier/res/layout/fs_main.xml
+++ b/apps/CtsVerifier/res/layout/fs_main.xml
@@ -1,5 +1,4 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2010 The Android Open Source Project
+<?xml version="1.0" encoding="utf-8"?><!-- Copyright (C) 2010 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,32 +12,30 @@
      See the License for the specific language governing permissions and
      limitations under the License.
 -->
-<com.android.cts.verifier.BoxInsetLayout xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:app="http://schemas.android.com/apk/res-auto"
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    style="@style/RootLayoutPadding"
     android:layout_width="match_parent"
-    android:layout_height="match_parent">
-    <LinearLayout app:ctsv_layout_box="all"
-             android:orientation="vertical"
-             android:layout_width="match_parent"
-             android:layout_height="match_parent">
+    android:layout_height="match_parent"
+    android:orientation="vertical">
 
-         <TextView android:id="@+id/fs_warnings"
-                   android:layout_width="wrap_content"
-                   android:layout_height="wrap_content"
-                   android:text="@string/empty"/>
+    <TextView
+        android:id="@+id/fs_warnings"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:text="@string/empty" />
 
-         <ListView android:id="@id/android:list"
-                   android:layout_width="match_parent"
-                   android:layout_height="match_parent"
-                   android:layout_weight="1"
-                   android:drawSelectorOnTop="false"/>
+    <ListView
+        android:id="@id/android:list"
+        android:layout_width="match_parent"
+        android:layout_height="match_parent"
+        android:layout_weight="1"
+        android:drawSelectorOnTop="false" />
 
-         <TextView android:id="@id/android:empty"
-                   android:layout_width="match_parent"
-                   android:layout_height="match_parent"
-                   android:text="@string/fs_no_data"/>
+    <TextView
+        android:id="@id/android:empty"
+        android:layout_width="match_parent"
+        android:layout_height="match_parent"
+        android:text="@string/fs_no_data" />
 
-        <include layout="@layout/pass_fail_buttons" />
-
-    </LinearLayout>
-</com.android.cts.verifier.BoxInsetLayout>
+    <include layout="@layout/pass_fail_buttons" />
+</LinearLayout>
diff --git a/apps/CtsVerifier/res/layout/hifi_ultrasound.xml b/apps/CtsVerifier/res/layout/hifi_ultrasound.xml
index 7d2de5a..8ad3fbd 100644
--- a/apps/CtsVerifier/res/layout/hifi_ultrasound.xml
+++ b/apps/CtsVerifier/res/layout/hifi_ultrasound.xml
@@ -14,17 +14,19 @@
      limitations under the License.
 -->
 
-<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
               android:layout_width="match_parent"
               android:layout_height="match_parent"
-              android:orientation="vertical">
+              style="@style/RootLayoutPadding">
+
+<LinearLayout
+      android:layout_width="match_parent"
+      android:layout_height="match_parent"
+      android:orientation="vertical">
 
   <TextView
       android:layout_width="match_parent"
-      android:layout_height="0dp"
-      android:layout_weight="7"
-      android:scrollbars="vertical"
-      android:gravity="bottom"
+      android:layout_height="wrap_content"
       android:id="@+id/info_text"/>
 
   <LinearLayout
@@ -46,6 +48,6 @@
         android:id="@+id/player_button"/>
   </LinearLayout>
 
-  <include layout="@layout/pass_fail_buttons" />
-
-</LinearLayout>
+      <include layout="@layout/pass_fail_buttons" />
+      </LinearLayout>
+</ScrollView>
diff --git a/apps/CtsVerifier/res/layout/intent_driven_test.xml b/apps/CtsVerifier/res/layout/intent_driven_test.xml
index dbb54c9..794a6d6 100644
--- a/apps/CtsVerifier/res/layout/intent_driven_test.xml
+++ b/apps/CtsVerifier/res/layout/intent_driven_test.xml
@@ -1,36 +1,32 @@
 <?xml version="1.0" encoding="utf-8"?>
 
-<com.android.cts.verifier.BoxInsetLayout xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:app="http://schemas.android.com/apk/res-auto"
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
     android:layout_width="match_parent"
-    android:layout_height="match_parent">
-    <LinearLayout app:ctsv_layout_box="all"
+    android:layout_height="match_parent"
+    android:orientation="vertical"
+    style="@style/RootLayoutPadding">
+
+    <ScrollView
         android:layout_width="match_parent"
-        android:layout_height="match_parent"
-        android:orientation="vertical">
-
-        <ScrollView
+        android:layout_height="0dp"
+        android:layout_weight="1">
+        <TextView android:id="@+id/info"
             android:layout_width="match_parent"
-            android:layout_height="0dp"
-            android:layout_weight="1">
-            <TextView android:id="@+id/info"
-                android:layout_width="match_parent"
-                android:layout_height="wrap_content"
-                android:textSize="18sp"
-                android:padding="5dp"
-                android:text="@string/dc_start_alarm_test_info"/>
-        </ScrollView>
+            android:layout_height="wrap_content"
+            android:textSize="18sp"
+            android:padding="5dp"
+            android:text="@string/dc_start_alarm_test_info"/>
+    </ScrollView>
 
-        <LinearLayout android:id="@+id/buttons"
-            android:orientation="horizontal"
-            android:layout_width="wrap_content"
-            android:layout_height="wrap_content"/>
+    <LinearLayout android:id="@+id/buttons"
+        android:orientation="horizontal"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"/>
 
-        <LinearLayout
-            android:layout_width="match_parent"
-            android:layout_height="wrap_content">
+    <LinearLayout
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content">
 
-            <include layout="@layout/pass_fail_buttons"/>
-        </LinearLayout>
+        <include layout="@layout/pass_fail_buttons"/>
     </LinearLayout>
-</com.android.cts.verifier.BoxInsetLayout>
+</LinearLayout>
diff --git a/apps/CtsVerifier/res/layout/js_charging.xml b/apps/CtsVerifier/res/layout/js_charging.xml
index e0986ba..306d02d 100644
--- a/apps/CtsVerifier/res/layout/js_charging.xml
+++ b/apps/CtsVerifier/res/layout/js_charging.xml
@@ -1,20 +1,36 @@
-<?xml version="1.0" encoding="utf-8"?>
-<com.android.cts.verifier.BoxInsetLayout xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:app="http://schemas.android.com/apk/res-auto"
+<?xml version="1.0" encoding="utf-8"?><!--
+     Copyright (C) 2016 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    style="@style/RootLayoutPadding"
     android:layout_width="match_parent"
-    android:layout_height="match_parent">
-    <ScrollView app:ctsv_layout_box="all"
+    android:layout_height="match_parent"
+    android:orientation="vertical">
+
+    <ScrollView
         android:layout_width="match_parent"
         android:layout_height="match_parent">
         <LinearLayout
-            android:orientation="vertical"
             android:layout_width="match_parent"
-            android:layout_height="match_parent">
+            android:layout_height="match_parent"
+            android:orientation="vertical">
             <TextView
                 android:layout_width="match_parent"
                 android:layout_height="wrap_content"
-                android:text="@string/js_test_description"
-                android:layout_margin="@dimen/js_padding"/>
+                android:layout_margin="@dimen/js_padding"
+                android:text="@string/js_test_description"/>
             <TextView
                 android:layout_width="match_parent"
                 android:layout_height="wrap_content"
@@ -26,9 +42,9 @@
                 android:layout_width="wrap_content"
                 android:layout_height="wrap_content"
                 android:layout_gravity="center"
-                android:text="@string/js_start_test_text"
+                android:enabled="false"
                 android:onClick="startTest"
-                android:enabled="false"/>
+                android:text="@string/js_start_test_text"/>
             <TextView
                 android:id="@+id/js_waiting_for_charging_text_view"
                 android:layout_width="match_parent"
@@ -55,14 +71,14 @@
             <LinearLayout
                 android:layout_width="wrap_content"
                 android:layout_height="wrap_content"
-                android:layout_marginTop="@dimen/js_padding"
-                android:layout_marginBottom="@dimen/js_padding">
+                android:layout_marginBottom="@dimen/js_padding"
+                android:layout_marginTop="@dimen/js_padding">
                 <ImageView
                     android:id="@+id/charging_on_test_image"
                     android:layout_width="wrap_content"
                     android:layout_height="wrap_content"
-                    android:src="@drawable/fs_indeterminate"
-                    android:layout_marginRight="@dimen/js_padding"/>
+                    android:layout_marginRight="@dimen/js_padding"
+                    android:src="@drawable/fs_indeterminate"/>
                 <TextView
                     android:layout_width="wrap_content"
                     android:layout_height="wrap_content"
@@ -78,21 +94,21 @@
             <LinearLayout
                 android:layout_width="wrap_content"
                 android:layout_height="wrap_content"
-                android:layout_marginTop="@dimen/js_padding"
-                android:layout_marginBottom="@dimen/js_padding">
+                android:layout_marginBottom="@dimen/js_padding"
+                android:layout_marginTop="@dimen/js_padding">
                 <ImageView
                     android:id="@+id/charging_off_test_image"
                     android:layout_width="wrap_content"
                     android:layout_height="wrap_content"
-                    android:src="@drawable/fs_indeterminate"
-                    android:layout_marginRight="@dimen/js_padding"/>
+                    android:layout_marginRight="@dimen/js_padding"
+                    android:src="@drawable/fs_indeterminate"/>
                 <TextView
                     android:layout_width="wrap_content"
                     android:layout_height="wrap_content"
                     android:text="@string/js_charging_off_test"
                     android:textSize="16dp"/>
             </LinearLayout>
-            <include layout="@layout/pass_fail_buttons" />
+            <include layout="@layout/pass_fail_buttons"/>
         </LinearLayout>
     </ScrollView>
-</com.android.cts.verifier.BoxInsetLayout>
+</LinearLayout>
diff --git a/apps/CtsVerifier/res/layout/js_connectivity.xml b/apps/CtsVerifier/res/layout/js_connectivity.xml
index 0fbd48f..923d19e 100644
--- a/apps/CtsVerifier/res/layout/js_connectivity.xml
+++ b/apps/CtsVerifier/res/layout/js_connectivity.xml
@@ -1,25 +1,40 @@
-<?xml version="1.0" encoding="utf-8"?>
-<com.android.cts.verifier.BoxInsetLayout xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:app="http://schemas.android.com/apk/res-auto"
+<?xml version="1.0" encoding="utf-8"?><!--
+     Copyright (C) 2016 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    style="@style/RootLayoutPadding"
     android:layout_width="match_parent"
-    android:layout_height="match_parent">
-    <ScrollView app:ctsv_layout_box="all"
+    android:layout_height="match_parent"
+    android:orientation="vertical">
+    <ScrollView
         android:layout_width="match_parent"
         android:layout_height="match_parent">
         <LinearLayout
-            android:orientation="vertical" android:layout_width="match_parent"
-            android:layout_height="match_parent">
+            android:layout_width="match_parent" android:layout_height="match_parent"
+            android:orientation="vertical">
             <TextView
                 android:layout_width="match_parent"
                 android:layout_height="wrap_content"
-                android:text="@string/js_test_description"
-                android:layout_margin="@dimen/js_padding"/>
+                android:layout_margin="@dimen/js_padding"
+                android:text="@string/js_test_description"/>
 
             <TextView
                 android:layout_width="match_parent"
                 android:layout_height="wrap_content"
-                android:text="@string/js_connectivity_description_1"
                 android:layout_margin="@dimen/js_padding"
+                android:text="@string/js_connectivity_description_1"
                 android:textStyle="bold"/>
 
             <Button
@@ -27,21 +42,21 @@
                 android:layout_width="wrap_content"
                 android:layout_height="wrap_content"
                 android:layout_gravity="center"
-                android:text="@string/js_start_test_text"
+                android:enabled="false"
                 android:onClick="startTest"
-                android:enabled="false"/>
+                android:text="@string/js_start_test_text"/>
 
             <LinearLayout
                 android:layout_width="wrap_content"
                 android:layout_height="wrap_content"
-                android:layout_marginTop="@dimen/js_padding"
-                android:layout_marginBottom="@dimen/js_padding">
+                android:layout_marginBottom="@dimen/js_padding"
+                android:layout_marginTop="@dimen/js_padding">
                 <ImageView
                     android:id="@+id/connectivity_off_test_unmetered_image"
                     android:layout_width="wrap_content"
                     android:layout_height="wrap_content"
-                    android:src="@drawable/fs_indeterminate"
-                    android:layout_marginRight="@dimen/js_padding"/>
+                    android:layout_marginRight="@dimen/js_padding"
+                    android:src="@drawable/fs_indeterminate"/>
                 <TextView
                     android:layout_width="wrap_content"
                     android:layout_height="wrap_content"
@@ -52,14 +67,14 @@
             <LinearLayout
                 android:layout_width="wrap_content"
                 android:layout_height="wrap_content"
-                android:layout_marginTop="@dimen/js_padding"
-                android:layout_marginBottom="@dimen/js_padding">
+                android:layout_marginBottom="@dimen/js_padding"
+                android:layout_marginTop="@dimen/js_padding">
                 <ImageView
                     android:id="@+id/connectivity_off_test_any_connectivity_image"
                     android:layout_width="wrap_content"
                     android:layout_height="wrap_content"
-                    android:src="@drawable/fs_indeterminate"
-                    android:layout_marginRight="@dimen/js_padding"/>
+                    android:layout_marginRight="@dimen/js_padding"
+                    android:src="@drawable/fs_indeterminate"/>
                 <TextView
                     android:layout_width="wrap_content"
                     android:layout_height="wrap_content"
@@ -70,14 +85,14 @@
             <LinearLayout
                 android:layout_width="wrap_content"
                 android:layout_height="wrap_content"
-                android:layout_marginTop="@dimen/js_padding"
-                android:layout_marginBottom="@dimen/js_padding">
+                android:layout_marginBottom="@dimen/js_padding"
+                android:layout_marginTop="@dimen/js_padding">
                 <ImageView
                     android:id="@+id/connectivity_off_test_no_connectivity_image"
                     android:layout_width="wrap_content"
                     android:layout_height="wrap_content"
-                    android:src="@drawable/fs_indeterminate"
-                    android:layout_marginRight="@dimen/js_padding"/>
+                    android:layout_marginRight="@dimen/js_padding"
+                    android:src="@drawable/fs_indeterminate"/>
                 <TextView
                     android:layout_width="wrap_content"
                     android:layout_height="wrap_content"
@@ -85,7 +100,7 @@
                     android:textSize="16dp"/>
             </LinearLayout>
 
-            <include layout="@layout/pass_fail_buttons" />
+            <include layout="@layout/pass_fail_buttons"/>
         </LinearLayout>
     </ScrollView>
-</com.android.cts.verifier.BoxInsetLayout>
+</LinearLayout>
diff --git a/apps/CtsVerifier/res/layout/js_idle.xml b/apps/CtsVerifier/res/layout/js_idle.xml
index 732f503..620ed97 100644
--- a/apps/CtsVerifier/res/layout/js_idle.xml
+++ b/apps/CtsVerifier/res/layout/js_idle.xml
@@ -1,48 +1,61 @@
-<?xml version="1.0" encoding="utf-8"?>
-<com.android.cts.verifier.BoxInsetLayout xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:app="http://schemas.android.com/apk/res-auto"
+<?xml version="1.0" encoding="utf-8"?><!--
+     Copyright (C) 2016 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
     android:layout_width="match_parent"
-    android:layout_height="match_parent">
-    <ScrollView app:ctsv_layout_box="all"
+    android:layout_height="match_parent"
+    android:orientation="vertical">
+    <ScrollView
         android:layout_width="match_parent"
         android:layout_height="match_parent">
-        <LinearLayout
-            android:orientation="vertical"
-            android:layout_width="match_parent"
-            android:layout_height="match_parent">
+        <LinearLayout android:layout_width="match_parent"
+            android:layout_height="match_parent"
+            android:orientation="vertical">
             <TextView
                 android:layout_width="match_parent"
                 android:layout_height="wrap_content"
-                android:text="@string/js_test_description"
-                android:layout_margin="@dimen/js_padding"/>
+                android:layout_margin="@dimen/js_padding"
+                android:text="@string/js_test_description"/>
             <Button
                 android:id="@+id/js_idle_start_test_button"
                 android:layout_width="wrap_content"
                 android:layout_height="wrap_content"
                 android:layout_gravity="center"
-                android:text="@string/js_start_test_text"
+                android:enabled="false"
                 android:onClick="startTest"
-                android:enabled="false"/>
+                android:text="@string/js_start_test_text"/>
             <TextView
                 android:id="@+id/js_idle_continue_instruction_view"
                 android:layout_width="match_parent"
                 android:layout_height="wrap_content"
-                android:text="@string/js_idle_continue_instruction"
                 android:layout_margin="@dimen/js_padding"
+                android:text="@string/js_idle_continue_instruction"
                 android:textStyle="bold"
                 android:visibility="gone"/>
 
             <LinearLayout
                 android:layout_width="wrap_content"
                 android:layout_height="wrap_content"
-                android:layout_marginTop="@dimen/js_padding"
-                android:layout_marginBottom="@dimen/js_padding">
+                android:layout_marginBottom="@dimen/js_padding"
+                android:layout_marginTop="@dimen/js_padding">
                 <ImageView
                     android:id="@+id/idle_off_test_image"
                     android:layout_width="wrap_content"
                     android:layout_height="wrap_content"
-                    android:src="@drawable/fs_indeterminate"
-                    android:layout_marginRight="@dimen/js_padding"/>
+                    android:layout_marginRight="@dimen/js_padding"
+                    android:src="@drawable/fs_indeterminate"/>
                 <TextView
                     android:layout_width="wrap_content"
                     android:layout_height="wrap_content"
@@ -52,21 +65,22 @@
             <LinearLayout
                 android:layout_width="wrap_content"
                 android:layout_height="wrap_content"
-                android:layout_marginTop="@dimen/js_padding"
-                android:layout_marginBottom="@dimen/js_padding">
+                android:layout_marginBottom="@dimen/js_padding"
+                android:layout_marginTop="@dimen/js_padding">
                 <ImageView
                     android:id="@+id/idle_on_test_image"
                     android:layout_width="wrap_content"
                     android:layout_height="wrap_content"
-                    android:src="@drawable/fs_indeterminate"
-                    android:layout_marginRight="@dimen/js_padding"/>
+                    android:layout_marginRight="@dimen/js_padding"
+                    android:src="@drawable/fs_indeterminate"/>
                 <TextView
                     android:layout_width="wrap_content"
                     android:layout_height="wrap_content"
                     android:text="@string/js_idle_item_idle_on"
                     android:textSize="16dp"/>
             </LinearLayout>
-            <include layout="@layout/pass_fail_buttons" />
+
+            <include layout="@layout/pass_fail_buttons"/>
         </LinearLayout>
     </ScrollView>
-</com.android.cts.verifier.BoxInsetLayout>
+</LinearLayout>
diff --git a/apps/CtsVerifier/res/layout/keychain_main.xml b/apps/CtsVerifier/res/layout/keychain_main.xml
index b134908..e31cac8 100644
--- a/apps/CtsVerifier/res/layout/keychain_main.xml
+++ b/apps/CtsVerifier/res/layout/keychain_main.xml
@@ -1,5 +1,4 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
+<?xml version="1.0" encoding="utf-8"?><!--
      Copyright (C) 2015 The Android Open Source Project
 
      Licensed under the Apache License, Version 2.0 (the "License");
@@ -14,23 +13,22 @@
      See the License for the specific language governing permissions and
      limitations under the License.
 -->
-<com.android.cts.verifier.BoxInsetLayout
-    xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:app="http://schemas.android.com/apk/res-auto"
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    style="@style/RootLayoutPadding"
     android:layout_width="match_parent"
-    android:layout_height="match_parent">
+    android:layout_height="match_parent"
+    android:orientation="vertical">
 
-    <LinearLayout xmlns:app="http://schemas.android.com/apk/res-auto"
+    <ScrollView
         android:layout_width="match_parent"
-        android:layout_height="match_parent"
-        android:orientation="vertical"
-        android:padding="10dip">
+        android:layout_height="0dp"
+        android:layout_weight="1"
+        android:fillViewport="true">
 
-        <ScrollView
+        <LinearLayout
             android:layout_width="match_parent"
-            android:layout_height="0dp"
-            android:layout_weight="1"
-            android:fillViewport="true">
+            android:layout_height="match_parent"
+            android:orientation="vertical">
 
             <LinearLayout
                 android:id="@+id/test_messages"
@@ -53,43 +51,43 @@
                     android:orientation="vertical" />
 
             </LinearLayout>
-        </ScrollView>
 
-        <LinearLayout
-            android:id="@+id/action_buttons"
-            android:layout_width="match_parent"
-            android:layout_height="wrap_content"
-            android:layout_weight="0"
-            android:orientation="horizontal">
+            <LinearLayout
+                android:id="@+id/action_buttons"
+                android:layout_width="match_parent"
+                android:layout_height="wrap_content"
+                android:layout_weight="0"
+                android:orientation="horizontal">
 
-            <Button
-                android:id="@+id/action_reset"
-                android:text="@string/keychain_reset"
-                android:layout_weight="1"
-                android:layout_width="0dp"
-                android:layout_height="wrap_content" />
+                <Button
+                    android:id="@+id/action_reset"
+                    android:layout_width="0dp"
+                    android:layout_height="wrap_content"
+                    android:layout_weight="1"
+                    android:text="@string/keychain_reset" />
 
-            <Button
-                android:id="@+id/action_skip"
-                android:text="@string/keychain_skip"
-                android:layout_weight="1"
-                android:layout_width="0dp"
-                android:layout_height="wrap_content" />
+                <Button
+                    android:id="@+id/action_skip"
+                    android:layout_width="0dp"
+                    android:layout_height="wrap_content"
+                    android:layout_weight="1"
+                    android:text="@string/keychain_skip" />
 
-            <Button
-                android:id="@+id/action_next"
-                android:text="@string/next_button_text"
-                android:layout_weight="1"
-                android:layout_width="0dp"
-                android:layout_height="wrap_content" />
+                <Button
+                    android:id="@+id/action_next"
+                    android:layout_width="0dp"
+                    android:layout_height="wrap_content"
+                    android:layout_weight="1"
+                    android:text="@string/next_button_text" />
 
+            </LinearLayout>
         </LinearLayout>
+    </ScrollView>
 
-        <include
-            android:layout_width="match_parent"
-            android:layout_height="wrap_content"
-            android:layout_weight="0"
-            layout="@layout/pass_fail_buttons" />
+    <include
+        layout="@layout/pass_fail_buttons"
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:layout_weight="0" />
 
-    </LinearLayout>
-</com.android.cts.verifier.BoxInsetLayout>
+</LinearLayout>
diff --git a/apps/CtsVerifier/res/layout/list_content.xml b/apps/CtsVerifier/res/layout/list_content.xml
index e7de596..decef55 100644
--- a/apps/CtsVerifier/res/layout/list_content.xml
+++ b/apps/CtsVerifier/res/layout/list_content.xml
@@ -15,14 +15,12 @@
   ~ See the License for the specific language governing permissions and
   ~ limitations under the License
   -->
-<com.android.cts.verifier.BoxInsetLayout xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:app="http://schemas.android.com/apk/res-auto"
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
     android:layout_width="match_parent"
-    android:layout_height="match_parent">
-
-    <ListView
-        android:id="@android:id/list"
-        app:ctsv_layout_box="all"
-        android:layout_width="match_parent"
-        android:layout_height="match_parent" />
-</com.android.cts.verifier.BoxInsetLayout>
+    android:layout_height="match_parent"
+    style="@style/RootLayoutPadding">
+        <ListView
+            android:id="@android:id/list"
+            android:layout_width="match_parent"
+            android:layout_height="match_parent" />
+</LinearLayout>
diff --git a/apps/CtsVerifier/res/layout/location_mode_main.xml b/apps/CtsVerifier/res/layout/location_mode_main.xml
index 58ac069..a9206fa 100644
--- a/apps/CtsVerifier/res/layout/location_mode_main.xml
+++ b/apps/CtsVerifier/res/layout/location_mode_main.xml
@@ -1,5 +1,4 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
+<?xml version="1.0" encoding="utf-8"?><!--
      Copyright (C) 2013 The Android Open Source Project
 
      Licensed under the Apache License, Version 2.0 (the "License");
@@ -14,37 +13,31 @@
      See the License for the specific language governing permissions and
      limitations under the License.
 -->
-<com.android.cts.verifier.BoxInsetLayout xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:app="http://schemas.android.com/apk/res-auto"
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    style="@style/RootLayoutPadding"
     android:layout_width="match_parent"
-    android:layout_height="match_parent">
-    <LinearLayout app:ctsv_layout_box="all"
+    android:layout_height="match_parent"
+    android:orientation="vertical">
+    <LinearLayout
         android:layout_width="match_parent"
         android:layout_height="match_parent"
-        android:orientation="vertical"
-        android:padding="10dip" >
+        android:orientation="vertical">
 
         <ScrollView
             android:id="@+id/test_scroller"
             android:layout_width="match_parent"
             android:layout_height="0dp"
             android:layout_weight="1"
-            android:orientation="vertical"
-            android:padding="10dip" >
-
+            android:orientation="vertical">
             <LinearLayout
                 android:id="@+id/test_items"
                 android:layout_width="match_parent"
                 android:layout_height="wrap_content"
-                android:orientation="vertical" >
+                android:orientation="vertical">
             </LinearLayout>
         </ScrollView>
 
-        <include
-            android:layout_width="match_parent"
-            android:layout_height="wrap_content"
-            android:layout_weight="0"
-            layout="@layout/pass_fail_buttons" />
+        <include layout="@layout/pass_fail_buttons"/>
 
     </LinearLayout>
-</com.android.cts.verifier.BoxInsetLayout>
+</LinearLayout>
diff --git a/apps/CtsVerifier/res/layout/network_screen_off.xml b/apps/CtsVerifier/res/layout/network_screen_off.xml
index 5a2446d..c0eeee8 100644
--- a/apps/CtsVerifier/res/layout/network_screen_off.xml
+++ b/apps/CtsVerifier/res/layout/network_screen_off.xml
@@ -15,7 +15,8 @@
 -->
 <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
         android:layout_width="match_parent"
-        android:layout_height="match_parent">
+        android:layout_height="match_parent"
+        style="@style/RootLayoutPadding">
 
     <Button android:id="@+id/start_btn"
             android:text="@string/network_screen_off_test_start"
diff --git a/apps/CtsVerifier/res/layout/nls_main.xml b/apps/CtsVerifier/res/layout/nls_main.xml
index 0ee4cbf..24dfb91 100644
--- a/apps/CtsVerifier/res/layout/nls_main.xml
+++ b/apps/CtsVerifier/res/layout/nls_main.xml
@@ -18,15 +18,14 @@
     android:layout_width="match_parent"
     android:layout_height="match_parent"
     android:orientation="vertical"
-    android:padding="10dip" >
+    style="@style/RootLayoutPadding">
 
     <ScrollView
         android:id="@+id/nls_test_scroller"
         android:layout_width="match_parent"
         android:layout_height="0dp"
         android:layout_weight="1"
-        android:orientation="vertical"
-        android:padding="10dip" >
+        android:orientation="vertical">
 
         <LinearLayout
             android:id="@+id/nls_test_items"
diff --git a/apps/CtsVerifier/res/layout/pa_main.xml b/apps/CtsVerifier/res/layout/pa_main.xml
index b748123..a08daf0 100644
--- a/apps/CtsVerifier/res/layout/pa_main.xml
+++ b/apps/CtsVerifier/res/layout/pa_main.xml
@@ -1,5 +1,4 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2014 The Android Open Source Project
+<?xml version="1.0" encoding="utf-8"?><!-- 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.
@@ -13,24 +12,19 @@
      See the License for the specific language governing permissions and
      limitations under the License.
 -->
-<com.android.cts.verifier.BoxInsetLayout xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:app="http://schemas.android.com/apk/res-auto"
+<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
     android:layout_width="match_parent"
     android:layout_height="match_parent">
-    <RelativeLayout app:ctsv_layout_box="all"
+
+    <include
+        android:id="@+id/pass_fail_buttons"
+        layout="@layout/pass_fail_buttons"
+        android:layout_gravity="top" />
+
+    <TextureView
+        android:id="@+id/texture_view"
         android:layout_width="match_parent"
-        android:layout_height="match_parent" >
+        android:layout_height="match_parent"
+        android:layout_below="@id/pass_fail_buttons" />
 
-        <include
-            android:id="@+id/pass_fail_buttons"
-            android:layout_gravity="top"
-            layout="@layout/pass_fail_buttons" />
-
-        <TextureView
-            android:id="@+id/texture_view"
-            android:layout_width="match_parent"
-            android:layout_height="match_parent"
-            android:layout_below="@id/pass_fail_buttons" />
-
-    </RelativeLayout>
-</com.android.cts.verifier.BoxInsetLayout>
+</RelativeLayout>
diff --git a/apps/CtsVerifier/res/layout/pass_fail_list.xml b/apps/CtsVerifier/res/layout/pass_fail_list.xml
index 575e630..20e3c3b 100644
--- a/apps/CtsVerifier/res/layout/pass_fail_list.xml
+++ b/apps/CtsVerifier/res/layout/pass_fail_list.xml
@@ -1,5 +1,4 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2011 The Android Open Source Project
+<?xml version="1.0" encoding="utf-8"?><!-- Copyright (C) 2011 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,30 +12,23 @@
      See the License for the specific language governing permissions and
      limitations under the License.
 -->
-<com.android.cts.verifier.BoxInsetLayout xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:app="http://schemas.android.com/apk/res-auto"
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    style="@style/RootLayoutPadding"
     android:layout_width="match_parent"
-    android:layout_height="match_parent">
+    android:layout_height="match_parent"
+    android:orientation="vertical">
 
-    <LinearLayout app:ctsv_layout_box="all"
-            android:orientation="vertical"
-            android:layout_width="match_parent"
-            android:layout_height="match_parent"
-            >
+    <ListView
+        android:id="@+id/android:list"
+        android:layout_width="match_parent"
+        android:layout_height="match_parent"
+        android:layout_weight="1" />
 
-        <ListView android:id="@id/android:list"
-                android:layout_width="match_parent"
-                android:layout_height="match_parent"
-                android:layout_weight="1"
-                />
+    <TextView
+        android:id="@+id/android:empty"
+        android:layout_width="match_parent"
+        android:layout_height="match_parent"
+        android:layout_weight="1" />
 
-        <TextView android:id="@id/android:empty"
-                android:layout_width="match_parent"
-                android:layout_height="match_parent"
-                android:layout_weight="1"
-                />
-
-        <include layout="@layout/pass_fail_buttons" />
-
-    </LinearLayout>
-</com.android.cts.verifier.BoxInsetLayout>
+    <include layout="@layout/pass_fail_buttons" />
+</LinearLayout>
diff --git a/apps/CtsVerifier/res/layout/pass_fail_text.xml b/apps/CtsVerifier/res/layout/pass_fail_text.xml
index e6b6a73..99d0b7a 100644
--- a/apps/CtsVerifier/res/layout/pass_fail_text.xml
+++ b/apps/CtsVerifier/res/layout/pass_fail_text.xml
@@ -1,5 +1,4 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2011 The Android Open Source Project
+<?xml version="1.0" encoding="utf-8"?><!-- Copyright (C) 2011 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,21 +13,21 @@
      limitations under the License.
 -->
 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
-        android:orientation="vertical"
-        android:layout_width="match_parent"
-        android:layout_height="match_parent"
-        >
+    style="@style/RootLayoutPadding"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent"
+    android:orientation="vertical">
 
-    <ScrollView android:id="@+id/scroll"
+    <ScrollView
+        android:id="@+id/scroll"
+        android:layout_width="match_parent"
+        android:layout_height="0dip"
+        android:layout_weight="1">
+        <TextView
+            android:id="@+id/text"
+            style="@style/InstructionsFont"
             android:layout_width="match_parent"
-            android:layout_height="0dip"
-            android:layout_weight="1"
-            >
-        <TextView android:id="@+id/text"
-                android:layout_width="match_parent"
-                android:layout_height="wrap_content"
-                style="@style/InstructionsFont"
-                />
+            android:layout_height="wrap_content" />
     </ScrollView>
 
     <include layout="@layout/pass_fail_buttons" />
diff --git a/apps/CtsVerifier/res/layout/pla_list.xml b/apps/CtsVerifier/res/layout/pla_list.xml
index 0973136..83dac69 100644
--- a/apps/CtsVerifier/res/layout/pla_list.xml
+++ b/apps/CtsVerifier/res/layout/pla_list.xml
@@ -1,5 +1,4 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2014 The Android Open Source Project
+<?xml version="1.0" encoding="utf-8"?><!-- 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.
@@ -14,14 +13,14 @@
      limitations under the License.
 -->
 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    style="@style/RootLayoutPadding"
     android:layout_width="fill_parent"
     android:layout_height="fill_parent"
-    android:orientation="vertical" >
+    android:orientation="vertical">
 
     <ListView
         android:id="@+id/pla_list"
         android:layout_width="match_parent"
-        android:layout_height="wrap_content" >
-    </ListView>
+        android:layout_height="wrap_content" />
 
 </LinearLayout>
\ No newline at end of file
diff --git a/apps/CtsVerifier/res/layout/poa_main.xml b/apps/CtsVerifier/res/layout/poa_main.xml
index b3c5588..f43b458 100644
--- a/apps/CtsVerifier/res/layout/poa_main.xml
+++ b/apps/CtsVerifier/res/layout/poa_main.xml
@@ -1,5 +1,4 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2014 The Android Open Source Project
+<?xml version="1.0" encoding="utf-8"?><!-- 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.
@@ -13,22 +12,22 @@
      See the License for the specific language governing permissions and
      limitations under the License.
 -->
-<com.android.cts.verifier.BoxInsetLayout xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:app="http://schemas.android.com/apk/res-auto"
-    android:layout_width="match_parent"
-    android:layout_height="match_parent">
-    <LinearLayout app:ctsv_layout_box="all"
-        android:layout_width="fill_parent"
-        android:layout_height="fill_parent"
-        android:orientation="vertical" >
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    style="@style/RootLayoutPadding"
+    android:layout_width="fill_parent"
+    android:layout_height="fill_parent"
+    android:orientation="vertical">
 
-        <include layout="@layout/pass_fail_buttons" />
+    <include layout="@layout/pass_fail_buttons" />
 
+    <ScrollView
+        android:layout_width="match_parent"
+        android:layout_height="match_parent">
         <TextView
             android:id="@+id/poa_status_text"
             android:layout_width="match_parent"
             android:layout_height="match_parent"
             android:textAppearance="@style/InstructionsFont" />
+    </ScrollView>
 
-    </LinearLayout>
-</com.android.cts.verifier.BoxInsetLayout>
+</LinearLayout>
diff --git a/apps/CtsVerifier/res/layout/poa_touch.xml b/apps/CtsVerifier/res/layout/poa_touch.xml
index 0085227..cba7e98 100644
--- a/apps/CtsVerifier/res/layout/poa_touch.xml
+++ b/apps/CtsVerifier/res/layout/poa_touch.xml
@@ -1,5 +1,4 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2014 The Android Open Source Project
+<?xml version="1.0" encoding="utf-8"?><!-- 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.
@@ -15,12 +14,12 @@
 -->
 <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
     android:layout_width="match_parent"
-    android:layout_height="match_parent" >
+    android:layout_height="match_parent">
     <com.android.cts.verifier.projection.offscreen.ColorChangeOnKeyView
         android:id="@+id/multi_touch_view"
-        android:focusable="true"
-        android:focusableInTouchMode="true"
         android:layout_width="match_parent"
-        android:layout_height="match_parent" />
+        android:layout_height="match_parent"
+        android:focusable="true"
+        android:focusableInTouchMode="true" />
 
 </RelativeLayout>
diff --git a/apps/CtsVerifier/res/layout/positive_device_owner.xml b/apps/CtsVerifier/res/layout/positive_device_owner.xml
index 2ffb463..fa437de 100644
--- a/apps/CtsVerifier/res/layout/positive_device_owner.xml
+++ b/apps/CtsVerifier/res/layout/positive_device_owner.xml
@@ -1,5 +1,4 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2015 The Android Open Source Project
+<?xml version="1.0" encoding="utf-8"?><!-- 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.
@@ -14,36 +13,38 @@
      limitations under the License.
 -->
 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
-        android:orientation="vertical"
-        android:layout_width="match_parent"
-        android:layout_height="match_parent"
-        >
+    style="@style/RootLayoutPadding"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent"
+    android:orientation="vertical">
 
     <ScrollView
+        android:layout_width="match_parent"
+        android:layout_height="match_parent">
+        <LinearLayout
             android:layout_width="match_parent"
-            android:layout_height="150dp"
-            android:layout_weight="2">
-        <TextView
+            android:layout_height="match_parent"
+            android:orientation="vertical">
+
+            <TextView
                 android:id="@+id/positive_device_owner_instructions"
                 android:layout_width="match_parent"
                 android:layout_height="wrap_content"
-                android:padding="10dip"
                 android:text="@string/device_owner_positive_tests_instructions"
                 android:textSize="18dip" />
+
+            <Button
+                android:id="@+id/set_device_owner_button"
+                android:layout_width="match_parent"
+                android:layout_height="wrap_content"
+                android:text="@string/set_device_owner_button_label" />
+
+            <ListView
+                android:id="@+id/android:list"
+                android:layout_width="match_parent"
+                android:layout_height="wrap_content" />
+
+            <include layout="@layout/pass_fail_buttons" />
+        </LinearLayout>
     </ScrollView>
-
-    <Button
-        android:id="@+id/set_device_owner_button"
-        android:layout_width="204dp"
-        android:layout_height="wrap_content"
-        android:text="@string/set_device_owner_button_label" />
-
-    <ListView
-        android:id="@+id/android:list"
-        android:layout_width="match_parent"
-        android:layout_height="wrap_content"
-        android:layout_weight="3" />
-
-    <include layout="@layout/pass_fail_buttons" />
-
 </LinearLayout>
\ No newline at end of file
diff --git a/apps/CtsVerifier/res/layout/provisioning_byod.xml b/apps/CtsVerifier/res/layout/provisioning_byod.xml
index 54b5121..227d8d8 100644
--- a/apps/CtsVerifier/res/layout/provisioning_byod.xml
+++ b/apps/CtsVerifier/res/layout/provisioning_byod.xml
@@ -1,12 +1,8 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2011 The Android Open Source Project
-
+<?xml version="1.0" encoding="utf-8"?><!-- Copyright (C) 2011 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.
@@ -14,34 +10,28 @@
      limitations under the License.
 -->
 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
-        android:orientation="vertical"
-        android:layout_width="match_parent"
-        android:layout_height="match_parent"
-        >
-
+    android:layout_width="match_parent"
+    android:layout_height="match_parent"
+    android:orientation="vertical">
     <ScrollView
-            android:layout_width="match_parent"
-            android:layout_height="150dp"
-            android:layout_weight="2">
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:layout_weight="2">
         <TextView
-                android:id="@+id/test_instructions"
-                android:layout_width="match_parent"
-                android:layout_height="wrap_content"
-                android:padding="10dip"
-                android:textSize="18dip" />
+            android:id="@+id/test_instructions"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:padding="10dip"
+            android:textSize="18dip"/>
     </ScrollView>
-
     <Button
         android:id="@+id/prepare_test_button"
-        android:layout_width="204dp"
-        android:layout_height="wrap_content" />
-
+        android:layout_width="204dip"
+        android:layout_height="wrap_content"/>
     <ListView
         android:id="@+id/android:list"
         android:layout_width="match_parent"
         android:layout_height="wrap_content"
-        android:layout_weight="3" />
-
-    <include layout="@layout/pass_fail_buttons" />
-
-</LinearLayout>
\ No newline at end of file
+        android:layout_weight="3"/>
+    <include layout="@layout/pass_fail_buttons"/>
+</LinearLayout>
diff --git a/apps/CtsVerifier/res/layout/pwa_widgets.xml b/apps/CtsVerifier/res/layout/pwa_widgets.xml
index 7ead0cb..cb611b9 100644
--- a/apps/CtsVerifier/res/layout/pwa_widgets.xml
+++ b/apps/CtsVerifier/res/layout/pwa_widgets.xml
@@ -1,5 +1,4 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2014 The Android Open Source Project
+<?xml version="1.0" encoding="utf-8"?><!-- 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.
@@ -13,50 +12,50 @@
      See the License for the specific language governing permissions and
      limitations under the License.
 -->
-<com.android.cts.verifier.BoxInsetLayout xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:app="http://schemas.android.com/apk/res-auto"
+<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
     android:layout_width="match_parent"
     android:layout_height="match_parent">
 
-     <TextureView
-         app:ctsv_layout_box="all"
-         android:id="@+id/texture_view"
-         android:layout_width="match_parent"
-         android:layout_height="match_parent" />
+    <LinearLayout
+        android:id="@+id/test_controls"
+        android:layout_width="fill_parent"
+        android:layout_height="wrap_content"
+        android:orientation="vertical"
+        android:layout_gravity="top">
 
-     <LinearLayout
-         app:ctsv_layout_box="all"
-         android:layout_width="fill_parent"
-         android:layout_height="wrap_content"
-         android:orientation="vertical" >
+        <LinearLayout
+            android:layout_width="match_parent"
+            android:layout_height="match_parent">
 
-         <LinearLayout
-             android:layout_width="match_parent"
-             android:layout_height="match_parent" >
+            <include layout="@layout/pass_fail_buttons" />
+        </LinearLayout>
 
-             <include layout="@layout/pass_fail_buttons" />
-         </LinearLayout>
+        <LinearLayout
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:orientation="horizontal">
 
-         <LinearLayout
-             android:layout_width="match_parent"
-             android:layout_height="wrap_content"
-             android:orientation="horizontal" >
+            <Button
+                android:id="@+id/up_button"
+                android:layout_width="match_parent"
+                android:layout_height="wrap_content"
+                android:layout_weight="1"
+                android:text="@string/pwa_button_up" />
 
-             <Button
-                 android:id="@+id/up_button"
-                 android:layout_width="match_parent"
-                 android:layout_height="wrap_content"
-                 android:layout_weight="1"
-                 android:text="@string/pwa_button_up" />
+            <Button
+                android:id="@+id/down_button"
+                android:layout_width="match_parent"
+                android:layout_height="wrap_content"
+                android:layout_weight="1"
+                android:text="@string/pwa_button_down" />
 
-             <Button
-                 android:id="@+id/down_button"
-                 android:layout_width="match_parent"
-                 android:layout_height="wrap_content"
-                 android:layout_weight="1"
-                 android:text="@string/pwa_button_down" />
+        </LinearLayout>
+    </LinearLayout>
 
-         </LinearLayout>
-     </LinearLayout>
+    <TextureView
+        android:id="@+id/texture_view"
+        android:layout_width="match_parent"
+        android:layout_height="match_parent"
+        android:layout_below="@id/test_controls" />
 
-</com.android.cts.verifier.BoxInsetLayout>
+</RelativeLayout>
diff --git a/apps/CtsVerifier/res/layout/requesting_bugreport_device_owner.xml b/apps/CtsVerifier/res/layout/requesting_bugreport_device_owner.xml
index b2955ec..f3320c6 100644
--- a/apps/CtsVerifier/res/layout/requesting_bugreport_device_owner.xml
+++ b/apps/CtsVerifier/res/layout/requesting_bugreport_device_owner.xml
@@ -1,12 +1,9 @@
 <?xml version="1.0" encoding="utf-8"?>
 <!-- Copyright (C) 2016 The Android Open Source Project
-
      Licensed under the Apache License, Version 2.0 (the "License");
      you may not use this file except in compliance with the License.
      You may obtain a copy of the License at
-
           http://www.apache.org/licenses/LICENSE-2.0
-
      Unless required by applicable law or agreed to in writing, software
      distributed under the License is distributed on an "AS IS" BASIS,
      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@@ -14,36 +11,31 @@
      limitations under the License.
 -->
 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
-        android:orientation="vertical"
-        android:layout_width="match_parent"
-        android:layout_height="match_parent"
-        >
-
+    android:orientation="vertical"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent"
+>
     <ScrollView
-            android:layout_width="match_parent"
-            android:layout_height="100dp"
-            android:layout_weight="2">
+        android:layout_width="match_parent"
+        android:layout_height="100dp"
+        android:layout_weight="2">
         <TextView
-                android:id="@+id/requesting_bugreport_device_owner_instructions"
-                android:layout_width="match_parent"
-                android:layout_height="wrap_content"
-                android:padding="10dip"
-                android:text="@string/device_owner_requesting_bugreport_tests_info"
-                android:textSize="18dip" />
+            android:id="@+id/requesting_bugreport_device_owner_instructions"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:padding="10dip"
+            android:text="@string/device_owner_requesting_bugreport_tests_info"
+            android:textSize="18dip" />
     </ScrollView>
-
     <Button
         android:id="@+id/set_device_owner_button"
         android:layout_width="204dp"
         android:layout_height="wrap_content"
         android:text="@string/set_device_owner_button_label" />
-
     <ListView
         android:id="@+id/android:list"
         android:layout_width="match_parent"
         android:layout_height="wrap_content"
         android:layout_weight="3" />
-
     <include layout="@layout/pass_fail_buttons" />
-
 </LinearLayout>
diff --git a/apps/CtsVerifier/res/layout/snsr_hrm.xml b/apps/CtsVerifier/res/layout/snsr_hrm.xml
index 506ba9f..4c6b6ff 100644
--- a/apps/CtsVerifier/res/layout/snsr_hrm.xml
+++ b/apps/CtsVerifier/res/layout/snsr_hrm.xml
@@ -1,5 +1,4 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
+<?xml version="1.0" encoding="utf-8"?><!--
   ~ Copyright (C) 2014 The Android Open Source Project
   ~
   ~ Licensed under the Apache License, Version 2.0 (the "License");
@@ -15,43 +14,45 @@
   ~ limitations under the License
   -->
 <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    style="@style/RootLayoutPadding"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent">
+
+    <include
+        android:id="@+id/pass_fail_buttons"
+        layout="@layout/pass_fail_buttons"
         android:layout_width="match_parent"
-        android:layout_height="match_parent">
+        android:layout_height="wrap_content"
+        android:layout_alignParentBottom="true" />
 
-    <include android:id="@+id/pass_fail_buttons"
-            android:layout_width="match_parent"
-            android:layout_height="wrap_content"
-            android:layout_alignParentBottom="true"
-            layout="@layout/pass_fail_buttons" />
+    <TextView
+        android:id="@+id/sensor_value"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:layout_above="@+id/sensor_accuracy_value"
+        android:layout_centerInParent="true"
+        android:layout_marginBottom="10dip"
+        android:background="@drawable/gray_bubble"
+        android:drawablePadding="10dip"
+        android:paddingBottom="5dip"
+        android:paddingLeft="10dip"
+        android:paddingRight="10dip"
+        android:paddingTop="5dip"
+        android:textSize="28dip" />
 
-    <TextView android:id="@+id/sensor_value"
-              android:background="@drawable/gray_bubble"
-              android:drawablePadding="10dip"
-              android:layout_above="@+id/sensor_accuracy_value"
-              android:layout_centerInParent="true"
-              android:layout_width="wrap_content"
-              android:layout_height="wrap_content"
-              android:layout_marginBottom="10dip"
-              android:paddingLeft="10dip"
-              android:paddingRight="10dip"
-              android:paddingTop="5dip"
-              android:paddingBottom="5dip"
-              android:textSize="28dip"
-        />
-
-    <TextView android:id="@+id/sensor_accuracy_value"
-              android:background="@drawable/gray_bubble"
-              android:drawablePadding="10dip"
-              android:layout_above="@+id/pass_fail_buttons"
-              android:layout_centerInParent="true"
-              android:layout_width="wrap_content"
-              android:layout_height="wrap_content"
-              android:layout_marginBottom="10dip"
-              android:paddingLeft="10dip"
-              android:paddingRight="10dip"
-              android:paddingTop="5dip"
-              android:paddingBottom="5dip"
-              android:textSize="28dip"
-        />
+    <TextView
+        android:id="@+id/sensor_accuracy_value"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:layout_above="@+id/pass_fail_buttons"
+        android:layout_centerInParent="true"
+        android:layout_marginBottom="10dip"
+        android:background="@drawable/gray_bubble"
+        android:drawablePadding="10dip"
+        android:paddingBottom="5dip"
+        android:paddingLeft="10dip"
+        android:paddingRight="10dip"
+        android:paddingTop="5dip"
+        android:textSize="28dip" />
 
 </RelativeLayout>
diff --git a/apps/CtsVerifier/res/layout/snsr_next_button.xml b/apps/CtsVerifier/res/layout/snsr_next_button.xml
index 391c394..78c9f1f 100644
--- a/apps/CtsVerifier/res/layout/snsr_next_button.xml
+++ b/apps/CtsVerifier/res/layout/snsr_next_button.xml
@@ -1,5 +1,4 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2013 The Android Open Source Project
+<?xml version="1.0" encoding="utf-8"?><!-- Copyright (C) 2013 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,35 +13,32 @@
      limitations under the License.
 -->
 <GridLayout xmlns:android="http://schemas.android.com/apk/res/android"
-        android:orientation="horizontal"
-        android:columnCount="@integer/test_list_footer_button_count"
+    android:layout_width="match_parent"
+    android:layout_height="wrap_content"
+    android:columnCount="@integer/test_list_footer_button_count"
+    android:orientation="horizontal"
+    android:paddingBottom="@dimen/snsr_view_padding_bottom"
+    android:paddingTop="@dimen/snsr_view_padding_top">
+
+    <Button
+        android:id="@+id/next_button"
         android:layout_width="match_parent"
         android:layout_height="wrap_content"
-        android:paddingBottom="@dimen/snsr_view_padding_bottom"
-        android:paddingTop="@dimen/snsr_view_padding_top"
-        >
+        android:text="@string/next_button_text" />
 
-    <Button android:id="@+id/next_button"
-            android:layout_height="wrap_content"
-            android:layout_width="wrap_content"
-            android:layout_columnWeight="1"
-            android:text="@string/next_button_text"
-            />
+    <Button
+        android:id="@+id/pass_button"
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:drawableTop="@drawable/fs_good"
+        android:visibility="gone" />
 
-    <Button android:id="@+id/pass_button"
-            android:visibility="gone"
-            android:layout_width="wrap_content"
-            android:layout_height="wrap_content"
-            android:layout_columnWeight="1"
-            android:drawableTop="@drawable/fs_good"
-            />
-
-    <Button android:id="@+id/fail_button"
-            android:visibility="gone"
-            android:layout_width="wrap_content"
-            android:layout_height="wrap_content"
-            android:layout_columnWeight="1"
-            android:drawableTop="@drawable/fs_error"
-            />
+    <Button
+        android:id="@+id/fail_button"
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:layout_columnWeight="1"
+        android:drawableTop="@drawable/fs_error"
+        android:visibility="gone" />
 
 </GridLayout>
diff --git a/apps/CtsVerifier/res/values-round/styles.xml b/apps/CtsVerifier/res/values-round/styles.xml
new file mode 100644
index 0000000..31e3c17
--- /dev/null
+++ b/apps/CtsVerifier/res/values-round/styles.xml
@@ -0,0 +1,11 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+    <style name="RootLayoutPadding">
+        <item name="android:paddingEnd">?android:listPreferredItemPaddingEnd</item>
+        <item name="android:paddingBottom">?android:dialogPreferredPadding</item>
+        <item name="android:paddingLeft">?android:listPreferredItemPaddingLeft</item>
+        <item name="android:paddingRight">?android:listPreferredItemPaddingRight</item>
+        <item name="android:paddingStart">?android:listPreferredItemPaddingStart</item>
+        <item name="android:paddingTop">?android:dialogPreferredPadding</item>
+    </style>
+</resources>
diff --git a/apps/CtsVerifier/res/values-watch/styles.xml b/apps/CtsVerifier/res/values-watch/styles.xml
new file mode 100644
index 0000000..31e3c17
--- /dev/null
+++ b/apps/CtsVerifier/res/values-watch/styles.xml
@@ -0,0 +1,11 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+    <style name="RootLayoutPadding">
+        <item name="android:paddingEnd">?android:listPreferredItemPaddingEnd</item>
+        <item name="android:paddingBottom">?android:dialogPreferredPadding</item>
+        <item name="android:paddingLeft">?android:listPreferredItemPaddingLeft</item>
+        <item name="android:paddingRight">?android:listPreferredItemPaddingRight</item>
+        <item name="android:paddingStart">?android:listPreferredItemPaddingStart</item>
+        <item name="android:paddingTop">?android:dialogPreferredPadding</item>
+    </style>
+</resources>
diff --git a/apps/CtsVerifier/res/values/strings.xml b/apps/CtsVerifier/res/values/strings.xml
index 2bc448b..49ee133 100755
--- a/apps/CtsVerifier/res/values/strings.xml
+++ b/apps/CtsVerifier/res/values/strings.xml
@@ -52,6 +52,10 @@
     <string name="no_storage">Cannot save report to external storage, see log for details.</string>
     <string name="report_saved">Report saved to: %s</string>
 
+    <!-- Strings for IntentDrivenTestActivity -->
+    <string name="intent_not_resolved">Intent Not Resolved</string>
+    <string name="intent_not_resolved_info">The following intent could not be resolved: %1$s</string>
+
     <!-- Strings for ReportViewerActivity -->
     <string name="report_viewer">Report Viewer</string>
 
@@ -443,6 +447,7 @@
     <string name="location_gnss_reg_test">GNSS Measurement Registration Test</string>
     <string name="location_gnss_value_test">GNSS Measurement Values Test</string>
     <string name="location_gnss_nav_msg_test">GNSS Navigation Message Test</string>
+    <string name="location_gnss_status_test">GNSS Status Test</string>
     <string name="location_gnss_test_info">This test verifies basic GNSS behavior.
         Make sure the device has line of sight to GNSS satellites
         (for example, stationary on a windowsill.  If needed, try again, outside, also with the
@@ -1215,6 +1220,16 @@
     <string name="package_priority_default">Find \"%s\" in the \"Notifications\" settings panel, and disallow it to Override Do Not Disturb.</string>
     <string name="package_priority_user_order">Check that ranker respects user priorities.</string>
 
+    <string name="shortcut_reset_test">Shortcut Reset Rate-limiting Test</string>
+    <string name="shortcut_reset_info">This test checks that when an inline-reply happens, ShortcutManager\'s rate-limiting
+        is reset.</string>
+    <string name="shortcut_reset_bot">Verifying that the CTS Robot helper package is installed.</string>
+    <string name="shortcut_reset_start">Showing the notification.</string>
+    <string name="shortcut_reset_prompt_inline_reply">Open the notification shade,
+        find the \"Shortcut Reset Rate-limiting Test\" notification, type something in the inline-reply field and
+        press the send button.</string>
+    <string name="shortcut_reset_check_result">Check ShortcutManager rate-limit has been reset.</string>
+
     <string name="attention_test">Notification Attention Management Test</string>
     <string name="attention_info">This test checks that the NotificationManagerService is
         respecting user preferences about notification ranking and filtering.
@@ -1669,7 +1684,33 @@
         The only way to disable the encryption is to factory reset the device.
     </string>
     <string name="provisioning_byod_profileowner">Profile owner installed</string>
-    <string name="provisioning_byod_diskencryption">Full disk encryption enabled</string>
+    <string name="provisioning_byod_disk_encryption">Full disk encryption enabled</string>
+    <string name="provisioning_byod_disk_encryption_default_key_toast">
+        Cannot secure device with screen lock. Please re-run the test if you forgot to select
+        the \"require PIN to boot\" option.
+    </string>
+    <string name="provisioning_byod_disk_encryption_no_pin_toast">
+        No PIN is detected. Please re-run the test if you forgot to set a PIN.
+    </string>
+    <string name="provisioning_byod_set_screen_lock_dialog_message">
+        Next, you will be asked to set a screen lock for the device.\n
+        \n
+        Please set \"1111\" as the new PIN (or any other PIN that you can memorize).
+        You have to enter this PIN again later in order to finish the test.\n
+        \n
+        You may be asked whether the PIN should be required to boot the device. Please answer yes.\n
+        \n
+        Tap Go button to set a new screen lock.
+    </string>
+    <string name="provisioning_byod_remove_screen_lock_dialog_message">
+        The test is almost finished. \n
+        \n
+        Next, you will be asked to remove the screen lock that you just set. Please enter \"1111\"
+        (or your own PIN) when prompted for the old PIN, and do not set any new screen lock. This
+        is to make sure that the device returns to the initial state after this test.\n
+        \n
+        Tap Go button to remove existing screen lock.
+    </string>
     <string name="provisioning_byod_profile_visible">Profile-aware accounts settings</string>
     <string name="provisioning_byod_admin_visible">Profile-aware device administrator settings</string>
     <string name="provisioning_byod_workapps_visible">Badged work apps visible in Launcher</string>
@@ -2177,9 +2218,12 @@
     <string name="device_owner_disallow_usb_file_transfer_test">Disallow USB file transfer</string>
     <string name="device_owner_disallow_usb_file_transfer_test_info">
             Please press below button to set the \"disallow USB file transfer\" restriction.\n
-            Next, connect your device to your desktop computer through USB, open the USB notification from the status bar
-            and check that the \"Transfer files (MTP)\" and \"Transfer photos (PTP)\" cannot be selected and triggers a support message when trying to select them.\n
-            Also, check that if you can download files from your phone to the desktop computer. The test is successful if the files from your phone are not and cannot be downloaded through USB.\n
+            If a USB notification appears, open the notification and check that the
+            \"Transfer files (MTP)\" and \"Transfer photos (PTP)\" cannot be selected and trigger a
+            support message when trying to select them.\n
+            Check if you can mount the device as a USB drive on your desktop computer. The test is
+            successful if you cannot mount the device, and files from your phone cannot be
+            downloaded through USB.\n
             Please mark the test accordingly.
     </string>
     <string name="device_owner_set_user_icon">Setting the user icon</string>
@@ -2286,11 +2330,14 @@
     <string name="device_owner_disallow_config_vpn_info">
         Please press the Set VPN restriction button to set the VPN restriction.
         Perform tests in order. Mark test as passed if both test cases pass\n\n
-        1. Press Go to open the Vpn settings page.\n
-        Confirm that:\n
+        1. Press Go to attempt to open the VPN settings page.\n
+        You should either see (a) the VPN settings page or (b) that the Intent
+        android.settings.VPN_SETTINGS fails to resolve.\n
+        In the case of (a), confirm that:\n
         - You cannot add a new VPN network.\n
         - You cannot edit, add or remove any existing VPNs.\n
-        - Trying to perform any of the above actions will trigger a support message.\n\n
+        - Trying to perform any of the above actions will trigger a support message.\n
+        In the case of (b) this step is successful.\n\n
         2. Press Check VPN to check programmatic Vpn test.\n
         - Check Vpn setup is not allowed\n
         - If prompted to allow a VPN connection, press OK.\n\n
diff --git a/apps/CtsVerifier/res/values/styles.xml b/apps/CtsVerifier/res/values/styles.xml
index 64fd4fe..ca85431 100644
--- a/apps/CtsVerifier/res/values/styles.xml
+++ b/apps/CtsVerifier/res/values/styles.xml
@@ -11,7 +11,12 @@
         <item name="android:padding">5dp</item>
     </style>
     <style name="RootLayoutPadding">
-        <item name="android:padding">10dip</item>
+      <item name="android:paddingEnd">?android:attr/listPreferredItemPaddingEnd</item>
+      <item name="android:paddingBottom">?android:attr/dialogPreferredPadding</item>
+      <item name="android:paddingLeft">?android:attr/listPreferredItemPaddingLeft</item>
+      <item name="android:paddingRight">?android:attr/listPreferredItemPaddingRight</item>
+      <item name="android:paddingStart">?android:attr/listPreferredItemPaddingStart</item>
+      <item name="android:paddingTop">?android:attr/dialogPreferredPadding</item>
     </style>
     <style name="OverlayTheme" parent="android:Theme.Dialog">
         <item name="android:windowNoTitle">true</item>
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/DialogTestListActivity.java b/apps/CtsVerifier/src/com/android/cts/verifier/DialogTestListActivity.java
index 1e83087..aa6eaba 100644
--- a/apps/CtsVerifier/src/com/android/cts/verifier/DialogTestListActivity.java
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/DialogTestListActivity.java
@@ -21,10 +21,12 @@
 import android.content.Context;
 import android.content.DialogInterface;
 import android.content.Intent;
+import android.content.pm.PackageManager;
 import android.database.DataSetObserver;
 import android.os.Bundle;
 import android.util.Log;
 import android.view.LayoutInflater;
+import android.view.MotionEvent;
 import android.view.View;
 import android.view.View.OnClickListener;
 import android.widget.Button;
@@ -49,6 +51,7 @@
     private final int mInstructionsStringId;
 
     protected Button mPrepareTestButton;
+    protected ListView mTestFeaturesList;
 
     protected int mCurrentTestPosition;
 
@@ -85,15 +88,31 @@
 
         mCurrentTestPosition = 0;
 
-        TextView instructionTextView = (TextView)findViewById(R.id.test_instructions);
+        TextView instructionTextView = (TextView) findViewById(R.id.test_instructions);
         instructionTextView.setText(mInstructionsStringId);
-        mPrepareTestButton = (Button)findViewById(R.id.prepare_test_button);
+        mPrepareTestButton = (Button) findViewById(R.id.prepare_test_button);
+        mTestFeaturesList = (ListView) findViewById(android.R.id.list);
+        if (getPackageManager().hasSystemFeature(PackageManager.FEATURE_WATCH)) {
+            mTestFeaturesList.setOnTouchListener((View v, MotionEvent e) -> {
+                switch (e.getAction()) {
+                    case MotionEvent.ACTION_DOWN:
+                        v.getParent().requestDisallowInterceptTouchEvent(true);
+                        break;
+                    case MotionEvent.ACTION_UP:
+                        v.getParent().requestDisallowInterceptTouchEvent(false);
+                        break;
+                    default:
+                }
+                return false;
+            });
+        }
     }
 
     /**
      * Subclasses must add their tests items to the provided adapter(usually instances of
      * {@link DialogTestListItem} or {@link DialogTestListItemWithIcon} but any class deriving from
      * {@link TestListAdapter.TestListItem} will do).
+     *
      * @param adapter The adapter to add test items to.
      */
     protected abstract void setupTests(ArrayTestListAdapter adapter);
@@ -165,7 +184,7 @@
                 .getItem(position);
         if (test instanceof DialogTestListItem) {
             mCurrentTestPosition = position;
-            ((DialogTestListItem)test).performTest(this);
+            ((DialogTestListItem) test).performTest(this);
         } else {
             try {
                 super.handleItemClick(l, v, position, id);
@@ -180,6 +199,7 @@
 
     /**
      * Start a test's manual intent
+     *
      * @param test The test the manual intent of which is to be started.
      * @return true if activity could be started successfully, false otherwise.
      */
@@ -227,6 +247,7 @@
 
         public interface TestCallback {
             void onPass();
+
             void onFail();
         }
 
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/IntentDrivenTestActivity.java b/apps/CtsVerifier/src/com/android/cts/verifier/IntentDrivenTestActivity.java
index 678a338..cc072a1 100644
--- a/apps/CtsVerifier/src/com/android/cts/verifier/IntentDrivenTestActivity.java
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/IntentDrivenTestActivity.java
@@ -2,10 +2,13 @@
 
 package com.android.cts.verifier;
 
+import android.app.AlertDialog;
+import android.content.ActivityNotFoundException;
 import android.content.Intent;
 import android.os.Bundle;
 import android.os.Parcel;
 import android.os.Parcelable;
+import android.util.Log;
 import android.view.View;
 import android.view.View.OnClickListener;
 import android.view.ViewGroup;
@@ -26,6 +29,8 @@
  *  button that was clicked.
  */
 public class IntentDrivenTestActivity extends PassFailButtons.Activity implements OnClickListener {
+    private static final String TAG = "IntentDrivenTestActivity";
+
     public static final String EXTRA_ID = "id";
     public static final String EXTRA_TITLE = "title";
     public static final String EXTRA_INFO = "info";
@@ -80,33 +85,46 @@
     public void onClick(View v) {
         final ButtonInfo buttonInfo = mButtonInfos[(Integer) v.getTag()];
         final Intent[] intents = buttonInfo.getIntents();
-        if (intents != null) {
-            for (Parcelable intent : intents) {
-                startActivity((Intent) intent);
-            }
-        } else {
-            final Class<?> factoryClass;
-            final String className = buttonInfo.getIntentFactoryClassName();
-            try {
-                factoryClass = Thread.currentThread().getContextClassLoader().loadClass(className);
-            } catch (ClassNotFoundException e) {
-                throw new IllegalArgumentException("Factory not found: " + className, e);
-            }
-            final IntentFactory factory;
-            try {
-                factory = (IntentFactory) factoryClass.newInstance();
-            } catch (InstantiationException e) {
-                throw new IllegalArgumentException("Can't create factory: " + className, e);
-            } catch (IllegalAccessException e) {
-                throw new IllegalArgumentException("Can't create factory: " + className, e);
-            }
+        try {
+            if (intents != null) {
+                for (Parcelable intent : intents) {
+                    startActivity((Intent) intent);
+                }
+            } else {
+                final Class<?> factoryClass;
+                final String className = buttonInfo.getIntentFactoryClassName();
+                try {
+                    factoryClass = Thread.currentThread().getContextClassLoader().loadClass(className);
+                } catch (ClassNotFoundException e) {
+                    throw new IllegalArgumentException("Factory not found: " + className, e);
+                }
+                final IntentFactory factory;
+                try {
+                    factory = (IntentFactory) factoryClass.newInstance();
+                } catch (InstantiationException e) {
+                    throw new IllegalArgumentException("Can't create factory: " + className, e);
+                } catch (IllegalAccessException e) {
+                    throw new IllegalArgumentException("Can't create factory: " + className, e);
+                }
 
-            for (Intent intent : factory.createIntents(mTestId, buttonInfo.getButtonText())) {
-                startActivity(intent);
+                for (Intent intent : factory.createIntents(mTestId, buttonInfo.getButtonText())) {
+                    startActivity(intent);
+                }
             }
+        } catch (ActivityNotFoundException e) {
+            // Instead of crashing, log and alert the user of that the Intent couldn't be resolved.
+            Log.w(TAG, "Could not resolve Intent.", e);
+            showFailedIntentResolution(e.getMessage());
         }
     }
 
+    private void showFailedIntentResolution(String message) {
+        new AlertDialog.Builder(this)
+                .setTitle(R.string.intent_not_resolved)
+                .setMessage(getString(R.string.intent_not_resolved_info, message))
+                .show();
+    }
+
     @Override
     public String getTestId() {
         return mTestId;
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/audio/HifiUltrasoundSpeakerTestActivity.java b/apps/CtsVerifier/src/com/android/cts/verifier/audio/HifiUltrasoundSpeakerTestActivity.java
index 2e4bc5c..1a9ffac 100644
--- a/apps/CtsVerifier/src/com/android/cts/verifier/audio/HifiUltrasoundSpeakerTestActivity.java
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/audio/HifiUltrasoundSpeakerTestActivity.java
@@ -41,6 +41,9 @@
 import com.androidplot.xy.XYSeries;
 import com.androidplot.xy.*;
 
+import com.android.compatibility.common.util.CddTest;
+
+@CddTest(requirement="7.8.3")
 public class HifiUltrasoundSpeakerTestActivity extends PassFailButtons.Activity {
 
   public enum Status {
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/camera/its/ItsSerializer.java b/apps/CtsVerifier/src/com/android/cts/verifier/camera/its/ItsSerializer.java
index 193c94c..2a6c146 100644
--- a/apps/CtsVerifier/src/com/android/cts/verifier/camera/its/ItsSerializer.java
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/camera/its/ItsSerializer.java
@@ -371,7 +371,7 @@
         try {
             Object keyValue = getKeyValue(md, keyObj);
             if (keyValue == null) {
-                return new MetadataEntry(keyName, JSONObject.NULL);
+                return null;
             }
             int arrayLen = Array.getLength(keyValue);
             Type elmtType = ((GenericArrayType)keyType).getGenericComponentType();
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 9a7c351..8710096 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
@@ -416,6 +416,7 @@
         // (called on different threads) will need to send data back to the host script.
 
         public Socket mOpenSocket = null;
+        private Thread mThread = null;
 
         public SocketWriteRunnable(Socket openSocket) {
             mOpenSocket = openSocket;
@@ -433,6 +434,7 @@
                     ByteBuffer b = mSocketWriteQueue.take();
                     synchronized(mSocketWriteDrainLock) {
                         if (mOpenSocket == null) {
+                            Logt.e(TAG, "No open socket connection!");
                             continue;
                         }
                         if (b.hasArray()) {
@@ -454,14 +456,26 @@
                     }
                 } catch (IOException e) {
                     Logt.e(TAG, "Error writing to socket", e);
+                    mOpenSocket = null;
                     break;
                 } catch (java.lang.InterruptedException e) {
                     Logt.e(TAG, "Error writing to socket (interrupted)", e);
+                    mOpenSocket = null;
                     break;
                 }
             }
             Logt.i(TAG, "Socket writer thread terminated");
         }
+
+        public synchronized void checkAndStartThread() {
+            if (mThread == null || mThread.getState() == Thread.State.TERMINATED) {
+                mThread = new Thread(this);
+            }
+            if (mThread.getState() == Thread.State.NEW) {
+                mThread.start();
+            }
+        }
+
     }
 
     class SocketRunnable implements Runnable {
@@ -487,7 +501,6 @@
 
             // Create a new thread to handle writes to this socket.
             mSocketWriteRunnable = new SocketWriteRunnable(null);
-            (new Thread(mSocketWriteRunnable)).start();
 
             while (!mThreadExitFlag) {
                 // Receive the socket-open request from the host.
@@ -501,6 +514,7 @@
                     mSocketWriteQueue.clear();
                     mInflightImageSizes.clear();
                     mSocketWriteRunnable.setOpenSocket(mOpenSocket);
+                    mSocketWriteRunnable.checkAndStartThread();
                     Logt.i(TAG, "Socket connected");
                 } catch (IOException e) {
                     Logt.e(TAG, "Socket open error: ", e);
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/location/GnssStatusTestsActivity.java b/apps/CtsVerifier/src/com/android/cts/verifier/location/GnssStatusTestsActivity.java
new file mode 100644
index 0000000..a64c5d3
--- /dev/null
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/location/GnssStatusTestsActivity.java
@@ -0,0 +1,15 @@
+package com.android.cts.verifier.location;
+
+import com.android.cts.verifier.location.base.GnssCtsTestActivity;
+import android.location.cts.GnssStatusTest;
+
+/**
+ * Activity to execute CTS GnssStatusTest.
+ * It is a wrapper for {@link GnssStatusTest} running with AndroidJUnitRunner.
+ */
+
+public class GnssStatusTestsActivity extends GnssCtsTestActivity {
+  public GnssStatusTestsActivity() {
+    super(GnssStatusTest.class);
+  }
+}
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/managedprovisioning/ByodFlowTestActivity.java b/apps/CtsVerifier/src/com/android/cts/verifier/managedprovisioning/ByodFlowTestActivity.java
index 3867d7f..d2dd9ef 100644
--- a/apps/CtsVerifier/src/com/android/cts/verifier/managedprovisioning/ByodFlowTestActivity.java
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/managedprovisioning/ByodFlowTestActivity.java
@@ -16,6 +16,7 @@
 
 package com.android.cts.verifier.managedprovisioning;
 
+import android.app.KeyguardManager;
 import android.app.admin.DevicePolicyManager;
 import android.content.ActivityNotFoundException;
 import android.content.ComponentName;
@@ -39,9 +40,10 @@
 import com.android.cts.verifier.location.LocationListenerActivity;
 
 /**
- * CTS verifier test for BYOD managed provisioning flow.
- * This activity is responsible for starting the managed provisioning flow and verify the outcome of provisioning.
- * It performs the following verifications:
+ * CTS verifier test for BYOD managed provisioning flow
+ *
+ * This activity is responsible for starting the managed provisioning flow and verify the outcome of
+ * provisioning. It performs the following verifications:
  *   Full disk encryption is enabled.
  *   Profile owner is correctly installed.
  *   Profile owner shows up in the Settings app.
@@ -51,17 +53,21 @@
  */
 public class ByodFlowTestActivity extends DialogTestListActivity {
 
-    private final String TAG = "ByodFlowTestActivity";
+    private static final String TAG = "ByodFlowTestActivity";
     private static ConnectivityManager mCm;
     private static final int REQUEST_MANAGED_PROVISIONING = 0;
     private static final int REQUEST_PROFILE_OWNER_STATUS = 1;
     private static final int REQUEST_INTENT_FILTERS_STATUS = 2;
+    private static final int REQUEST_CHECK_DISK_ENCRYPTION = 3;
+    private static final int REQUEST_SET_LOCK_FOR_ENCRYPTION = 4;
 
     private ComponentName mAdminReceiverComponent;
+    private KeyguardManager mKeyguardManager;
 
     private ByodFlowTestHelper mByodFlowTestHelper;
 
     private DialogTestListItem mProfileOwnerInstalled;
+    private DialogTestListItem mDiskEncryptionTest;
     private DialogTestListItem mProfileAccountVisibleTest;
     private DialogTestListItem mDeviceAdminVisibleTest;
     private DialogTestListItem mWorkAppVisibleTest;
@@ -112,6 +118,7 @@
         super.onCreate(savedInstanceState);
         mByodFlowTestHelper = new ByodFlowTestHelper(this);
         mAdminReceiverComponent = new ComponentName(this, DeviceAdminTestReceiver.class.getName());
+        mKeyguardManager = (KeyguardManager) getSystemService(KEYGUARD_SERVICE);
 
         mByodFlowTestHelper.setup();
 
@@ -151,17 +158,24 @@
         switch (requestCode) {
             case REQUEST_MANAGED_PROVISIONING:
                 return;
-            case REQUEST_PROFILE_OWNER_STATUS: {
+            case REQUEST_PROFILE_OWNER_STATUS:
                 // Called after queryProfileOwner()
                 handleStatusUpdate(resultCode, data);
-            } break;
-            case REQUEST_INTENT_FILTERS_STATUS: {
+                break;
+            case REQUEST_CHECK_DISK_ENCRYPTION:
+                // Called after checkDiskEncryption()
+                handleDiskEncryptionStatus(resultCode, data);
+                break;
+            case REQUEST_SET_LOCK_FOR_ENCRYPTION:
+                // Called after handleDiskEncryptionStatus() to set screen lock if necessary
+                handleSetLockForEncryption();
+                break;
+            case REQUEST_INTENT_FILTERS_STATUS:
                 // Called after checkIntentFilters()
                 handleIntentFiltersStatus(resultCode);
-            } break;
-            default: {
+                break;
+            default:
                 super.handleActivityResult(requestCode, resultCode, data);
-            }
         }
     }
 
@@ -191,6 +205,15 @@
             }
         };
 
+        mDiskEncryptionTest = new DialogTestListItem(this,
+                R.string.provisioning_byod_disk_encryption,
+                "BYOD_DiskEncryptionTest") {
+            @Override
+            public void performTest(DialogTestListActivity activity) {
+                checkDiskEncryption();
+            }
+        };
+
         /*
          * To keep the image in this test up to date, use the instructions in
          * {@link ByodIconSamplerActivity}.
@@ -304,11 +327,13 @@
                 R.string.provisioning_byod_cross_profile_from_work_instruction,
                 new Intent(ByodHelperActivity.ACTION_TEST_CROSS_PROFILE_INTENTS_DIALOG));
 
+        /* Disable due to b/33571176
         mAppLinkingTest = new DialogTestListItem(this,
                 R.string.provisioning_app_linking,
                 "BYOD_AppLinking",
                 R.string.provisioning_byod_app_linking_instruction,
                 new Intent(ByodHelperActivity.ACTION_TEST_APP_LINKING_DIALOG));
+        */
 
         mKeyguardDisabledFeaturesTest = TestListItem.newTest(this,
                 R.string.provisioning_byod_keyguard_disabled_features,
@@ -355,6 +380,7 @@
                 R.string.profile_owner_permission_lockdown_test_info,
                 permissionCheckIntent);
 
+        /* Disable due to b/33571768
         mSelectWorkChallenge = new DialogTestListItem(this,
                 R.string.provisioning_byod_select_work_challenge,
                 "BYOD_SelectWorkChallenge",
@@ -366,6 +392,7 @@
                 "BYOD_ConfirmWorkCredentials",
                 R.string.provisioning_byod_confirm_work_credentials_description,
                 new Intent(Intent.ACTION_MAIN).addCategory(Intent.CATEGORY_HOME));
+        */
 
         mOrganizationInfoTest = TestListItem.newTest(this,
                 R.string.provisioning_byod_organization_info,
@@ -391,6 +418,7 @@
                 policyTransparencyTestIntent, null);
 
         adapter.add(mProfileOwnerInstalled);
+        adapter.add(mDiskEncryptionTest);
 
         // Badge related tests
         adapter.add(mWorkAppVisibleTest);
@@ -408,7 +436,9 @@
 
         adapter.add(mCrossProfileIntentFiltersTestFromPersonal);
         adapter.add(mCrossProfileIntentFiltersTestFromWork);
+        /* Disable due to b/33571176
         adapter.add(mAppLinkingTest);
+        */
         adapter.add(mDisableNonMarketTest);
         adapter.add(mEnableNonMarketTest);
         adapter.add(mIntentFiltersTest);
@@ -417,8 +447,10 @@
         adapter.add(mAuthenticationBoundKeyTest);
         adapter.add(mVpnTest);
         adapter.add(mTurnOffWorkFeaturesTest);
+        /* Disable due to b/33571768
         adapter.add(mSelectWorkChallenge);
         adapter.add(mConfirmWorkCredentials);
+        */
         adapter.add(mOrganizationInfoTest);
         adapter.add(mParentProfilePassword);
         adapter.add(mPolicyTransparencyTest);
@@ -606,6 +638,59 @@
         }
     }
 
+    private void checkDiskEncryption() {
+        try {
+            Intent intent = new Intent(ByodHelperActivity.ACTION_CHECK_DISK_ENCRYPTION);
+            startActivityForResult(intent, REQUEST_CHECK_DISK_ENCRYPTION);
+        } catch (ActivityNotFoundException e) {
+            Log.d(TAG, "checkDiskEncryption: ActivityNotFoundException", e);
+            setTestResult(mDiskEncryptionTest, TestResult.TEST_RESULT_FAILED);
+            showToast(R.string.provisioning_byod_no_activity);
+        }
+    }
+
+    private void handleDiskEncryptionStatus(int resultCode, Intent data) {
+        if (resultCode != RESULT_OK || data == null) {
+            Log.e(TAG, "Failed to get result for disk encryption, result code: " + resultCode);
+            setTestResult(mDiskEncryptionTest, TestResult.TEST_RESULT_FAILED);
+            return;
+        }
+
+        final int status = data.getIntExtra(ByodHelperActivity.EXTRA_ENCRYPTION_STATUS,
+                DevicePolicyManager.ENCRYPTION_STATUS_UNSUPPORTED);
+        switch (status) {
+            case DevicePolicyManager.ENCRYPTION_STATUS_ACTIVE:
+            case DevicePolicyManager.ENCRYPTION_STATUS_ACTIVE_PER_USER:
+                setTestResult(mDiskEncryptionTest, TestResult.TEST_RESULT_PASSED);
+                break;
+            case DevicePolicyManager.ENCRYPTION_STATUS_ACTIVE_DEFAULT_KEY:
+                if (!mKeyguardManager.isDeviceSecure()) {
+                    Utils.setScreenLock(this, REQUEST_SET_LOCK_FOR_ENCRYPTION);
+                    return;
+                }
+                Log.e(TAG, "Disk encryption key is not entangled with lock screen credentials");
+                Toast.makeText(this, R.string.provisioning_byod_disk_encryption_default_key_toast,
+                        Toast.LENGTH_LONG).show();
+                // fall through
+            default:
+                setTestResult(mDiskEncryptionTest, TestResult.TEST_RESULT_FAILED);
+        }
+
+        if (mKeyguardManager.isDeviceSecure()) {
+            Utils.removeScreenLock(this);
+        }
+    }
+
+    private void handleSetLockForEncryption() {
+        if (mKeyguardManager.isDeviceSecure()) {
+            checkDiskEncryption();
+        } else {
+            setTestResult(mDiskEncryptionTest, TestResult.TEST_RESULT_FAILED);
+            Toast.makeText(this, R.string.provisioning_byod_disk_encryption_no_pin_toast,
+                    Toast.LENGTH_LONG).show();
+        }
+    }
+
     private void checkIntentFilters() {
         try {
             // Enable component HandleIntentActivity before intent filters are checked.
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/managedprovisioning/ByodHelperActivity.java b/apps/CtsVerifier/src/com/android/cts/verifier/managedprovisioning/ByodHelperActivity.java
index b4f9724..86087f2 100644
--- a/apps/CtsVerifier/src/com/android/cts/verifier/managedprovisioning/ByodHelperActivity.java
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/managedprovisioning/ByodHelperActivity.java
@@ -91,6 +91,15 @@
     public static final String EXTRA_PROVISIONED = "extra_provisioned";
     public static final String EXTRA_PARAMETER_1 = "extra_parameter_1";
 
+    // Primary -> managed intent: check if the disk of the device is encrypted
+    public static final String ACTION_CHECK_DISK_ENCRYPTION =
+            "com.android.cts.verifier.managedprovisioning.action.BYOD_CHECK_DISK_ENCRYPTION";
+    // Managed -> primary intent: update disk encryption status in primary's CtsVerifier
+    public static final String ACTION_DISK_ENCRYPTION_STATUS =
+            "com.android.cts.verifier.managedprovisioning.action.BYOD_DISK_ENCRYPTION_STATUS";
+    // Int extra field indicating the encryption status of the device storage
+    public static final String EXTRA_ENCRYPTION_STATUS = "extra_encryption_status";
+
     // Primary -> managed intent: set unknown sources restriction and install package
     public static final String ACTION_INSTALL_APK = "com.android.cts.verifier.managedprovisioning.BYOD_INSTALL_APK";
     public static final String EXTRA_ALLOW_NON_MARKET_APPS = INSTALL_NON_MARKET_APPS;
@@ -217,6 +226,11 @@
                 mDevicePolicyManager.wipeData(0);
                 showToast(R.string.provisioning_byod_profile_deleted);
             }
+        } else if (action.equals(ACTION_CHECK_DISK_ENCRYPTION)) {
+            final int status = mDevicePolicyManager.getStorageEncryptionStatus();
+            final Intent response = new Intent(ACTION_DISK_ENCRYPTION_STATUS)
+                    .putExtra(EXTRA_ENCRYPTION_STATUS, status);
+            setResult(RESULT_OK, response);
         } else if (action.equals(ACTION_INSTALL_APK)) {
             boolean allowNonMarket = intent.getBooleanExtra(EXTRA_ALLOW_NON_MARKET_APPS, false);
             boolean wasAllowed = getAllowNonMarket();
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/managedprovisioning/DeviceAdminTestReceiver.java b/apps/CtsVerifier/src/com/android/cts/verifier/managedprovisioning/DeviceAdminTestReceiver.java
index e6ba855..122dd00 100644
--- a/apps/CtsVerifier/src/com/android/cts/verifier/managedprovisioning/DeviceAdminTestReceiver.java
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/managedprovisioning/DeviceAdminTestReceiver.java
@@ -82,6 +82,7 @@
             IntentFilter filter = new IntentFilter();
             filter.addAction(ByodHelperActivity.ACTION_QUERY_PROFILE_OWNER);
             filter.addAction(ByodHelperActivity.ACTION_REMOVE_MANAGED_PROFILE);
+            filter.addAction(ByodHelperActivity.ACTION_CHECK_DISK_ENCRYPTION);
             filter.addAction(ByodHelperActivity.ACTION_INSTALL_APK);
             filter.addAction(ByodHelperActivity.ACTION_CHECK_INTENT_FILTERS);
             filter.addAction(ByodHelperActivity.ACTION_CAPTURE_AND_CHECK_IMAGE);
@@ -118,6 +119,7 @@
             // Work -> primary direction
             filter = new IntentFilter();
             filter.addAction(ByodHelperActivity.ACTION_PROFILE_OWNER_STATUS);
+            filter.addAction(ByodHelperActivity.ACTION_DISK_ENCRYPTION_STATUS);
             filter.addAction(CrossProfileTestActivity.ACTION_CROSS_PROFILE_TO_PERSONAL);
             filter.addAction(LocationListenerActivity.ACTION_SET_LOCATION_AND_CHECK_UPDATES);
             dpm.addCrossProfileIntentFilter(getWho(context), filter,
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/managedprovisioning/DeviceOwnerPositiveTestActivity.java b/apps/CtsVerifier/src/com/android/cts/verifier/managedprovisioning/DeviceOwnerPositiveTestActivity.java
index 7b3a4a4..ce53b61 100644
--- a/apps/CtsVerifier/src/com/android/cts/verifier/managedprovisioning/DeviceOwnerPositiveTestActivity.java
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/managedprovisioning/DeviceOwnerPositiveTestActivity.java
@@ -242,21 +242,23 @@
                                         UserManager.DISALLOW_USB_FILE_TRANSFER)),
                 }));
 
-        // setStatusBarDisabled
-        adapter.add(createInteractiveTestItem(this, DISABLE_STATUS_BAR_TEST_ID,
-                R.string.device_owner_disable_statusbar_test,
-                R.string.device_owner_disable_statusbar_test_info,
-                new ButtonInfo[] {
-                        new ButtonInfo(
-                                R.string.device_owner_disable_statusbar_button,
-                                createDeviceOwnerIntentWithBooleanParameter(
-                                        CommandReceiverActivity.COMMAND_SET_STATUSBAR_DISABLED,
-                                                true)),
-                        new ButtonInfo(
-                                R.string.device_owner_reenable_statusbar_button,
-                                createDeviceOwnerIntentWithBooleanParameter(
-                                        CommandReceiverActivity.COMMAND_SET_STATUSBAR_DISABLED,
-                                                false))}));
+        // DISABLE_STATUS_BAR_TEST
+        if (isStatusBarEnabled()) {
+            adapter.add(createInteractiveTestItem(this, DISABLE_STATUS_BAR_TEST_ID,
+                    R.string.device_owner_disable_statusbar_test,
+                    R.string.device_owner_disable_statusbar_test_info,
+                    new ButtonInfo[] {
+                            new ButtonInfo(
+                                    R.string.device_owner_disable_statusbar_button,
+                                    createDeviceOwnerIntentWithBooleanParameter(
+                                            CommandReceiverActivity.COMMAND_SET_STATUSBAR_DISABLED,
+                                                    true)),
+                            new ButtonInfo(
+                                    R.string.device_owner_reenable_statusbar_button,
+                                    createDeviceOwnerIntentWithBooleanParameter(
+                                            CommandReceiverActivity.COMMAND_SET_STATUSBAR_DISABLED,
+                                                    false))}));
+        }
 
         // setKeyguardDisabled
         adapter.add(createInteractiveTestItem(this, DISABLE_KEYGUARD_TEST_ID,
@@ -342,4 +344,10 @@
                 .putExtra(CommandReceiverActivity.EXTRA_COMMAND,
                         CommandReceiverActivity.COMMAND_SET_USER_ICON);
     }
+
+    private boolean isStatusBarEnabled() {
+      // Watches don't support the status bar so this is an ok proxy, but this is not the most
+      // general test for that. TODO: add a test API to do a real check for status bar support.
+      return !getPackageManager().hasSystemFeature(PackageManager.FEATURE_WATCH);
+    }
 }
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/managedprovisioning/PolicyTransparencyTestListActivity.java b/apps/CtsVerifier/src/com/android/cts/verifier/managedprovisioning/PolicyTransparencyTestListActivity.java
index c5b4a93..e74f07e 100644
--- a/apps/CtsVerifier/src/com/android/cts/verifier/managedprovisioning/PolicyTransparencyTestListActivity.java
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/managedprovisioning/PolicyTransparencyTestListActivity.java
@@ -152,6 +152,10 @@
         switch (test) {
             case PolicyTransparencyTestActivity.TEST_CHECK_PERMITTED_INPUT_METHOD:
                 return pm.hasSystemFeature(PackageManager.FEATURE_INPUT_METHODS);
+            case PolicyTransparencyTestActivity.TEST_CHECK_PERMITTED_ACCESSIBILITY_SERVICE:
+                return pm.hasSystemFeature(PackageManager.FEATURE_AUDIO_OUTPUT);
+            case PolicyTransparencyTestActivity.TEST_CHECK_LOCK_SCREEN_INFO:
+                return !pm.hasSystemFeature(PackageManager.FEATURE_WATCH);
             default:
                 return true;
         }
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/managedprovisioning/UserRestrictions.java b/apps/CtsVerifier/src/com/android/cts/verifier/managedprovisioning/UserRestrictions.java
index 935a1b8..9cb8672 100644
--- a/apps/CtsVerifier/src/com/android/cts/verifier/managedprovisioning/UserRestrictions.java
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/managedprovisioning/UserRestrictions.java
@@ -23,10 +23,10 @@
 import android.provider.Settings;
 import android.util.ArrayMap;
 
-import java.util.ArrayList;
-
 import com.android.cts.verifier.R;
 
+import java.util.ArrayList;
+
 public class UserRestrictions {
     private static final String[] RESTRICTION_IDS = new String[] {
         UserManager.DISALLOW_ADD_USER,
@@ -107,7 +107,7 @@
             Settings.ACTION_DEVICE_INFO_SETTINGS,
             Settings.ACTION_SECURITY_SETTINGS,
             Settings.ACTION_SYNC_SETTINGS,
-            Settings.ACTION_PRIVACY_SETTINGS,
+            Settings.ACTION_WIRELESS_SETTINGS,
             Settings.ACTION_WIRELESS_SETTINGS,
             Settings.ACTION_SETTINGS,
             Settings.ACTION_LOCATION_SOURCE_SETTINGS,
@@ -199,6 +199,9 @@
                     isCellBroadcastAppLinkEnabled = false;  // CMAS app not installed
                 }
                 return isCellBroadcastAppLinkEnabled;
+            case UserManager.DISALLOW_FUN:
+                // Easter egg is not available on watch
+                return !pm.hasSystemFeature(PackageManager.FEATURE_WATCH);
             case UserManager.DISALLOW_CONFIG_MOBILE_NETWORKS:
                 return pm.hasSystemFeature(PackageManager.FEATURE_TELEPHONY);
             case UserManager.DISALLOW_CONFIG_WIFI:
@@ -207,6 +210,10 @@
                 return pm.hasSystemFeature(PackageManager.FEATURE_NFC);
             case UserManager.DISALLOW_SHARE_LOCATION:
                 return pm.hasSystemFeature(PackageManager.FEATURE_LOCATION);
+            case UserManager.DISALLOW_INSTALL_UNKNOWN_SOURCES:
+                return !pm.hasSystemFeature(PackageManager.FEATURE_WATCH);
+            case UserManager.DISALLOW_CONFIG_CREDENTIALS:
+                return !pm.hasSystemFeature(PackageManager.FEATURE_WATCH);
             default:
                 return true;
         }
@@ -222,4 +229,4 @@
             this.intentAction = intentAction;
         }
     }
-}
\ No newline at end of file
+}
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/managedprovisioning/Utils.java b/apps/CtsVerifier/src/com/android/cts/verifier/managedprovisioning/Utils.java
index ffc1e07..2ea5cf9 100644
--- a/apps/CtsVerifier/src/com/android/cts/verifier/managedprovisioning/Utils.java
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/managedprovisioning/Utils.java
@@ -17,17 +17,19 @@
 package com.android.cts.verifier.managedprovisioning;
 
 import android.app.Activity;
+import android.app.AlertDialog;
 import android.app.Notification;
 import android.app.NotificationManager;
-import android.widget.Toast;
+import android.app.admin.DevicePolicyManager;
 import android.content.ActivityNotFoundException;
 import android.content.Context;
+import android.content.DialogInterface;
 import android.content.Intent;
 import android.util.Log;
+import android.widget.Toast;
 
 import com.android.cts.verifier.IntentDrivenTestActivity;
 import com.android.cts.verifier.IntentDrivenTestActivity.ButtonInfo;
-import com.android.cts.verifier.managedprovisioning.ByodHelperActivity;
 import com.android.cts.verifier.R;
 import com.android.cts.verifier.TestListAdapter.TestListItem;
 
@@ -76,4 +78,41 @@
                 .build();
         mNotificationManager.notify(notificationId, notification);
     }
+
+    /**
+     * Prompts the tester to set a screen lock credential, or change it if one exists.
+     *
+     * An instruction dialog is shown before the tester is sent to the ChooseLockGeneric activity
+     * in Settings.
+     *
+     * @param activity The calling activity where the result is handled
+     * @param requestCode The callback request code when the lock is set
+     */
+    static void setScreenLock(Activity activity, int requestCode) {
+        final Intent intent = new Intent(DevicePolicyManager.ACTION_SET_NEW_PASSWORD);
+        new AlertDialog.Builder(activity)
+                .setTitle(R.string.provisioning_byod)
+                .setMessage(R.string.provisioning_byod_set_screen_lock_dialog_message)
+                .setPositiveButton(R.string.go_button_text, (DialogInterface dialog, int which) ->
+                        activity.startActivityForResult(intent, requestCode))
+                .show();
+    }
+
+    /**
+     * Prompts the tester to remove the current screen lock credential.
+     *
+     * An instruction dialog is shown before the tester is sent to the ChooseLockGeneric activity
+     * in Settings.
+     *
+     * @param activity The calling activity
+     */
+    static void removeScreenLock(Activity activity) {
+        final Intent intent = new Intent(DevicePolicyManager.ACTION_SET_NEW_PASSWORD);
+        new AlertDialog.Builder(activity)
+                .setTitle(R.string.provisioning_byod)
+                .setMessage(R.string.provisioning_byod_remove_screen_lock_dialog_message)
+                .setPositiveButton(R.string.go_button_text, (DialogInterface dialog, int which) ->
+                        activity.startActivity(intent))
+                .show();
+    }
 }
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/nfc/hce/SimpleReaderActivity.java b/apps/CtsVerifier/src/com/android/cts/verifier/nfc/hce/SimpleReaderActivity.java
index 4fab77a..8df0061 100644
--- a/apps/CtsVerifier/src/com/android/cts/verifier/nfc/hce/SimpleReaderActivity.java
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/nfc/hce/SimpleReaderActivity.java
@@ -152,7 +152,7 @@
                 });
             }
         } catch (IOException e) {
-            sb.insert(0, "Test failed. IOException (did you keep the devices in range?)\n\n.");
+            sb.insert(0, "Error while reading: (did you keep the devices in range?)\nPlease try again\n.");
             runOnUiThread(new Runnable() {
                 @Override
                 public void run() {
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/notifications/PackagePriorityVerifierActivity.java b/apps/CtsVerifier/src/com/android/cts/verifier/notifications/PackagePriorityVerifierActivity.java
index 5870981..b40ecc6 100644
--- a/apps/CtsVerifier/src/com/android/cts/verifier/notifications/PackagePriorityVerifierActivity.java
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/notifications/PackagePriorityVerifierActivity.java
@@ -39,7 +39,7 @@
     private static final String ACTION_CANCEL = "com.android.cts.robot.ACTION_CANCEL";
     private static final String EXTRA_ID = "ID";
     private static final String EXTRA_NOTIFICATION = "NOTIFICATION";
-    private static final String NOTIFICATION_BOT_PACKAGE = "com.android.cts.robot";
+    static final String NOTIFICATION_BOT_PACKAGE = "com.android.cts.robot";
     private CharSequence mAppLabel;
 
     @Override
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/notifications/ShortcutThrottlingResetActivity.java b/apps/CtsVerifier/src/com/android/cts/verifier/notifications/ShortcutThrottlingResetActivity.java
new file mode 100644
index 0000000..313ebfa
--- /dev/null
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/notifications/ShortcutThrottlingResetActivity.java
@@ -0,0 +1,207 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.cts.verifier.notifications;
+
+import android.content.BroadcastReceiver;
+import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.content.pm.PackageManager;
+import android.os.Bundle;
+import android.util.Log;
+import android.view.View;
+import android.view.ViewGroup;
+
+import com.android.cts.verifier.R;
+
+import java.security.SecureRandom;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.concurrent.atomic.AtomicReference;
+
+/**
+ * Test to make sure, when an inline reply happens, the shortcut manager rate-limiting must
+ * be reset.
+ *
+ * We use the "BOT" apk here, because rate-limiting will be reset when an app shows an activity
+ * too -- so as long as this (or any) test activity is shown, CTS verifier won't be rate-limited.
+ */
+public class ShortcutThrottlingResetActivity extends InteractiveVerifierActivity {
+    private static final String TAG = "ShortcutThrottlingReset";
+
+    private static final String NOTIFICATION_BOT_PACKAGE
+            = PackagePriorityVerifierActivity.NOTIFICATION_BOT_PACKAGE;
+
+    private static final String ACTION_RESET_SETUP_NOTIFICATION =
+            "com.android.cts.robot.ACTION_RESET_SETUP_NOTIFICATION";
+
+    private static final String EXTRA_NOTIFICATION_TITLE = "EXTRA_NOTIFICATION_TITLE";
+    private static final String EXTRA_RESET_REPLY_PACKAGE = "EXTRA_RESET_REPLY_PACKAGE";
+    private static final String EXTRA_RESET_REPLY_ACTION = "EXTRA_RESET_REPLY_ACTION";
+    private static final String EXTRA_RESET_REPLY_ERROR = "EXTRA_RESET_REPLY_ERROR";
+
+    private static final String SUCCESS = "**SUCCESS**";
+
+    private String mReplyAction;
+
+    private final AtomicReference<Intent> mReplyIntent = new AtomicReference<>(null);
+
+    @Override
+    int getTitleResource() {
+        return R.string.shortcut_reset_test;
+    }
+
+    @Override
+    int getInstructionsResource() {
+        return R.string.shortcut_reset_info;
+    }
+
+    @Override
+    protected void onCreate(Bundle savedState) {
+        super.onCreate(savedState);
+
+        // Generate an unique reply action and register the reply receiver.
+        mReplyAction = "reply_" + new SecureRandom().nextLong();
+        final IntentFilter replyFilter = new IntentFilter(mReplyAction);
+        registerReceiver(mReplyReceiver, replyFilter);
+    }
+
+    @Override
+    protected void onDestroy() {
+        unregisterReceiver(mReplyReceiver);
+        super.onDestroy();
+    }
+
+    @Override
+    protected List<InteractiveTestCase> createTestItems() {
+        List<InteractiveTestCase> tests = new ArrayList<>();
+        tests.add(new CheckForBot());
+        tests.add(new SetupNotification());
+        tests.add(new WaitForTestReply());
+        tests.add(new CheckResult());
+        return tests;
+    }
+
+
+    private final BroadcastReceiver mReplyReceiver = new BroadcastReceiver() {
+        @Override
+        public void onReceive(Context context, Intent intent) {
+            Log.i(TAG, "Received reply from robot helper: " + intent);
+            mReplyIntent.set(intent);
+        }
+    };
+
+
+    /** Make sure the helper package is installed. */
+    protected class CheckForBot extends InteractiveTestCase {
+        @Override
+        View inflate(ViewGroup parent) {
+            return createAutoItem(parent, R.string.shortcut_reset_bot);
+        }
+
+        @Override
+        void test() {
+            PackageManager pm = mContext.getPackageManager();
+            try {
+                pm.getPackageInfo(NOTIFICATION_BOT_PACKAGE, 0);
+                status = PASS;
+            } catch (PackageManager.NameNotFoundException e) {
+                status = FAIL;
+                logFail("You must install the CTS Robot helper, aka " + NOTIFICATION_BOT_PACKAGE);
+            }
+            next();
+        }
+    }
+
+    /**
+     * Request the bot apk to show the notification.
+     */
+    protected class SetupNotification extends InteractiveTestCase {
+        @Override
+        View inflate(ViewGroup parent) {
+            return createAutoItem(parent, R.string.shortcut_reset_start);
+        }
+
+        @Override
+        void test() {
+            final Intent intent = new Intent(ACTION_RESET_SETUP_NOTIFICATION);
+            intent.setPackage(NOTIFICATION_BOT_PACKAGE);
+
+            intent.putExtra(EXTRA_NOTIFICATION_TITLE, getResources().getString(getTitleResource()));
+
+            intent.putExtra(EXTRA_RESET_REPLY_PACKAGE, getPackageName());
+            intent.putExtra(EXTRA_RESET_REPLY_ACTION, mReplyAction);
+
+            intent.addFlags(Intent.FLAG_INCLUDE_STOPPED_PACKAGES);
+            sendBroadcast(intent);
+            status = PASS;
+            next();
+        }
+    }
+
+    /**
+     * Let the human tester do an inline reply, and wait for the reply broadcast from the bot apk.
+     */
+    protected class WaitForTestReply extends InteractiveTestCase {
+        @Override
+        View inflate(ViewGroup parent) {
+            return createAutoItem(parent, R.string.shortcut_reset_prompt_inline_reply);
+        }
+
+        @Override
+        void test() {
+            final Intent replyIntent = mReplyIntent.get();
+            if (replyIntent == null) {
+                // Reply not received yet.
+                status = RETEST;
+                delay();
+                return;
+            }
+            status = PASS;
+            next();
+        }
+    }
+
+    /**
+     * Check the reply from the bot apk.
+     */
+    protected class CheckResult extends InteractiveTestCase {
+        @Override
+        View inflate(ViewGroup parent) {
+            return createAutoItem(parent, R.string.shortcut_reset_check_result);
+        }
+
+        @Override
+        void test() {
+            final Intent replyIntent = mReplyIntent.get();
+            if (replyIntent == null) {
+                logFail("Internal error, replyIntent shouldn't be null here.");
+                status = FAIL;
+                return;
+            }
+            final String error = replyIntent.getStringExtra(EXTRA_RESET_REPLY_ERROR);
+            if (SUCCESS.equals(error)) {
+                status = PASS;
+                next();
+                return;
+            }
+            logFail("Test failed. Error message=" + error);
+            status = FAIL;
+            next();
+        }
+    }
+}
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/sensors/BatchingTestActivity.java b/apps/CtsVerifier/src/com/android/cts/verifier/sensors/BatchingTestActivity.java
index 7ef63d7..b7d9617 100644
--- a/apps/CtsVerifier/src/com/android/cts/verifier/sensors/BatchingTestActivity.java
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/sensors/BatchingTestActivity.java
@@ -19,6 +19,7 @@
 import com.android.cts.verifier.R;
 import com.android.cts.verifier.sensors.base.SensorCtsVerifierTestActivity;
 
+import android.content.pm.PackageManager;
 import android.hardware.Sensor;
 import android.hardware.SensorManager;
 import android.hardware.cts.helpers.TestSensorEnvironment;
@@ -82,6 +83,9 @@
 
     @SuppressWarnings("unused")
     public String testProximity_batching() throws Throwable {
+        if (getPackageManager().hasSystemFeature(PackageManager.FEATURE_SENSOR_PROXIMITY)) {
+            return null;
+        }
         return runBatchTest(
                 Sensor.TYPE_PROXIMITY,
                 REPORT_LATENCY_10_SEC,
@@ -90,6 +94,9 @@
 
     @SuppressWarnings("unused")
     public String testProximity_flush() throws Throwable {
+        if (getPackageManager().hasSystemFeature(PackageManager.FEATURE_SENSOR_PROXIMITY)) {
+            return null;
+        }
         return runFlushTest(
                 Sensor.TYPE_PROXIMITY,
                 REPORT_LATENCY_10_SEC,
diff --git a/apps/NotificationBot/AndroidManifest.xml b/apps/NotificationBot/AndroidManifest.xml
index b63791f..0388cbc 100644
--- a/apps/NotificationBot/AndroidManifest.xml
+++ b/apps/NotificationBot/AndroidManifest.xml
@@ -39,10 +39,10 @@
             <intent-filter>
                 <action android:name="com.android.cts.robot.ACTION_POST" />
                 <action android:name="com.android.cts.robot.ACTION_CANCEL" />
+                <action android:name="com.android.cts.robot.ACTION_RESET_SETUP_NOTIFICATION" />
+                <action android:name="com.android.cts.robot.ACTION_INLINE_REPLY" />
             </intent-filter>
         </receiver>
-
-
     </application>
 
 </manifest>
diff --git a/apps/NotificationBot/src/com/android/cts/robot/NotificationBot.java b/apps/NotificationBot/src/com/android/cts/robot/NotificationBot.java
index 2aa5f41..746b840 100644
--- a/apps/NotificationBot/src/com/android/cts/robot/NotificationBot.java
+++ b/apps/NotificationBot/src/com/android/cts/robot/NotificationBot.java
@@ -15,14 +15,23 @@
  */
 package com.android.cts.robot;
 
-import android.app.Activity;
 import android.app.Notification;
+import android.app.Notification.Action;
 import android.app.NotificationManager;
+import android.app.PendingIntent;
+import android.app.RemoteInput;
 import android.content.BroadcastReceiver;
+import android.content.ComponentName;
 import android.content.Context;
 import android.content.Intent;
+import android.content.pm.ShortcutInfo;
+import android.content.pm.ShortcutManager;
+import android.os.SystemClock;
 import android.util.Log;
 
+import java.util.ArrayList;
+import java.util.List;
+
 
 public class NotificationBot extends BroadcastReceiver {
     private static final String TAG = "NotificationBot";
@@ -30,6 +39,21 @@
     private static final String EXTRA_NOTIFICATION = "NOTIFICATION";
     private static final String ACTION_POST = "com.android.cts.robot.ACTION_POST";
     private static final String ACTION_CANCEL = "com.android.cts.robot.ACTION_CANCEL";
+    private static final String ACTION_RESET_SETUP_NOTIFICATION =
+            "com.android.cts.robot.ACTION_RESET_SETUP_NOTIFICATION";
+
+    private static final String ACTION_INLINE_REPLY =
+            "com.android.cts.robot.ACTION_INLINE_REPLY";
+
+    private static final String EXTRA_RESET_REPLY_PACKAGE = "EXTRA_RESET_REPLY_PACKAGE";
+    private static final String EXTRA_RESET_REPLY_ACTION = "EXTRA_RESET_REPLY_ACTION";
+    private static final String EXTRA_NOTIFICATION_TITLE = "EXTRA_NOTIFICATION_TITLE";
+
+    private static final String EXTRA_RESET_REPLY_ERROR = "EXTRA_RESET_REPLY_ERROR";
+
+    private static final String EXTRA_RESET_REQUEST_INTENT = "EXTRA_RESET_REQUEST_INTENT";
+
+    private static final String SUCCESS = "**SUCCESS**";
 
     @Override
     public void onReceive(Context context, Intent intent) {
@@ -60,8 +84,112 @@
                     (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
             noMa.cancel(id);
 
+        } else if (ACTION_RESET_SETUP_NOTIFICATION.equals(intent.getAction())) {
+            testShortcutResetSetupNotification(context, intent);
+
+        } else if (ACTION_INLINE_REPLY.equals(intent.getAction())) {
+            testShortcutResetInlineReplyReceived(context, intent);
+
         } else {
             Log.i(TAG, "received unexpected action: " + intent.getAction());
         }
     }
+
+    /**
+     * Test start request from CTS verifier.  Show a notification with inline reply, which will
+     * trigger {@link #testShortcutResetInlineReplyReceived}.
+     */
+    private static void testShortcutResetSetupNotification(Context context, Intent intent) {
+        final NotificationManager nm = context.getSystemService(NotificationManager.class);
+        nm.cancelAll();
+
+        final ShortcutManager sm = context.getSystemService(ShortcutManager.class);
+
+        final List<ShortcutInfo> EMPTY_LIST = new ArrayList<>();
+
+        long timeout = SystemClock.elapsedRealtime() + 10 * 1000;
+
+        // First, make sure this package is throttled.
+        while (!sm.isRateLimitingActive()) {
+            sm.setDynamicShortcuts(EMPTY_LIST);
+            try {
+                Thread.sleep(0);
+            } catch (InterruptedException e) {
+            }
+            if (SystemClock.elapsedRealtime() >= timeout) {
+                sendShortcutResetReply(context, intent,
+                        "ShortcutMager rate-limiting not activated.");
+                return;
+            }
+        }
+
+        // Show a notification with inline reply.
+        final PendingIntent receiverIntent =
+                PendingIntent.getBroadcast(context, 0,
+                        new Intent(ACTION_INLINE_REPLY)
+                                .setComponent(new ComponentName(context, NotificationBot.class))
+                                .putExtra(EXTRA_RESET_REQUEST_INTENT, intent),
+                        PendingIntent.FLAG_UPDATE_CURRENT);
+        final RemoteInput ri = new RemoteInput.Builder("result")
+                .setLabel("Type something here and press send button").build();
+
+        final Notification.Builder nb = new Notification.Builder(context)
+                .setContentTitle(intent.getStringExtra(EXTRA_NOTIFICATION_TITLE))
+                .setSmallIcon(android.R.drawable.ic_popup_sync)
+                .addAction(new Action.Builder(0,
+                        "Type something here and press send button", receiverIntent)
+                        .addRemoteInput(ri)
+                        .build());
+        context.getSystemService(NotificationManager.class).notify(0, nb.build());
+    }
+
+    /**
+     * Invoked when the inline reply from {@link #testShortcutResetSetupNotification} is performed.
+     *
+     * Check the shortcut manager rate-limiting state, and post the reply to CTS verifier.
+     */
+    private static void testShortcutResetInlineReplyReceived(Context context, Intent intent) {
+        Log.i(TAG, "Inline reply received");
+
+        final NotificationManager nm = context.getSystemService(NotificationManager.class);
+        nm.cancelAll();
+
+        // Close notification shade.
+        context.sendBroadcast(new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS));
+
+        // Check if rate-limiting has been reset.
+        final ShortcutManager sm = context.getSystemService(ShortcutManager.class);
+
+        String error;
+        final boolean success = !sm.isRateLimitingActive();
+        if (success) {
+            error = SUCCESS;
+        } else {
+            error = "Inline reply received, but ShortcutManager rate-limiting is still active.";
+        }
+
+        // Send back the result.
+        sendShortcutResetReply(context,
+                intent.getParcelableExtra(EXTRA_RESET_REQUEST_INTENT), error);
+    }
+
+    /**
+     * Reply an error message, or {@link #SUCCESS} for success, to CTS verifier for shortcut manager
+     * reset rate-limiting test.
+
+     * @param requestIntent original intent sent from the verifier to
+     *     {@link #testShortcutResetSetupNotification}.
+     * @param error error message, or {@link #SUCCESS} if success.
+     */
+    private static void sendShortcutResetReply(Context context, Intent requestIntent, String error) {
+        final Intent replyIntent = new Intent();
+        replyIntent.setAction(requestIntent.getStringExtra(EXTRA_RESET_REPLY_ACTION));
+        replyIntent.putExtra(EXTRA_RESET_REPLY_ERROR, error);
+
+        if (error != null) {
+            Log.e(TAG, error);
+        }
+
+        context.sendBroadcast(replyIntent);
+    }
 }
diff --git a/common/device-side/device-info/src/com/android/compatibility/common/deviceinfo/DeviceInfo.java b/common/device-side/device-info/src/com/android/compatibility/common/deviceinfo/DeviceInfo.java
index 8aa3380..750e45f 100644
--- a/common/device-side/device-info/src/com/android/compatibility/common/deviceinfo/DeviceInfo.java
+++ b/common/device-side/device-info/src/com/android/compatibility/common/deviceinfo/DeviceInfo.java
@@ -87,7 +87,7 @@
                     mResultCode = ResultCode.COMPLETED;
                 }
             } catch (Exception e) {
-                failed("Could not collect device info: " + e.getMessage());
+                failed("Could not collect device info", e);
             }
         }
 
@@ -136,6 +136,12 @@
         Log.e(LOG_TAG, message, exception);
     }
 
+    private void failed(String message, Throwable exception) {
+        mResultCode = ResultCode.FAILED;
+        mErrorMessage = message;
+        Log.e(LOG_TAG, message, exception);
+    }
+
     private void failed(String message) {
         mResultCode = ResultCode.FAILED;
         mErrorMessage = message;
diff --git a/common/device-side/util/src/com/android/compatibility/common/util/DeviceInfoStore.java b/common/device-side/util/src/com/android/compatibility/common/util/DeviceInfoStore.java
index 9f1bda5..735b955 100644
--- a/common/device-side/util/src/com/android/compatibility/common/util/DeviceInfoStore.java
+++ b/common/device-side/util/src/com/android/compatibility/common/util/DeviceInfoStore.java
@@ -135,9 +135,7 @@
      */
     @Override
     public void addResult(String name, float value) throws IOException {
-        checkName(name);
-        mJsonWriter.name(name);
-        mJsonWriter.value(value);
+        addResult(name, (double) value);
     }
 
     /**
@@ -146,8 +144,12 @@
     @Override
     public void addResult(String name, double value) throws IOException {
         checkName(name);
-        mJsonWriter.name(name);
-        mJsonWriter.value(value);
+        if (isDoubleNaNOrInfinite(value)) {
+            return;
+        } else {
+            mJsonWriter.name(name);
+            mJsonWriter.value(value);
+        }
     }
 
     /**
@@ -203,13 +205,11 @@
      */
     @Override
     public void addArrayResult(String name, float[] array) throws IOException {
-        checkName(name);
-        mJsonWriter.name(name);
-        mJsonWriter.beginArray();
-        for (float value : checkArray(array)) {
-            mJsonWriter.value(value);
+        double[] doubleArray = new double[array.length];
+        for (int i = 0; i < array.length; i++) {
+            doubleArray[i] = array[i];
         }
-        mJsonWriter.endArray();
+        addArrayResult(name, doubleArray);
     }
 
     /**
@@ -221,6 +221,9 @@
         mJsonWriter.name(name);
         mJsonWriter.beginArray();
         for (double value : checkArray(array)) {
+            if (isDoubleNaNOrInfinite(value)) {
+                continue;
+            }
             mJsonWriter.value(value);
         }
         mJsonWriter.endArray();
diff --git a/common/host-side/tradefed/src/com/android/compatibility/common/tradefed/command/CompatibilityConsole.java b/common/host-side/tradefed/src/com/android/compatibility/common/tradefed/command/CompatibilityConsole.java
index c67b176..2f255c6 100644
--- a/common/host-side/tradefed/src/com/android/compatibility/common/tradefed/command/CompatibilityConsole.java
+++ b/common/host-side/tradefed/src/com/android/compatibility/common/tradefed/command/CompatibilityConsole.java
@@ -131,6 +131,13 @@
                 addSubPlan(flatArgs);
             }
         }, "a(?:dd)?", "s(?:ubplan)?", null);
+        trie.put(new Runnable() {
+            @Override
+            public void run() {
+                printLine(String.format("Android %s %s (%s)", SuiteInfo.FULLNAME,
+                        SuiteInfo.VERSION, SuiteInfo.BUILD_NUMBER));
+            }
+        }, "version"); // override tradefed 'version' command to print test suite name and version
 
         // find existing help for 'LIST_PATTERN' commands, and append these commands help
         String listHelp = commandHelp.get(LIST_PATTERN);
diff --git a/common/host-side/tradefed/src/com/android/compatibility/common/tradefed/result/ResultReporter.java b/common/host-side/tradefed/src/com/android/compatibility/common/tradefed/result/ResultReporter.java
index 32d3cda..8b4d2ff 100644
--- a/common/host-side/tradefed/src/com/android/compatibility/common/tradefed/result/ResultReporter.java
+++ b/common/host-side/tradefed/src/com/android/compatibility/common/tradefed/result/ResultReporter.java
@@ -705,15 +705,22 @@
     static void copyDynamicConfigFiles(Map<String, File> configFiles, File resultsDir) {
         if (configFiles.size() == 0) return;
 
-        File folder = new File(resultsDir, "config");
-        folder.mkdir();
+        File configDir = new File(resultsDir, "config");
+        boolean mkdirSuccess = configDir.mkdir(); // success check added for b/63030111
+        if (!mkdirSuccess) {
+            warn("Failed to make dynamic config directory \"%s\" in the result",
+                    configDir.getAbsolutePath());
+        }
         for (String moduleName : configFiles.keySet()) {
-            File resultFile = new File(folder, moduleName+".dynamic");
+            File srcFile = configFiles.get(moduleName);
+            File destFile = new File(configDir, moduleName+".dynamic");
             try {
-                FileUtil.copyFile(configFiles.get(moduleName), resultFile);
-                FileUtil.deleteFile(configFiles.get(moduleName));
+                FileUtil.copyFile(srcFile, destFile);
+                FileUtil.deleteFile(srcFile);
             } catch (IOException e) {
-                warn("Failed to copy config file for %s to file", moduleName);
+                warn("Failure when copying config file \"%s\" to \"%s\" for module %s",
+                        srcFile.getAbsolutePath(), destFile.getAbsolutePath(), moduleName);
+                CLog.e(e);
             }
         }
     }
diff --git a/common/util/src/com/android/compatibility/common/util/CddTest.java b/common/util/src/com/android/compatibility/common/util/CddTest.java
new file mode 100644
index 0000000..34ee663
--- /dev/null
+++ b/common/util/src/com/android/compatibility/common/util/CddTest.java
@@ -0,0 +1,31 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.compatibility.common.util;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+/**
+ * Marks the type of test with purpose of asserting CDD requirements.
+ */
+@Retention(RetentionPolicy.RUNTIME)
+@Target({ElementType.METHOD, ElementType.TYPE})
+public @interface CddTest {
+    String requirement();
+}
diff --git a/common/util/src/com/android/compatibility/common/util/InfoStore.java b/common/util/src/com/android/compatibility/common/util/InfoStore.java
index 6c5cc0d..b8014f7 100644
--- a/common/util/src/com/android/compatibility/common/util/InfoStore.java
+++ b/common/util/src/com/android/compatibility/common/util/InfoStore.java
@@ -189,4 +189,8 @@
         }
         return value;
     }
+
+    protected static boolean isDoubleNaNOrInfinite(Double value) {
+        return Double.isNaN(value) || Double.isInfinite(value);
+    }
 }
diff --git a/hostsidetests/appsecurity/src/android/appsecurity/cts/DirectBootHostTest.java b/hostsidetests/appsecurity/src/android/appsecurity/cts/DirectBootHostTest.java
index 99a7e8f..b63b040 100644
--- a/hostsidetests/appsecurity/src/android/appsecurity/cts/DirectBootHostTest.java
+++ b/hostsidetests/appsecurity/src/android/appsecurity/cts/DirectBootHostTest.java
@@ -179,7 +179,7 @@
                     getDevice().executeShellCommand("sm set-emulate-fbe false");
                     getDevice().waitForDeviceOnline();
                 } else {
-                    getDevice().nonBlockingReboot();
+                    getDevice().rebootUntilOnline();
                 }
                 waitForBootCompleted();
             }
@@ -214,12 +214,7 @@
 
     private boolean isSupportedDevice() throws Exception {
         final String featureList = getDevice().executeShellCommand("pm list features");
-        if (featureList.contains("feature:android.hardware.type.watch\n") ||
-                featureList.contains("feature:android.hardware.type.television\n")) {
-            return false;
-        } else {
-            return true;
-        }
+        return featureList.contains("feature:android.software.device_admin\n");
     }
 
     private void waitForBootCompleted() throws Exception {
diff --git a/hostsidetests/appsecurity/src/android/appsecurity/cts/DocumentsTestCase.java b/hostsidetests/appsecurity/src/android/appsecurity/cts/DocumentsTestCase.java
index 7bd42b5..009d81b 100644
--- a/hostsidetests/appsecurity/src/android/appsecurity/cts/DocumentsTestCase.java
+++ b/hostsidetests/appsecurity/src/android/appsecurity/cts/DocumentsTestCase.java
@@ -51,10 +51,7 @@
         assertNotNull(mAbi);
         assertNotNull(mCtsBuild);
 
-        getDevice().uninstallPackage(CLIENT_PKG);
-
-        assertNull(getDevice().installPackage(
-                MigrationHelper.getTestFile(mCtsBuild, CLIENT_APK), false));
+        reinstallClientPackage();
     }
 
     @Override
@@ -68,4 +65,11 @@
             throws DeviceNotAvailableException {
         Utils.runDeviceTests(getDevice(), packageName, testClassName, testMethodName);
     }
+
+    protected void reinstallClientPackage() throws Exception {
+        getDevice().uninstallPackage(CLIENT_PKG);
+
+        assertNull(getDevice().installPackage(
+                MigrationHelper.getTestFile(mCtsBuild, CLIENT_APK), false));
+    }
 }
diff --git a/hostsidetests/appsecurity/src/android/appsecurity/cts/ScopedDirectoryAccessTest.java b/hostsidetests/appsecurity/src/android/appsecurity/cts/ScopedDirectoryAccessTest.java
index ffc7597..889b20b 100644
--- a/hostsidetests/appsecurity/src/android/appsecurity/cts/ScopedDirectoryAccessTest.java
+++ b/hostsidetests/appsecurity/src/android/appsecurity/cts/ScopedDirectoryAccessTest.java
@@ -42,6 +42,14 @@
         runDeviceTests(CLIENT_PKG, ".ScopedDirectoryAccessClientTest", "testNotAskedAgain");
     }
 
+    public void testDeniesOnceForAllClearedWhenPackageRemoved() throws Exception {
+        runDeviceTests(CLIENT_PKG, ".ScopedDirectoryAccessClientTest",
+                "testRemovePackageStep1UserDenies");
+        reinstallClientPackage();
+        runDeviceTests(CLIENT_PKG, ".ScopedDirectoryAccessClientTest",
+                "testRemovePackageStep2UserAcceptsDoNotClear");
+    }
+
     public void testDeniesOnceButAllowsAskingAgain() throws Exception {
         runDeviceTests(CLIENT_PKG, ".ScopedDirectoryAccessClientTest",
                 "testDeniesOnceButAllowsAskingAgain");
diff --git a/hostsidetests/appsecurity/test-apps/DocumentClient/src/com/android/cts/documentclient/DocumentsClientTestCase.java b/hostsidetests/appsecurity/test-apps/DocumentClient/src/com/android/cts/documentclient/DocumentsClientTestCase.java
index e52af73..a26ec2d 100644
--- a/hostsidetests/appsecurity/test-apps/DocumentClient/src/com/android/cts/documentclient/DocumentsClientTestCase.java
+++ b/hostsidetests/appsecurity/test-apps/DocumentClient/src/com/android/cts/documentclient/DocumentsClientTestCase.java
@@ -150,7 +150,15 @@
         return result;
     }
 
+    /**
+     * Clears the DocumentsUI package data, unless test name ends on {@code DoNotClear}.
+     */
     protected void clearDocumentsUi() throws Exception {
+        final String testName = getName();
+        if (testName.endsWith("DoNotClear")) {
+            Log.d(TAG, "Not clearing DocumentsUI due to test name: " + testName);
+            return;
+        }
         executeShellCommand("pm clear com.android.documentsui");
     }
 }
diff --git a/hostsidetests/appsecurity/test-apps/DocumentClient/src/com/android/cts/documentclient/ScopedDirectoryAccessClientTest.java b/hostsidetests/appsecurity/test-apps/DocumentClient/src/com/android/cts/documentclient/ScopedDirectoryAccessClientTest.java
index a4d35fb..dec8769 100644
--- a/hostsidetests/appsecurity/test-apps/DocumentClient/src/com/android/cts/documentclient/ScopedDirectoryAccessClientTest.java
+++ b/hostsidetests/appsecurity/test-apps/DocumentClient/src/com/android/cts/documentclient/ScopedDirectoryAccessClientTest.java
@@ -117,9 +117,9 @@
         if (!supportedHardware()) return;
 
         for (StorageVolume volume : getVolumes()) {
-            userAcceptsOpenExternalDirectoryTest(volume, DIRECTORY_PICTURES);
+            userAcceptsTest(volume, DIRECTORY_PICTURES);
             if (!volume.isPrimary()) {
-                userAcceptsOpenExternalDirectoryTest(volume, DIRECTORY_ROOT);
+                userAcceptsTest(volume, DIRECTORY_ROOT);
             }
         }
     }
@@ -133,7 +133,7 @@
         if (!output.isEmpty()) {
             fail("Command '" + command + "' failed: '" + output + "'");
         }
-        userAcceptsOpenExternalDirectoryTest(getPrimaryVolume(), DIRECTORY_PICTURES);
+        userAcceptsTest(getPrimaryVolume(), DIRECTORY_PICTURES);
     }
 
     public void testNotAskedAgain() throws Exception {
@@ -141,7 +141,7 @@
 
         for (StorageVolume volume : getVolumes()) {
             final String volumeDesc = volume.getDescription(getInstrumentation().getContext());
-            final Uri grantedUri = userAcceptsOpenExternalDirectoryTest(volume, DIRECTORY_PICTURES);
+            final Uri grantedUri = userAcceptsTest(volume, DIRECTORY_PICTURES);
 
             // Calls it again - since the permission has been granted, it should return right
             // away, without popping up the permissions dialog.
@@ -151,7 +151,7 @@
             assertEquals(grantedUri, newData.getData());
 
             // Make sure other directories still require user permission.
-            final Uri grantedUri2 = userAcceptsOpenExternalDirectoryTest(volume, DIRECTORY_ALARMS);
+            final Uri grantedUri2 = userAcceptsTest(volume, DIRECTORY_ALARMS);
             assertNotEqual(grantedUri, grantedUri2);
         }
     }
@@ -162,7 +162,7 @@
         for (StorageVolume volume : getVolumes()) {
             if (volume.isPrimary()) continue;
             final String volumeDesc = volume.getDescription(getInstrumentation().getContext());
-            final Uri grantedRootUri = userAcceptsOpenExternalDirectoryTest(volume, DIRECTORY_ROOT);
+            final Uri grantedRootUri = userAcceptsTest(volume, DIRECTORY_ROOT);
 
             // Calls it again - since the permission has been granted, it should return right
             // away, without popping up the permissions dialog.
@@ -204,7 +204,7 @@
                 assertActivityFailed();
 
                 // Third time is a charm...
-                userAcceptsOpenExternalDirectoryTest(volume, dir);
+                userAcceptsTest(volume, dir);
             }
         }
     }
@@ -216,33 +216,48 @@
         for (StorageVolume volume : getVolumes()) {
             for (String dir : dirs) {
                 if (volume.isPrimary() && dir == DIRECTORY_ROOT) continue;
-                // Rejects the first attempt...
-                UiAlertDialog dialog = openExternalDirectoryValidPath(volume, dir);
-                dialog.assertDoNotAskAgainVisibility(false);
-                dialog.noButton.click();
-                assertActivityFailed();
-
-                // ...and the second, checking the box
-                dialog = openExternalDirectoryValidPath(volume, dir);
-                UiObject checkbox = dialog.assertDoNotAskAgainVisibility(true);
-                assertTrue("checkbox should not be checkable", checkbox.isCheckable());
-                assertFalse("checkbox should not be checked", checkbox.isChecked());
-                checkbox.click();
-                assertTrue("checkbox should be checked", checkbox.isChecked()); // Sanity check
-                assertFalse("allow button should be disabled", dialog.yesButton.isEnabled());
-
-                dialog.noButton.click();
-                assertActivityFailed();
-
-                // Third strike out...
-                sendOpenExternalDirectoryIntent(volume, dir);
-                assertActivityFailed();
+                deniesOnceForAllTest(volume, dir);
             }
         }
     }
 
-    private Uri userAcceptsOpenExternalDirectoryTest(StorageVolume volume, String directoryName)
-            throws Exception {
+    private void deniesOnceForAllTest(StorageVolume volume, String dir) throws Exception {
+        // Rejects the first attempt...
+        UiAlertDialog dialog = openExternalDirectoryValidPath(volume, dir);
+        dialog.assertDoNotAskAgainVisibility(false);
+        dialog.noButton.click();
+        assertActivityFailed();
+
+        // ...and the second, checking the box
+        dialog = openExternalDirectoryValidPath(volume, dir);
+        UiObject checkbox = dialog.assertDoNotAskAgainVisibility(true);
+        assertTrue("checkbox should not be checkable", checkbox.isCheckable());
+        assertFalse("checkbox should not be checked", checkbox.isChecked());
+        checkbox.click();
+        assertTrue("checkbox should be checked", checkbox.isChecked()); // Sanity check
+        assertFalse("allow button should be disabled", dialog.yesButton.isEnabled());
+
+        dialog.noButton.click();
+        assertActivityFailed();
+
+        // Third strike out...
+        sendOpenExternalDirectoryIntent(volume, dir);
+        assertActivityFailed();
+    }
+
+    public void testRemovePackageStep1UserDenies() throws Exception {
+        if (!supportedHardware()) return;
+
+        deniesOnceForAllTest(getPrimaryVolume(), DIRECTORY_NOTIFICATIONS);
+    }
+
+    public void testRemovePackageStep2UserAcceptsDoNotClear() throws Exception {
+        if (!supportedHardware()) return;
+
+        userAcceptsTest(getPrimaryVolume(), DIRECTORY_NOTIFICATIONS);
+    }
+
+    private Uri userAcceptsTest(StorageVolume volume, String directoryName) throws Exception {
         // Asserts dialog contain the proper message.
         final UiAlertDialog dialog = openExternalDirectoryValidPath(volume, directoryName);
         final String message = dialog.messageText.getText();
diff --git a/hostsidetests/appsecurity/test-apps/EncryptionApp/src/com/android/cts/encryptionapp/EncryptionAppTest.java b/hostsidetests/appsecurity/test-apps/EncryptionApp/src/com/android/cts/encryptionapp/EncryptionAppTest.java
index 329f4a2..1d27066 100644
--- a/hostsidetests/appsecurity/test-apps/EncryptionApp/src/com/android/cts/encryptionapp/EncryptionAppTest.java
+++ b/hostsidetests/appsecurity/test-apps/EncryptionApp/src/com/android/cts/encryptionapp/EncryptionAppTest.java
@@ -19,7 +19,6 @@
 import static android.content.pm.PackageManager.MATCH_DIRECT_BOOT_AWARE;
 import static android.content.pm.PackageManager.MATCH_DIRECT_BOOT_UNAWARE;
 
-import android.app.admin.DevicePolicyManager;
 import android.content.BroadcastReceiver;
 import android.content.ComponentName;
 import android.content.Context;
@@ -32,8 +31,6 @@
 import android.os.UserManager;
 import android.provider.Settings;
 import android.support.test.uiautomator.UiDevice;
-import android.support.test.uiautomator.UiObject;
-import android.support.test.uiautomator.UiSelector;
 import android.test.InstrumentationTestCase;
 import android.text.format.DateUtils;
 import android.util.Log;
@@ -43,9 +40,6 @@
 import java.util.concurrent.CountDownLatch;
 import java.util.concurrent.TimeUnit;
 
-// for another encryption ui setting package
-import android.content.pm.ResolveInfo;
-
 public class EncryptionAppTest extends InstrumentationTestCase {
     private static final String TAG = "EncryptionAppTest";
 
@@ -65,9 +59,6 @@
     private UiDevice mDevice;
     private AwareActivity mActivity;
 
-    // for another encryption ui setting package
-    private String mEncryptionSettingPackage = "com.android.settings";
-
     @Override
     public void setUp() throws Exception {
         super.setUp();
@@ -76,13 +67,6 @@
         mDe = mCe.createDeviceProtectedStorageContext();
         mPm = mCe.getPackageManager();
 
-        final Intent intent = new Intent(DevicePolicyManager.ACTION_SET_NEW_PASSWORD);
-        intent.addCategory(Intent.CATEGORY_DEFAULT);
-        ResolveInfo rInfo = mPm.resolveActivity(intent, PackageManager.MATCH_DEFAULT_ONLY);
-        if (rInfo != null) {
-            mEncryptionSettingPackage = rInfo.activityInfo.packageName;
-        }
-
         mDevice = UiDevice.getInstance(getInstrumentation());
         assertNotNull(mDevice);
     }
@@ -108,44 +92,7 @@
         mDevice.waitForIdle();
 
         // Set a PIN for this user
-        final Intent intent = new Intent(DevicePolicyManager.ACTION_SET_NEW_PASSWORD);
-        intent.addCategory(Intent.CATEGORY_DEFAULT);
-        mActivity.startActivity(intent);
-        mDevice.waitForIdle();
-
-        // Pick PIN from the option list
-        UiObject view = new UiObject(new UiSelector()
-                .resourceId(mEncryptionSettingPackage + ":id/lock_pin"));
-        assertTrue("lock_pin", view.waitForExists(TIMEOUT));
-        view.click();
-        mDevice.waitForIdle();
-
-        // Ignore any interstitial options
-        view = new UiObject(new UiSelector()
-                .resourceId(mEncryptionSettingPackage + ":id/encrypt_dont_require_password"));
-        if (view.waitForExists(TIMEOUT)) {
-            view.click();
-            mDevice.waitForIdle();
-        }
-
-        // Yes, we really want to
-        view = new UiObject(new UiSelector()
-                .resourceId(mEncryptionSettingPackage + ":id/next_button"));
-        if (view.waitForExists(TIMEOUT)) {
-            view.click();
-            mDevice.waitForIdle();
-        }
-
-        // Set our PIN
-        view = new UiObject(new UiSelector()
-                .resourceId(mEncryptionSettingPackage + ":id/password_entry"));
-        assertTrue("password_entry", view.waitForExists(TIMEOUT));
-
-        // Enter it twice to confirm
-        enterTestPin();
-        enterTestPin();
-
-        mDevice.pressBack();
+        mDevice.executeShellCommand("locksettings set-pin 12345");
     }
 
     public void testTearDown() throws Exception {
@@ -157,40 +104,7 @@
         mDevice.waitForIdle();
 
         // Clear PIN for this user
-        final Intent intent = new Intent(DevicePolicyManager.ACTION_SET_NEW_PASSWORD);
-        intent.addCategory(Intent.CATEGORY_DEFAULT);
-        mActivity.startActivity(intent);
-        mDevice.waitForIdle();
-
-        // Enter current PIN
-        UiObject view = new UiObject(new UiSelector()
-                .resourceId(mEncryptionSettingPackage + ":id/password_entry"));
-        if (!view.waitForExists(TIMEOUT)) {
-            // Odd, maybe there is a crash dialog showing; try dismissing it
-            mDevice.pressBack();
-            mDevice.waitForIdle();
-
-            assertTrue("password_entry", view.waitForExists(TIMEOUT));
-        }
-
-        enterTestPin();
-
-        // Set back to "none"
-        view = new UiObject(new UiSelector()
-                .resourceId(mEncryptionSettingPackage + ":id/lock_none"));
-        assertTrue("lock_none", view.waitForExists(TIMEOUT));
-        view.click();
-        mDevice.waitForIdle();
-
-        // Yes, we really want to
-        view = new UiObject(new UiSelector()
-                .resourceId("android:id/button1"));
-        if (view.waitForExists(TIMEOUT)) {
-            view.click();
-            mDevice.waitForIdle();
-        }
-
-        mDevice.pressBack();
+        mDevice.executeShellCommand("locksettings clear --old 12345");
     }
 
     public void doBootCountBefore() throws Exception {
diff --git a/hostsidetests/appsecurity/test-apps/ExternalStorageApp/src/com/android/cts/externalstorageapp/ExternalStorageTest.java b/hostsidetests/appsecurity/test-apps/ExternalStorageApp/src/com/android/cts/externalstorageapp/ExternalStorageTest.java
index 6030f1c..13b7bcb 100644
--- a/hostsidetests/appsecurity/test-apps/ExternalStorageApp/src/com/android/cts/externalstorageapp/ExternalStorageTest.java
+++ b/hostsidetests/appsecurity/test-apps/ExternalStorageApp/src/com/android/cts/externalstorageapp/ExternalStorageTest.java
@@ -128,8 +128,12 @@
                     getContext().getExternalFilesDir(Environment.DIRECTORY_DOWNLOADS), "meow");
 
             final long id = dm.enqueue(new Request(source).setDestinationUri(Uri.fromFile(target)));
-            receiver.waitForDownloadComplete(30 * DateUtils.SECOND_IN_MILLIS, id);
-            assertSuccessfulDownload(id, target);
+            try {
+                receiver.waitForDownloadComplete(30 * DateUtils.SECOND_IN_MILLIS, id);
+                assertSuccessfulDownload(id, target);
+            } finally {
+                dm.remove(id);
+            }
         } finally {
             mContext.unregisterReceiver(receiver);
         }
diff --git a/hostsidetests/appsecurity/test-apps/UsePermissionApp23/src/com/android/cts/usepermission/BasePermissionsTest.java b/hostsidetests/appsecurity/test-apps/UsePermissionApp23/src/com/android/cts/usepermission/BasePermissionsTest.java
index 4a6d7f1..4367aff 100755
--- a/hostsidetests/appsecurity/test-apps/UsePermissionApp23/src/com/android/cts/usepermission/BasePermissionsTest.java
+++ b/hostsidetests/appsecurity/test-apps/UsePermissionApp23/src/com/android/cts/usepermission/BasePermissionsTest.java
@@ -38,12 +38,14 @@
 import android.support.test.uiautomator.UiDevice;
 import android.support.test.uiautomator.UiObject;
 import android.support.test.uiautomator.UiObject2;
+import android.support.test.uiautomator.UiScrollable;
 import android.support.test.uiautomator.UiSelector;
 import android.util.ArrayMap;
 import android.util.Log;
 import android.view.accessibility.AccessibilityEvent;
 import android.view.accessibility.AccessibilityNodeInfo;
 import android.widget.Switch;
+import android.widget.ScrollView;
 import junit.framework.Assert;
 import org.junit.Before;
 import org.junit.runner.RunWith;
@@ -128,6 +130,7 @@
 
     private Context mContext;
     private Resources mPlatformResources;
+    private boolean mWatch;
 
     protected static Instrumentation getInstrumentation() {
         return InstrumentationRegistry.getInstrumentation();
@@ -172,6 +175,8 @@
             /* cannot happen */
         }
 
+        mWatch = mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_WATCH);
+
         UiObject2 button = getUiDevice().findObject(By.text("Close"));
         if (button != null) {
             button.click();
@@ -205,11 +210,13 @@
     }
 
     protected void clickAllowButton() throws Exception {
+        scrollToBottomIfWatch();
         getUiDevice().findObject(new UiSelector().resourceId(
                 "com.android.packageinstaller:id/permission_allow_button")).click();
     }
 
     protected void clickDenyButton() throws Exception {
+        scrollToBottomIfWatch();
         getUiDevice().findObject(new UiSelector().resourceId(
                 "com.android.packageinstaller:id/permission_deny_button")).click();
     }
@@ -220,6 +227,7 @@
     }
 
     protected void clickDontAskAgainButton() throws Exception {
+        scrollToBottomIfWatch();
         getUiDevice().findObject(new UiSelector().resourceId(
                 "com.android.packageinstaller:id/permission_deny_dont_ask_again_button")).click();
     }
@@ -240,6 +248,16 @@
         setPermissionGrantState(permissions, false, legacyApp);
     }
 
+    private void scrollToBottomIfWatch() throws Exception {
+        if (mWatch) {
+            UiScrollable scrollable =
+                    new UiScrollable(new UiSelector().className(ScrollView.class));
+            if (scrollable.exists()) {
+                scrollable.flingToEnd(10);
+            }
+        }
+    }
+
     private void setPermissionGrantState(String[] permissions, boolean granted,
             boolean legacyApp) throws Exception {
         getUiDevice().pressBack();
@@ -295,6 +313,7 @@
                 waitForIdle();
 
                 if (wasGranted && legacyApp) {
+                    scrollToBottomIfWatch();
                     String packageName = getInstrumentation().getContext().getPackageManager()
                             .getPermissionControllerPackageName();
                     String resIdName = "com.android.packageinstaller"
@@ -304,7 +323,7 @@
                     final int confirmResId = resources.getIdentifier(resIdName, null, null);
                     String confirmTitle = resources.getString(confirmResId);
                     UiObject denyAnyway = getUiDevice().findObject(new UiSelector()
-                            .text(confirmTitle.toUpperCase()));
+                            .textStartsWith(confirmTitle));
                     denyAnyway.click();
 
                     waitForIdle();
@@ -372,12 +391,16 @@
                 if (result != null) {
                     return result;
                 }
-                while (child.getActionList().contains(AccessibilityAction.ACTION_SCROLL_FORWARD)) {
-                    scrollForward(child);
-                    result = getNodeTimed(() -> findByText(child, text), false);
-                    if (result != null) {
-                        return result;
+                try {
+                    while (child.getActionList().contains(AccessibilityAction.ACTION_SCROLL_FORWARD)) {
+                        scrollForward(child);
+                        result = getNodeTimed(() -> findByText(child, text), false);
+                        if (result != null) {
+                            return result;
+                        }
                     }
+                } catch (TimeoutException e) {
+                     /* ignore */
                 }
             } else {
                 result = findByTextInCollection(child, text);
@@ -400,11 +423,7 @@
     }
 
     private static void scrollForward(AccessibilityNodeInfo node) throws Exception {
-        try {
             scroll(node, true);
-        } catch (TimeoutException e) {
-            /* ignore */
-        }
     }
 
     private static void scroll(AccessibilityNodeInfo node, boolean forward) throws Exception {
@@ -415,6 +434,7 @@
                 (AccessibilityEvent event) -> event.getEventType()
                         == AccessibilityEvent.TYPE_VIEW_SCROLLED,
                 GLOBAL_TIMEOUT_MILLIS);
+        node.refresh();
         waitForIdle();
     }
 
diff --git a/hostsidetests/appsecurity/test-apps/UsePermissionApp23/src/com/android/cts/usepermission/UsePermissionTest23.java b/hostsidetests/appsecurity/test-apps/UsePermissionApp23/src/com/android/cts/usepermission/UsePermissionTest23.java
index fae0a3c..dc528a1 100644
--- a/hostsidetests/appsecurity/test-apps/UsePermissionApp23/src/com/android/cts/usepermission/UsePermissionTest23.java
+++ b/hostsidetests/appsecurity/test-apps/UsePermissionApp23/src/com/android/cts/usepermission/UsePermissionTest23.java
@@ -28,6 +28,7 @@
 import android.Manifest;
 import android.content.pm.PackageManager;
 import android.os.Environment;
+import org.junit.Before;
 import org.junit.Test;
 
 /**
@@ -36,6 +37,16 @@
 public class UsePermissionTest23 extends BasePermissionsTest {
     private static final int REQUEST_CODE_PERMISSIONS = 42;
 
+    private boolean mLeanback;
+    private boolean mWatch;
+
+    @Before
+    public void initialize() {
+        PackageManager pm = getInstrumentation().getContext().getPackageManager();
+        mLeanback = pm.hasSystemFeature(PackageManager.FEATURE_LEANBACK);
+        mWatch = pm.hasSystemFeature(PackageManager.FEATURE_WATCH);
+    }
+
     public void testFail() throws Exception {
         fail("Expected");
     }
@@ -564,12 +575,11 @@
     }
 
     private void denyWithPrejudice() throws Exception {
-        if (!getInstrumentation().getContext().getPackageManager()
-                .hasSystemFeature(PackageManager.FEATURE_LEANBACK)) {
+        if (mLeanback || mWatch) {
+            clickDontAskAgainButton();
+        } else {
             clickDontAskAgainCheckbox();
             clickDenyButton();
-        } else {
-            clickDontAskAgainButton();
         }
     }
 }
diff --git a/hostsidetests/devicepolicy/app/AccountCheck/Android.mk b/hostsidetests/devicepolicy/app/AccountCheck/Android.mk
new file mode 100644
index 0000000..41a41d0
--- /dev/null
+++ b/hostsidetests/devicepolicy/app/AccountCheck/Android.mk
@@ -0,0 +1,17 @@
+#
+# Copyright (C) 2016 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+include $(call all-subdir-makefiles)
diff --git a/hostsidetests/devicepolicy/app/AccountCheck/Auth/Android.mk b/hostsidetests/devicepolicy/app/AccountCheck/Auth/Android.mk
new file mode 100644
index 0000000..207b875
--- /dev/null
+++ b/hostsidetests/devicepolicy/app/AccountCheck/Auth/Android.mk
@@ -0,0 +1,34 @@
+# Copyright (C) 2016 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+LOCAL_PATH:= $(call my-dir)
+
+include $(CLEAR_VARS)
+
+# Tag this module as a cts test artifact
+LOCAL_COMPATIBILITY_SUITE := cts
+
+LOCAL_PACKAGE_NAME := CtsAccountCheckAuthApp
+
+LOCAL_MODULE_TAGS := optional
+
+LOCAL_MODULE_PATH := $(TARGET_OUT_DATA_APPS)
+
+LOCAL_SRC_FILES := $(call all-java-files-under, src)
+
+LOCAL_STATIC_JAVA_LIBRARIES := android-support-v4 ctstestrunner ub-uiautomator android-support-test
+
+LOCAL_SDK_VERSION := current
+
+include $(BUILD_CTS_PACKAGE)
diff --git a/hostsidetests/devicepolicy/app/AccountCheck/Auth/AndroidManifest.xml b/hostsidetests/devicepolicy/app/AccountCheck/Auth/AndroidManifest.xml
new file mode 100644
index 0000000..1f488e5
--- /dev/null
+++ b/hostsidetests/devicepolicy/app/AccountCheck/Auth/AndroidManifest.xml
@@ -0,0 +1,45 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ -->
+
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+    package="com.android.cts.devicepolicy.accountcheck.auth"
+    android:sharedUserId="com.android.cts.devicepolicy.accountcheck.uid">
+
+    <!-- GET_ACCOUNTS may stop working.  Targeting at 25 may prevent it. -->
+    <uses-sdk android:minSdkVersion="25" android:targetSdkVersion="25" />
+
+    <uses-permission android:name="android.permission.GET_ACCOUNTS" />
+    <uses-permission android:name="android.permission.AUTHENTICATE_ACCOUNTS" />
+    <uses-permission android:name="android.permission.MANAGE_ACCOUNTS" />
+
+    <application>
+        <service android:name="com.android.cts.devicepolicy.accountcheck.TestAuthenticator"
+            android:exported="true">
+            <intent-filter>
+                <action android:name="android.accounts.AccountAuthenticator" />
+            </intent-filter>
+
+            <meta-data android:name="android.accounts.AccountAuthenticator"
+                       android:resource="@xml/authenticator" />
+        </service>
+    </application>
+
+    <instrumentation
+        android:name="android.support.test.runner.AndroidJUnitRunner"
+        android:targetPackage="com.android.cts.devicepolicy.accountcheck.auth" />
+</manifest>
+
diff --git a/hostsidetests/devicepolicy/app/AccountCheck/Auth/res/xml/authenticator.xml b/hostsidetests/devicepolicy/app/AccountCheck/Auth/res/xml/authenticator.xml
new file mode 100644
index 0000000..ad963d7
--- /dev/null
+++ b/hostsidetests/devicepolicy/app/AccountCheck/Auth/res/xml/authenticator.xml
@@ -0,0 +1,20 @@
+<!-- Copyright (C) 2016 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+
+<!-- The attributes in this XML file provide configuration information -->
+<!-- for the Account Manager. -->
+
+<account-authenticator xmlns:android="http://schemas.android.com/apk/res/android"
+    android:accountType="com.android.cts.devicepolicy.accountcheck" />
diff --git a/hostsidetests/devicepolicy/app/AccountCheck/Auth/src/com/android/cts/devicepolicy/accountcheck/AccountCheckTest.java b/hostsidetests/devicepolicy/app/AccountCheck/Auth/src/com/android/cts/devicepolicy/accountcheck/AccountCheckTest.java
new file mode 100644
index 0000000..62c0b0b
--- /dev/null
+++ b/hostsidetests/devicepolicy/app/AccountCheck/Auth/src/com/android/cts/devicepolicy/accountcheck/AccountCheckTest.java
@@ -0,0 +1,171 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.cts.devicepolicy.accountcheck;
+
+import android.accounts.Account;
+import android.accounts.AccountManager;
+import android.app.admin.DevicePolicyManager;
+import android.content.ComponentName;
+import android.os.Bundle;
+import android.os.SystemClock;
+import android.test.AndroidTestCase;
+import android.util.Log;
+
+public class AccountCheckTest extends AndroidTestCase {
+    private static final String TAG = "AccountCheckTest";
+
+    private static final String ACCOUNT_TYPE = "com.android.cts.devicepolicy.accountcheck";
+    private static final String ACCOUNT_FEATURE_ALLOWED =
+            "android.account.DEVICE_OR_PROFILE_OWNER_ALLOWED";
+    private static final String ACCOUNT_FEATURE_DISALLOWED =
+            "android.account.DEVICE_OR_PROFILE_OWNER_DISALLOWED";
+
+    private DevicePolicyManager mDevicePolicyManager;
+    private AccountManager mAccountManager;
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+
+        mDevicePolicyManager = getContext().getSystemService(DevicePolicyManager.class);
+        mAccountManager = getContext().getSystemService(AccountManager.class);
+    }
+
+    /**
+     * Remove all test accounts.
+     */
+    public void testRemoveAllAccounts() throws Exception {
+        for (Account account : mAccountManager.getAccountsByType(ACCOUNT_TYPE)) {
+            Log.i(TAG, "Removing account: " + account);
+            mAccountManager.removeAccountExplicitly(account);
+        }
+    }
+
+    private void addAccount(String... features) throws Exception {
+        final Bundle result = mAccountManager.addAccount(
+                ACCOUNT_TYPE,
+                null, // tokentype
+                features,
+                null, // options
+                null, // activity
+                null, // callback
+                null // handler
+        ).getResult();
+        assertEquals(ACCOUNT_TYPE, result.getString(AccountManager.KEY_ACCOUNT_TYPE));
+    }
+
+    /**
+     * Add an incompatible account, type A, no features.
+     */
+    public void testAddIncompatibleA() throws Exception {
+        addAccount();
+    }
+
+    /**
+     * Add an incompatible account, type B.  Disallow feature only.
+     */
+    public void testAddIncompatibleB() throws Exception {
+        addAccount(ACCOUNT_FEATURE_DISALLOWED);
+    }
+
+    /**
+     * Add an incompatible account, type C.  Has the disallow feature.
+     */
+    public void testAddIncompatibleC() throws Exception {
+        addAccount(ACCOUNT_FEATURE_ALLOWED, ACCOUNT_FEATURE_DISALLOWED);
+    }
+
+    /**
+     * Add a compatible account.
+     */
+    public void testAddCompatible() throws Exception {
+        addAccount(ACCOUNT_FEATURE_ALLOWED);
+    }
+
+    /**
+     * Remove the non-test-only (profile|device) owner.  Note this package and the test-only owner
+     * have the same UID, so we can call clearXxX() from this package.
+     */
+    public void testCleanUpNonTestOwner() throws Exception {
+        final ComponentName admin = new ComponentName(
+                "com.android.cts.devicepolicy.accountcheck.nontestonly",
+                "com.android.cts.devicepolicy.accountcheck.owner.AdminReceiver");
+
+        if (mDevicePolicyManager.isDeviceOwnerApp(admin.getPackageName())) {
+            Log.i(TAG, "testCleanUpNonTestOwner: Removing as DO");
+            mDevicePolicyManager.clearDeviceOwnerApp(admin.getPackageName());
+        }
+
+        if (mDevicePolicyManager.isProfileOwnerApp(admin.getPackageName())) {
+            Log.i(TAG, "testCleanUpNonTestOwner: Removing as PO");
+            mDevicePolicyManager.clearProfileOwner(admin);
+        }
+
+        if (mDevicePolicyManager.isAdminActive(admin)) {
+            Log.i(TAG, "testCleanUpNonTestOwner: Removing as DA");
+            mDevicePolicyManager.removeActiveAdmin(admin);
+
+            final long timeout = SystemClock.elapsedRealtime() + 60 * 1000;
+            while (SystemClock.elapsedRealtime() < timeout
+                    && mDevicePolicyManager.isAdminActive(admin)) {
+                Thread.sleep(100);
+            }
+        }
+        // Give the system a breath.
+        Thread.sleep(5000);
+    }
+
+    /**
+     * Test there are no preconfigured accounts that don't accept DO/PO.
+     */
+    public void testCheckPreconfiguredAccountFeatures() {
+        final AccountManager am = AccountManager.get(mContext);
+        final Account accounts[] = am.getAccounts();
+        if (accounts.length == 0) {
+            Log.v(TAG, "No preconfigured accounts found.");
+            return; // pass.
+        }
+        final String[] feature_allow =
+                {"android.account.DEVICE_OR_PROFILE_OWNER_ALLOWED"};
+        final String[] feature_disallow =
+                {"android.account.DEVICE_OR_PROFILE_OWNER_DISALLOWED"};
+
+        // Even if we find incompatible accounts along the way, we still check all accounts
+        // for logging.
+        final StringBuilder error = new StringBuilder();
+        for (Account account : accounts) {
+            Log.v(TAG, "Checking " + account);
+            if (hasAccountFeatures(am, account, feature_disallow)) {
+                error.append(account + " has " + feature_disallow[0] + "\n");
+            }
+            if (!hasAccountFeatures(am, account, feature_allow)) {
+                error.append(account + " doesn't have " + feature_allow[0] + "\n");
+            }
+        }
+        if (error.length() > 0) {
+            fail(error.toString());
+        }
+    }
+
+    private boolean hasAccountFeatures(AccountManager am, Account account, String[] features) {
+        try {
+            return am.hasFeatures(account, features, null, null).getResult();
+        } catch (Exception e) {
+            Log.w(TAG, "Failed to get account feature", e);
+            return false;
+        }
+    }
+}
diff --git a/hostsidetests/devicepolicy/app/AccountCheck/Auth/src/com/android/cts/devicepolicy/accountcheck/TestAuthenticator.java b/hostsidetests/devicepolicy/app/AccountCheck/Auth/src/com/android/cts/devicepolicy/accountcheck/TestAuthenticator.java
new file mode 100644
index 0000000..31c79d7
--- /dev/null
+++ b/hostsidetests/devicepolicy/app/AccountCheck/Auth/src/com/android/cts/devicepolicy/accountcheck/TestAuthenticator.java
@@ -0,0 +1,135 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.cts.devicepolicy.accountcheck;
+
+import android.accounts.AbstractAccountAuthenticator;
+import android.accounts.Account;
+import android.accounts.AccountAuthenticatorResponse;
+import android.accounts.AccountManager;
+import android.accounts.NetworkErrorException;
+import android.app.Service;
+import android.content.Context;
+import android.content.Intent;
+import android.os.Bundle;
+import android.os.IBinder;
+import android.os.SystemClock;
+import android.text.TextUtils;
+import android.util.Log;
+
+import java.util.Arrays;
+import java.util.List;
+
+public class TestAuthenticator extends Service {
+    private static final String TAG = "TestAuthenticator";
+
+    private static Authenticator sInstance;
+
+    @Override
+    public IBinder onBind(Intent intent) {
+        if (sInstance == null) {
+            sInstance = new Authenticator(getApplicationContext());
+
+        }
+        return sInstance.getIBinder();
+    }
+
+    public static class Authenticator extends AbstractAccountAuthenticator {
+
+        private final Context mContxet;
+
+        public Authenticator(Context context) {
+            super(context);
+            mContxet = context;
+        }
+
+        @Override
+        public Bundle addAccount(AccountAuthenticatorResponse response, String accountType,
+                String authTokenType, String[] requiredFeatures, Bundle options)
+                throws NetworkErrorException {
+
+            // Create an account whose name is:
+            //   [current time] + ":" + [all requested features concatenated with , ]
+
+            if (requiredFeatures == null) {
+                requiredFeatures = new String[0];
+            }
+
+            final String name = SystemClock.elapsedRealtimeNanos()
+                    + ":" + TextUtils.join(",", requiredFeatures);
+
+            Log.v(TAG, "Adding account '" + name + "' for " + accountType
+                    + "... " + Arrays.asList(requiredFeatures));
+
+            Bundle result = new Bundle();
+            result.putString(AccountManager.KEY_ACCOUNT_TYPE, accountType);
+            result.putString(AccountManager.KEY_ACCOUNT_NAME, name);
+
+            mContxet.getSystemService(AccountManager.class).addAccountExplicitly(
+                    new Account(name, accountType), "password", new Bundle());
+
+            return result;
+        }
+
+        @Override
+        public Bundle editProperties(AccountAuthenticatorResponse response, String accountType) {
+            return new Bundle();
+        }
+
+        @Override
+        public Bundle updateCredentials(AccountAuthenticatorResponse response, Account account,
+                String authTokenType, Bundle options) throws NetworkErrorException {
+            return new Bundle();
+        }
+
+        @Override
+        public Bundle confirmCredentials(AccountAuthenticatorResponse response, Account account,
+                Bundle options) throws NetworkErrorException {
+            return new Bundle();
+        }
+
+        @Override
+        public Bundle getAuthToken(AccountAuthenticatorResponse response, Account account,
+                String authTokenType, Bundle options) throws NetworkErrorException {
+            return new Bundle();
+        }
+
+        @Override
+        public String getAuthTokenLabel(String authTokenType) {
+            return "token_label";
+        }
+
+        @Override
+        public Bundle hasFeatures(AccountAuthenticatorResponse response, Account account,
+                String[] features) throws NetworkErrorException {
+
+            final int p = account.name.indexOf(':');
+
+            boolean hasAll = true;
+            final List<String> hasFeatures =
+                    Arrays.asList(TextUtils.split(account.name.substring(p + 1), ","));
+            for (String requested : features) {
+                if (!hasFeatures.contains(requested)) {
+                    hasAll = false;
+                    break;
+                }
+            }
+
+            Bundle result = new Bundle();
+            result.putBoolean(AccountManager.KEY_BOOLEAN_RESULT, hasAll);
+            return result;
+        }
+    }
+}
diff --git a/hostsidetests/devicepolicy/app/AccountCheck/NonTestOnlyOwner/Android.mk b/hostsidetests/devicepolicy/app/AccountCheck/NonTestOnlyOwner/Android.mk
new file mode 100644
index 0000000..26e6dca
--- /dev/null
+++ b/hostsidetests/devicepolicy/app/AccountCheck/NonTestOnlyOwner/Android.mk
@@ -0,0 +1,34 @@
+# Copyright (C) 2016 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+LOCAL_PATH:= $(call my-dir)
+
+include $(CLEAR_VARS)
+
+# Tag this module as a cts test artifact
+LOCAL_COMPATIBILITY_SUITE := cts
+
+LOCAL_PACKAGE_NAME := CtsAccountCheckNonTestOnlyOwnerApp
+
+LOCAL_MODULE_TAGS := optional
+
+LOCAL_MODULE_PATH := $(TARGET_OUT_DATA_APPS)
+
+LOCAL_SRC_FILES := $(call all-java-files-under, ../src-owner)
+
+LOCAL_STATIC_JAVA_LIBRARIES := android-support-v4 ctstestrunner ub-uiautomator android-support-test
+
+LOCAL_SDK_VERSION := current
+
+include $(BUILD_CTS_PACKAGE)
diff --git a/hostsidetests/devicepolicy/app/AccountCheck/NonTestOnlyOwner/AndroidManifest.xml b/hostsidetests/devicepolicy/app/AccountCheck/NonTestOnlyOwner/AndroidManifest.xml
new file mode 100644
index 0000000..6b130b5
--- /dev/null
+++ b/hostsidetests/devicepolicy/app/AccountCheck/NonTestOnlyOwner/AndroidManifest.xml
@@ -0,0 +1,37 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ -->
+
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+    package="com.android.cts.devicepolicy.accountcheck.nontestonly"
+    android:sharedUserId="com.android.cts.devicepolicy.accountcheck.uid">
+
+    <application android:testOnly="false">
+        <receiver
+            android:name="com.android.cts.devicepolicy.accountcheck.owner.AdminReceiver"
+            android:permission="android.permission.BIND_DEVICE_ADMIN">
+            <meta-data android:name="android.app.device_admin"
+                android:resource="@xml/device_admin" />
+            <intent-filter>
+                <action android:name="android.app.action.DEVICE_ADMIN_ENABLED" />
+            </intent-filter>
+        </receiver>
+    </application>
+    <!--
+      Don't need instrumentation. All the three device side apps have the same UID, so we're able
+      to run all tests from the Auth package.
+    -->
+</manifest>
diff --git a/hostsidetests/devicepolicy/app/AccountCheck/NonTestOnlyOwner/res/xml/device_admin.xml b/hostsidetests/devicepolicy/app/AccountCheck/NonTestOnlyOwner/res/xml/device_admin.xml
new file mode 100644
index 0000000..98e7028
--- /dev/null
+++ b/hostsidetests/devicepolicy/app/AccountCheck/NonTestOnlyOwner/res/xml/device_admin.xml
@@ -0,0 +1,16 @@
+<!-- Copyright (C) 2016 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+<device-admin xmlns:android="http://schemas.android.com/apk/res/android" android:visible="false">
+</device-admin>
diff --git a/hostsidetests/devicepolicy/app/AccountCheck/TestOnlyOwner/Android.mk b/hostsidetests/devicepolicy/app/AccountCheck/TestOnlyOwner/Android.mk
new file mode 100644
index 0000000..eeba939
--- /dev/null
+++ b/hostsidetests/devicepolicy/app/AccountCheck/TestOnlyOwner/Android.mk
@@ -0,0 +1,34 @@
+# Copyright (C) 2016 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+LOCAL_PATH:= $(call my-dir)
+
+include $(CLEAR_VARS)
+
+# Tag this module as a cts test artifact
+LOCAL_COMPATIBILITY_SUITE := cts
+
+LOCAL_PACKAGE_NAME := CtsAccountCheckTestOnlyOwnerApp
+
+LOCAL_MODULE_TAGS := optional
+
+LOCAL_MODULE_PATH := $(TARGET_OUT_DATA_APPS)
+
+LOCAL_SRC_FILES := $(call all-java-files-under, ../src-owner)
+
+LOCAL_STATIC_JAVA_LIBRARIES := android-support-v4 ctstestrunner ub-uiautomator android-support-test
+
+LOCAL_SDK_VERSION := current
+
+include $(BUILD_CTS_PACKAGE)
diff --git a/hostsidetests/devicepolicy/app/AccountCheck/TestOnlyOwner/AndroidManifest.xml b/hostsidetests/devicepolicy/app/AccountCheck/TestOnlyOwner/AndroidManifest.xml
new file mode 100644
index 0000000..a9673e9
--- /dev/null
+++ b/hostsidetests/devicepolicy/app/AccountCheck/TestOnlyOwner/AndroidManifest.xml
@@ -0,0 +1,37 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ -->
+
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+    package="com.android.cts.devicepolicy.accountcheck.testonly"
+    android:sharedUserId="com.android.cts.devicepolicy.accountcheck.uid">
+
+    <application android:testOnly="true">
+        <receiver
+            android:name="com.android.cts.devicepolicy.accountcheck.owner.AdminReceiver"
+            android:permission="android.permission.BIND_DEVICE_ADMIN">
+            <meta-data android:name="android.app.device_admin"
+                android:resource="@xml/device_admin" />
+            <intent-filter>
+                <action android:name="android.app.action.DEVICE_ADMIN_ENABLED" />
+            </intent-filter>
+        </receiver>
+    </application>
+    <!--
+      Don't need instrumentation. All the three device side apps have the same UID, so we're able
+      to run all tests from the Auth package.
+    -->
+</manifest>
diff --git a/hostsidetests/devicepolicy/app/AccountCheck/TestOnlyOwner/res/xml/device_admin.xml b/hostsidetests/devicepolicy/app/AccountCheck/TestOnlyOwner/res/xml/device_admin.xml
new file mode 100644
index 0000000..98e7028
--- /dev/null
+++ b/hostsidetests/devicepolicy/app/AccountCheck/TestOnlyOwner/res/xml/device_admin.xml
@@ -0,0 +1,16 @@
+<!-- Copyright (C) 2016 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+<device-admin xmlns:android="http://schemas.android.com/apk/res/android" android:visible="false">
+</device-admin>
diff --git a/hostsidetests/devicepolicy/app/AccountCheck/TestOnlyOwnerUpdate/Android.mk b/hostsidetests/devicepolicy/app/AccountCheck/TestOnlyOwnerUpdate/Android.mk
new file mode 100644
index 0000000..a86a98b
--- /dev/null
+++ b/hostsidetests/devicepolicy/app/AccountCheck/TestOnlyOwnerUpdate/Android.mk
@@ -0,0 +1,34 @@
+# Copyright (C) 2016 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+LOCAL_PATH:= $(call my-dir)
+
+include $(CLEAR_VARS)
+
+# Tag this module as a cts test artifact
+LOCAL_COMPATIBILITY_SUITE := cts
+
+LOCAL_PACKAGE_NAME := CtsAccountCheckTestOnlyOwnerUpdateApp
+
+LOCAL_MODULE_TAGS := optional
+
+LOCAL_MODULE_PATH := $(TARGET_OUT_DATA_APPS)
+
+LOCAL_SRC_FILES := $(call all-java-files-under, ../src-owner)
+
+LOCAL_STATIC_JAVA_LIBRARIES := android-support-v4 ctstestrunner ub-uiautomator android-support-test
+
+LOCAL_SDK_VERSION := current
+
+include $(BUILD_CTS_PACKAGE)
diff --git a/hostsidetests/devicepolicy/app/AccountCheck/TestOnlyOwnerUpdate/AndroidManifest.xml b/hostsidetests/devicepolicy/app/AccountCheck/TestOnlyOwnerUpdate/AndroidManifest.xml
new file mode 100644
index 0000000..cd186e9
--- /dev/null
+++ b/hostsidetests/devicepolicy/app/AccountCheck/TestOnlyOwnerUpdate/AndroidManifest.xml
@@ -0,0 +1,39 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ -->
+
+<!-- This package is exactly same as TestOnlyOwner, except for testOnly=false -->
+
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+    package="com.android.cts.devicepolicy.accountcheck.testonly"
+    android:sharedUserId="com.android.cts.devicepolicy.accountcheck.uid">
+
+    <application android:testOnly="false">
+        <receiver
+            android:name="com.android.cts.devicepolicy.accountcheck.owner.AdminReceiver"
+            android:permission="android.permission.BIND_DEVICE_ADMIN">
+            <meta-data android:name="android.app.device_admin"
+                android:resource="@xml/device_admin" />
+            <intent-filter>
+                <action android:name="android.app.action.DEVICE_ADMIN_ENABLED" />
+            </intent-filter>
+        </receiver>
+    </application>
+    <!--
+      Don't need instrumentation. All the three device side apps have the same UID, so we're able
+      to run all tests from the Auth package.
+    -->
+</manifest>
diff --git a/hostsidetests/devicepolicy/app/AccountCheck/TestOnlyOwnerUpdate/res/xml/device_admin.xml b/hostsidetests/devicepolicy/app/AccountCheck/TestOnlyOwnerUpdate/res/xml/device_admin.xml
new file mode 100644
index 0000000..98e7028
--- /dev/null
+++ b/hostsidetests/devicepolicy/app/AccountCheck/TestOnlyOwnerUpdate/res/xml/device_admin.xml
@@ -0,0 +1,16 @@
+<!-- Copyright (C) 2016 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+<device-admin xmlns:android="http://schemas.android.com/apk/res/android" android:visible="false">
+</device-admin>
diff --git a/hostsidetests/devicepolicy/app/AccountCheck/src-owner/com/android/cts/devicepolicy/accountcheck/owner/AdminReceiver.java b/hostsidetests/devicepolicy/app/AccountCheck/src-owner/com/android/cts/devicepolicy/accountcheck/owner/AdminReceiver.java
new file mode 100644
index 0000000..bf2ec17
--- /dev/null
+++ b/hostsidetests/devicepolicy/app/AccountCheck/src-owner/com/android/cts/devicepolicy/accountcheck/owner/AdminReceiver.java
@@ -0,0 +1,21 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.cts.devicepolicy.accountcheck.owner;
+
+import android.app.admin.DeviceAdminReceiver;
+
+public class AdminReceiver extends DeviceAdminReceiver {
+}
diff --git a/hostsidetests/devicepolicy/app/DeviceAdmin/src/com.android.cts.deviceadmin/DeviceAdminPasswordTest.java b/hostsidetests/devicepolicy/app/DeviceAdmin/src/com.android.cts.deviceadmin/DeviceAdminPasswordTest.java
index 2d1197b..26d89c0 100644
--- a/hostsidetests/devicepolicy/app/DeviceAdmin/src/com.android.cts.deviceadmin/DeviceAdminPasswordTest.java
+++ b/hostsidetests/devicepolicy/app/DeviceAdmin/src/com.android.cts.deviceadmin/DeviceAdminPasswordTest.java
@@ -68,20 +68,22 @@
     }
 
     private void assertHasPassword() {
-        dpm.setPasswordMinimumLength(mAdminComponent, 1);
+        final int currentQuality = dpm.getPasswordQuality(mAdminComponent);
+        dpm.setPasswordQuality(mAdminComponent, DevicePolicyManager.PASSWORD_QUALITY_SOMETHING);
         try {
             assertTrue("No password set", dpm.isActivePasswordSufficient());
         } finally {
-            dpm.setPasswordMinimumLength(mAdminComponent, 0);
+            dpm.setPasswordQuality(mAdminComponent, currentQuality);
         }
     }
 
     private void assertNoPassword() {
-        dpm.setPasswordMinimumLength(mAdminComponent, 1);
+        final int currentQuality = dpm.getPasswordQuality(mAdminComponent);
+        dpm.setPasswordQuality(mAdminComponent, DevicePolicyManager.PASSWORD_QUALITY_SOMETHING);
         try {
             assertFalse("Password is set", dpm.isActivePasswordSufficient());
         } finally {
-            dpm.setPasswordMinimumLength(mAdminComponent, 0);
+            dpm.setPasswordQuality(mAdminComponent, currentQuality);
         }
     }
 
diff --git a/hostsidetests/devicepolicy/app/DeviceAdmin/src/com.android.cts.deviceadmin/DeviceOwnerPasswordTest.java b/hostsidetests/devicepolicy/app/DeviceAdmin/src/com.android.cts.deviceadmin/DeviceOwnerPasswordTest.java
index 18db8df..6a01ea6 100644
--- a/hostsidetests/devicepolicy/app/DeviceAdmin/src/com.android.cts.deviceadmin/DeviceOwnerPasswordTest.java
+++ b/hostsidetests/devicepolicy/app/DeviceAdmin/src/com.android.cts.deviceadmin/DeviceOwnerPasswordTest.java
@@ -56,8 +56,9 @@
         dpm.setPasswordMinimumLength(mAdminComponent, 10);
         caseDescription = "minimum password length = 10";
         assertEquals(10, dpm.getPasswordMinimumLength(mAdminComponent));
-        assertPasswordSufficiency(false); // length not checked for this quality
+        assertPasswordSufficiency(true); // length not checked for this quality
 
+        // TODO(ascull): fix resetPassword() logic so these succeed
         assertPasswordFails("1234", caseDescription);
         assertPasswordFails("abcd", caseDescription);
         assertPasswordFails("abcd1234", caseDescription);
diff --git a/hostsidetests/devicepolicy/app/DeviceAndProfileOwner/latest/AndroidManifest.xml b/hostsidetests/devicepolicy/app/DeviceAndProfileOwner/latest/AndroidManifest.xml
index 744db8f..632899d 100644
--- a/hostsidetests/devicepolicy/app/DeviceAndProfileOwner/latest/AndroidManifest.xml
+++ b/hostsidetests/devicepolicy/app/DeviceAndProfileOwner/latest/AndroidManifest.xml
@@ -39,8 +39,6 @@
             </intent-filter>
         </receiver>
         <activity
-            android:name="com.android.cts.deviceandprofileowner.ScreenCaptureDisabledActivity" />
-        <activity
             android:name="com.android.cts.deviceandprofileowner.ExampleIntentReceivingActivity1">
             <intent-filter>
                 <action android:name="com.android.cts.deviceandprofileowner.EXAMPLE_ACTION" />
diff --git a/hostsidetests/devicepolicy/app/DeviceAndProfileOwner/src/com/android/cts/deviceandprofileowner/AlwaysOnVpnMultiStageTest.java b/hostsidetests/devicepolicy/app/DeviceAndProfileOwner/src/com/android/cts/deviceandprofileowner/AlwaysOnVpnMultiStageTest.java
index f6604ee..0b20c64 100644
--- a/hostsidetests/devicepolicy/app/DeviceAndProfileOwner/src/com/android/cts/deviceandprofileowner/AlwaysOnVpnMultiStageTest.java
+++ b/hostsidetests/devicepolicy/app/DeviceAndProfileOwner/src/com/android/cts/deviceandprofileowner/AlwaysOnVpnMultiStageTest.java
@@ -47,8 +47,9 @@
             VpnTestHelper.tryPosixConnect(TEST_ADDRESS);
             fail("sendIcmpMessage doesn't throw Exception during network lockdown");
         } catch (ErrnoException e) {
-            // Os.connect returns ENETUNREACH errno after the vpn app process is killed
-            assertEquals(OsConstants.ENETUNREACH, e.errno);
+            // Os.connect returns ENETUNREACH or EACCES errno after the vpn app process is killed
+            assertTrue((e.errno == OsConstants.ENETUNREACH) ||
+                       (e.errno == OsConstants.EACCES));
         }
     }
 
diff --git a/hostsidetests/devicepolicy/app/DeviceAndProfileOwner/src/com/android/cts/deviceandprofileowner/ScreenCaptureDisabledActivity.java b/hostsidetests/devicepolicy/app/DeviceAndProfileOwner/src/com/android/cts/deviceandprofileowner/ScreenCaptureDisabledActivity.java
deleted file mode 100644
index b5b4fdc..0000000
--- a/hostsidetests/devicepolicy/app/DeviceAndProfileOwner/src/com/android/cts/deviceandprofileowner/ScreenCaptureDisabledActivity.java
+++ /dev/null
@@ -1,34 +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.deviceandprofileowner;
-
-import android.app.Activity;
-import android.content.Intent;
-
-/**
- * Test activity for setScreenCaptureDisabled().
- */
-public class ScreenCaptureDisabledActivity extends Activity {
-
-    static final String ACTIVITY_RESUMED =
-            "com.android.cts.deviceandprofileowner.ACTIVITY_RESUMED";
-
-    @Override
-    protected void onResume() {
-        super.onResume();
-        sendBroadcast(new Intent(ACTIVITY_RESUMED));
-    }
-}
diff --git a/hostsidetests/devicepolicy/app/DeviceAndProfileOwner/src/com/android/cts/deviceandprofileowner/ScreenCaptureDisabledTest.java b/hostsidetests/devicepolicy/app/DeviceAndProfileOwner/src/com/android/cts/deviceandprofileowner/ScreenCaptureDisabledTest.java
index e2deaa4..b7f9066 100644
--- a/hostsidetests/devicepolicy/app/DeviceAndProfileOwner/src/com/android/cts/deviceandprofileowner/ScreenCaptureDisabledTest.java
+++ b/hostsidetests/devicepolicy/app/DeviceAndProfileOwner/src/com/android/cts/deviceandprofileowner/ScreenCaptureDisabledTest.java
@@ -16,16 +16,8 @@
 package com.android.cts.deviceandprofileowner;
 
 import android.app.admin.DevicePolicyManager;
-import android.content.BroadcastReceiver;
-import android.content.ComponentName;
-import android.content.Context;
-import android.content.Intent;
-import android.content.IntentFilter;
 import android.util.Log;
 
-import java.util.concurrent.Semaphore;
-import java.util.concurrent.TimeUnit;
-
 /**
  * Tests for {@link DevicePolicyManager#setScreenCaptureDisabled} and
  * {@link DevicePolicyManager#getScreenCaptureDisabled} APIs.
@@ -34,66 +26,23 @@
 
     private static final String TAG = "ScreenCaptureDisabledTest";
 
-    private ScreenCaptureBroadcastReceiver mReceiver = new ScreenCaptureBroadcastReceiver();
-
-    protected void setUp() throws Exception {
-        super.setUp();
-        mContext.registerReceiver(mReceiver, new IntentFilter(
-                ScreenCaptureDisabledActivity.ACTIVITY_RESUMED));
-    }
-
-    protected void tearDown() throws Exception {
-        mContext.unregisterReceiver(mReceiver);
-        super.tearDown();
-    }
-
     public void testSetScreenCaptureDisabled_false() throws Exception {
         mDevicePolicyManager.setScreenCaptureDisabled(ADMIN_RECEIVER_COMPONENT, false);
         assertFalse(mDevicePolicyManager.getScreenCaptureDisabled(ADMIN_RECEIVER_COMPONENT));
         assertFalse(mDevicePolicyManager.getScreenCaptureDisabled(null /* any admin */));
-        startTestActivity();
-        assertNotNull(getInstrumentation().getUiAutomation().takeScreenshot());
     }
 
     public void testSetScreenCaptureDisabled_true() throws Exception {
         mDevicePolicyManager.setScreenCaptureDisabled(ADMIN_RECEIVER_COMPONENT, true);
         assertTrue(mDevicePolicyManager.getScreenCaptureDisabled(ADMIN_RECEIVER_COMPONENT));
         assertTrue(mDevicePolicyManager.getScreenCaptureDisabled(null /* any admin */));
-        startTestActivity();
+    }
+
+    public void testScreenCaptureImpossible() throws Exception {
         assertNull(getInstrumentation().getUiAutomation().takeScreenshot());
     }
 
     public void testScreenCapturePossible() throws Exception {
         assertNotNull(getInstrumentation().getUiAutomation().takeScreenshot());
     }
-
-    // We need to launch an activity before trying to take a screen shot, because screenshots are
-    // only blocked on a per-user basis in the profile owner case depending on the owner of the
-    // foreground activity.
-    private void startTestActivity() throws Exception {
-        Intent launchIntent = new Intent();
-        launchIntent.setComponent(new ComponentName(PACKAGE_NAME,
-                ScreenCaptureDisabledActivity.class.getName()));
-        launchIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
-        mContext.startActivity(launchIntent);
-        assertTrue(mReceiver.waitForBroadcast());
-        Thread.sleep(1000);
-    }
-
-    private class ScreenCaptureBroadcastReceiver extends BroadcastReceiver {
-        private final Semaphore mSemaphore = new Semaphore(0);
-
-        @Override
-        public void onReceive(Context context, Intent intent) {
-            Log.d(TAG, "Broadcast received");
-            mSemaphore.release();
-        }
-
-        public boolean waitForBroadcast() throws Exception {
-            if (mSemaphore.tryAcquire(5, TimeUnit.SECONDS)) {
-                return true;
-            }
-            return false;
-        }
-    }
 }
diff --git a/hostsidetests/devicepolicy/app/DeviceOwner/src/com/android/cts/deviceowner/LockTaskTest.java b/hostsidetests/devicepolicy/app/DeviceOwner/src/com/android/cts/deviceowner/LockTaskTest.java
index f6f8dbbc..4b4faec 100644
--- a/hostsidetests/devicepolicy/app/DeviceOwner/src/com/android/cts/deviceowner/LockTaskTest.java
+++ b/hostsidetests/devicepolicy/app/DeviceOwner/src/com/android/cts/deviceowner/LockTaskTest.java
@@ -48,7 +48,7 @@
     private static final int ACTIVITY_RESUMED_TIMEOUT_MILLIS = 20000;  // 20 seconds
     private static final int ACTIVITY_RUNNING_TIMEOUT_MILLIS = 10000;  // 10 seconds
     private static final int ACTIVITY_DESTROYED_TIMEOUT_MILLIS = 60000;  // 60 seconds
-    private static final int UPDATE_LOCK_TASK_TIMEOUT_MILLIS = 1000; // 1 second
+    private static final int UPDATE_LOCK_TASK_TIMEOUT_MILLIS = 2000; // 2 second
     public static final String RECEIVING_ACTIVITY_CREATED_ACTION
             = "com.android.cts.deviceowner.RECEIVING_ACTIVITY_CREATED_ACTION";
     /**
diff --git a/hostsidetests/devicepolicy/app/SimpleApp/src/com/android/cts/launcherapps/simpleapp/SimpleActivity.java b/hostsidetests/devicepolicy/app/SimpleApp/src/com/android/cts/launcherapps/simpleapp/SimpleActivity.java
index 628a2cd..918094c 100644
--- a/hostsidetests/devicepolicy/app/SimpleApp/src/com/android/cts/launcherapps/simpleapp/SimpleActivity.java
+++ b/hostsidetests/devicepolicy/app/SimpleApp/src/com/android/cts/launcherapps/simpleapp/SimpleActivity.java
@@ -20,6 +20,7 @@
 import android.content.Intent;
 import android.os.Bundle;
 import android.util.Log;
+import android.view.WindowManager;
 
 import java.lang.Override;
 
@@ -35,6 +36,7 @@
     @Override
     public void onCreate(Bundle icicle) {
         super.onCreate(icicle);
+        getWindow().addFlags(WindowManager.LayoutParams.FLAG_DISMISS_KEYGUARD);
         Log.i(TAG, "Created for user " + android.os.Process.myUserHandle());
     }
 
diff --git a/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/AccountCheckHostSideTest.java b/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/AccountCheckHostSideTest.java
new file mode 100644
index 0000000..0ce2ab7
--- /dev/null
+++ b/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/AccountCheckHostSideTest.java
@@ -0,0 +1,278 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.cts.devicepolicy;
+
+import com.android.tradefed.log.LogUtil.CLog;
+
+import junit.framework.AssertionFailedError;
+
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+public class AccountCheckHostSideTest extends BaseDevicePolicyTest {
+    private static final String APK_NON_TEST_ONLY = "CtsAccountCheckNonTestOnlyOwnerApp.apk";
+    private static final String APK_TEST_ONLY = "CtsAccountCheckTestOnlyOwnerApp.apk";
+    private static final String APK_TEST_ONLY_UPDATE = "CtsAccountCheckTestOnlyOwnerUpdateApp.apk";
+    private static final String APK_AUTH = "CtsAccountCheckAuthApp.apk";
+
+    private static final String PACKAGE_NON_TEST_ONLY =
+            "com.android.cts.devicepolicy.accountcheck.nontestonly";
+    private static final String PACKAGE_TEST_ONLY =
+            "com.android.cts.devicepolicy.accountcheck.testonly";
+    private static final String PACKAGE_AUTH = "com.android.cts.devicepolicy.accountcheck.auth";
+
+    private static final String OWNER_TEST_ONLY = PACKAGE_TEST_ONLY
+            + "/com.android.cts.devicepolicy.accountcheck.owner.AdminReceiver";
+    private static final String OWNER_NON_TEST_ONLY = PACKAGE_NON_TEST_ONLY
+            + "/com.android.cts.devicepolicy.accountcheck.owner.AdminReceiver";
+
+    private static final String TEST_CLASS =
+            "com.android.cts.devicepolicy.accountcheck.AccountCheckTest";
+
+    @Override
+    protected void tearDown() throws Exception {
+        if (mHasFeature) {
+            if (getDevice().getInstalledPackageNames().contains(PACKAGE_AUTH)) {
+                runCleanupTestOnlyOwnerAllowingFailure();
+                runCleanupNonTestOnlyOwnerAllowingFailure();
+
+                // This shouldn't be needed since we're uninstalling the authenticator,
+                // but sometimes the account manager fails to clean up?
+                removeAllAccountsAllowingFailure();
+            }
+
+            getDevice().uninstallPackage(PACKAGE_AUTH);
+            getDevice().uninstallPackage(PACKAGE_TEST_ONLY);
+            getDevice().uninstallPackage(PACKAGE_NON_TEST_ONLY);
+        }
+        super.tearDown();
+    }
+
+    private void runTest(String method) throws Exception {
+        assertTrue(runDeviceTests(PACKAGE_AUTH, TEST_CLASS, method));
+    }
+
+    private void runCleanupTestOnlyOwner() throws Exception {
+        assertTrue(removeAdmin(OWNER_TEST_ONLY, mPrimaryUserId));
+    }
+
+    private void runCleanupTestOnlyOwnerAllowingFailure() throws Exception {
+        try {
+            runCleanupTestOnlyOwner();
+        } catch (AssertionFailedError ignore) {
+        }
+    }
+
+    private void runCleanupNonTestOnlyOwner() throws Exception {
+        runTest("testCleanUpNonTestOwner");
+    }
+
+    private void runCleanupNonTestOnlyOwnerAllowingFailure() throws Exception {
+        try {
+            runCleanupNonTestOnlyOwner();
+        } catch (AssertionFailedError ignore) {
+        }
+    }
+
+    private void removeAllAccounts() throws Exception {
+        runTest("testRemoveAllAccounts");
+    }
+
+    private void removeAllAccountsAllowingFailure() throws Exception {
+        try {
+            removeAllAccounts();
+        } catch (AssertionFailedError ignore) {
+        }
+    }
+
+    private void assertTestOnlyInstallable() throws Exception {
+        setDeviceOwnerOrFail(OWNER_TEST_ONLY, mPrimaryUserId);
+        runCleanupTestOnlyOwner();
+
+        setProfileOwnerOrFail(OWNER_TEST_ONLY, mPrimaryUserId);
+        runCleanupTestOnlyOwner();
+    }
+
+    private void assertNonTestOnlyInstallable() throws Exception {
+        setDeviceOwnerOrFail(OWNER_NON_TEST_ONLY, mPrimaryUserId);
+        runCleanupNonTestOnlyOwner();
+
+        setProfileOwnerOrFail(OWNER_NON_TEST_ONLY, mPrimaryUserId);
+        runCleanupNonTestOnlyOwner();
+    }
+
+    private void assertTestOnlyNotInstallable() throws Exception {
+        setDeviceOwnerExpectingFailure(OWNER_TEST_ONLY, mPrimaryUserId);
+        runCleanupTestOnlyOwnerAllowingFailure();
+
+        setProfileOwnerExpectingFailure(OWNER_TEST_ONLY, mPrimaryUserId);
+        runCleanupTestOnlyOwnerAllowingFailure();
+    }
+
+    private void assertNonTestOnlyNotInstallable() throws Exception {
+        setDeviceOwnerExpectingFailure(OWNER_NON_TEST_ONLY, mPrimaryUserId);
+        runCleanupNonTestOnlyOwnerAllowingFailure();
+
+        setProfileOwnerExpectingFailure(OWNER_NON_TEST_ONLY, mPrimaryUserId);
+        runCleanupNonTestOnlyOwnerAllowingFailure();
+    }
+
+    private boolean hasAccounts() throws Exception {
+        final String accountDump = getDevice().executeShellCommand("dumpsys account");
+
+        final Pattern p = Pattern.compile("^\\s*Accounts\\:\\s*(\\d+)", Pattern.MULTILINE);
+        final Matcher m = p.matcher(accountDump);
+        if (!m.find()) {
+            fail("Unable to obtain # of accounts");
+            return true;
+        }
+        final String count = m.group(1);
+
+        CLog.i("# of preconfigured accounts=" + count);
+
+        return Integer.parseInt(count) > 0;
+    }
+
+    public void testAccountCheck() throws Exception {
+        if (!mHasFeature) {
+            return;
+        }
+        installAppAsUser(APK_AUTH, mPrimaryUserId);
+        installAppAsUser(APK_NON_TEST_ONLY, mPrimaryUserId);
+        installAppAsUser(APK_TEST_ONLY, mPrimaryUserId);
+
+        runCleanupTestOnlyOwnerAllowingFailure();
+        runCleanupNonTestOnlyOwnerAllowingFailure();
+        removeAllAccountsAllowingFailure();
+        try {
+//            runTest("testCheckPreconfiguredAccountFeatures");
+//
+//            final boolean hasPreconfiguredAccounts = hasAccounts();
+//
+//            // All pre-configured accounts must be "compatible", so the test-only owner can be
+//            // installed.
+//            assertTestOnlyInstallable();
+//
+//            if (hasPreconfiguredAccounts) {
+//                assertNonTestOnlyNotInstallable();
+//            } else {
+//                assertNonTestOnlyInstallable();
+//            }
+//
+            // Incompatible, type A.
+            runTest("testAddIncompatibleA");
+
+            assertTestOnlyNotInstallable();
+            assertNonTestOnlyNotInstallable();
+
+            // The following tests use non-public strings, so disabled until they go public.
+//            // Incompatible, type B.
+//            removeAllAccounts();
+//            runTest("testAddIncompatibleB");
+//
+//            assertTestOnlyNotInstallable();
+//            assertNonTestOnlyNotInstallable();
+//
+//            // Incompatible, type C.
+//            removeAllAccounts();
+//            runTest("testAddIncompatibleC");
+//
+//            assertTestOnlyNotInstallable();
+//            assertNonTestOnlyNotInstallable();
+//
+//            // Compatible.
+//            removeAllAccounts();
+//            runTest("testAddCompatible");
+//
+//            assertTestOnlyInstallable(); // Now test-only owner can be accepted.
+//            assertNonTestOnlyNotInstallable();
+//
+//            // 2 compatible accounts.
+//            removeAllAccounts();
+//            runTest("testAddCompatible");
+//            runTest("testAddCompatible");
+//
+//            assertTestOnlyInstallable(); // Now test-only owner can be accepted.
+//
+//            assertNonTestOnlyNotInstallable();
+//
+//            // 2 compatible accounts + 1 incompatible.
+//            removeAllAccounts();
+//            runTest("testAddIncompatibleA");
+//            runTest("testAddCompatible");
+//            runTest("testAddCompatible");
+//
+//            assertTestOnlyNotInstallable();
+//            assertNonTestOnlyNotInstallable();
+//
+//            // 2 compatible accounts + 1 incompatible, different order.
+//            removeAllAccounts();
+//            runTest("testAddCompatible");
+//            runTest("testAddCompatible");
+//            runTest("testAddIncompatibleB");
+//
+//            assertTestOnlyNotInstallable();
+//            assertNonTestOnlyNotInstallable();
+        } catch (Throwable th) {
+            CLog.w("Tests failed; current accounts are:");
+            CLog.w(getDevice().executeShellCommand("dumpsys account"));
+
+            // Dump accounts
+            throw th;
+        }
+    }
+
+    /**
+     * Make sure even if the "test-only" flag changes when an app is updated, we still respect
+     * the original value.
+     */
+    public void testInheritTestOnly() throws Exception {
+        if (!mHasFeature) {
+            return;
+        }
+        installAppAsUser(APK_TEST_ONLY, mPrimaryUserId);
+
+        // Set as DO.
+        try {
+            setDeviceOwnerOrFail(OWNER_TEST_ONLY, mPrimaryUserId);
+        } catch (Throwable e) {
+            CLog.e("Unable to install DO, can't continue the test. Skipping.  hasAccounts="
+                    + hasAccounts());
+            return;
+        }
+        try {
+
+            // Override with a package that's not test-only.
+            installAppAsUser(APK_TEST_ONLY_UPDATE, mPrimaryUserId);
+
+            // But DPMS keeps the original test-only flag, so it's still removable.
+            runCleanupTestOnlyOwner();
+
+            return;
+        } catch (Throwable e) {
+            // If failed, re-install the APK with test-only=true.
+            try {
+                installAppAsUser(APK_TEST_ONLY, mPrimaryUserId);
+                runCleanupTestOnlyOwner();
+            } catch (Exception inner) {
+                CLog.e("Unable to clean up after a failure: " + e.getMessage());
+            }
+
+            throw e;
+        }
+    }
+}
diff --git a/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/BaseDevicePolicyTest.java b/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/BaseDevicePolicyTest.java
index 70206ee..85e1f7d 100644
--- a/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/BaseDevicePolicyTest.java
+++ b/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/BaseDevicePolicyTest.java
@@ -17,8 +17,6 @@
 package com.android.cts.devicepolicy;
 
 import com.android.cts.migration.MigrationHelper;
-import com.android.ddmlib.Log.LogLevel;
-import com.android.ddmlib.testrunner.InstrumentationResultParser;
 import com.android.ddmlib.testrunner.RemoteAndroidTestRunner;
 import com.android.ddmlib.testrunner.TestIdentifier;
 import com.android.ddmlib.testrunner.TestResult;
@@ -26,21 +24,17 @@
 import com.android.ddmlib.testrunner.TestRunResult;
 import com.android.tradefed.build.IBuildInfo;
 import com.android.tradefed.device.DeviceNotAvailableException;
-import com.android.tradefed.device.ITestDevice;
 import com.android.tradefed.log.LogUtil.CLog;
 import com.android.tradefed.result.CollectingTestListener;
 import com.android.tradefed.testtype.DeviceTestCase;
 import com.android.tradefed.testtype.IBuildReceiver;
 
-import java.io.File;
 import java.io.FileNotFoundException;
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.Collections;
 import java.util.HashSet;
 import java.util.Map;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
 
 import javax.annotation.Nullable;
 
@@ -229,6 +223,12 @@
         return runDeviceTestsAsUser(pkgName, testClassName, testMethodName, userId, params);
     }
 
+    protected boolean runDeviceTests(
+            String pkgName, @Nullable String testClassName, String testMethodName)
+            throws DeviceNotAvailableException {
+        return runDeviceTestsAsUser(pkgName, testClassName, testMethodName, mPrimaryUserId);
+    }
+
     protected boolean runDeviceTestsAsUser(String pkgName, @Nullable String testClassName,
             @Nullable String testMethodName, int userId,
             Map<String, String> params) throws DeviceNotAvailableException {
@@ -410,11 +410,23 @@
     protected void setProfileOwnerOrFail(String componentName, int userId)
             throws Exception {
         if (!setProfileOwner(componentName, userId, /*expectFailure*/ false)) {
-            removeUser(userId);
+            if (userId != 0) { // don't remove system user.
+                removeUser(userId);
+            }
             fail("Failed to set profile owner");
         }
     }
 
+    protected void setProfileOwnerExpectingFailure(String componentName, int userId)
+            throws Exception {
+        if (setProfileOwner(componentName, userId, /* expectFailure =*/ true)) {
+            if (userId != 0) { // don't remove system user.
+                removeUser(userId);
+            }
+            fail("Setting profile owner should have failed.");
+        }
+    }
+
     private String setDeviceAdminInner(String componentName, int userId)
             throws DeviceNotAvailableException {
         String command = "dpm set-active-admin --user " + userId + " '" + componentName + "'";
@@ -454,6 +466,16 @@
         return success;
     }
 
+    protected void setDeviceOwnerOrFail(String componentName, int userId)
+            throws Exception {
+        assertTrue(setDeviceOwner(componentName, userId, /* expectFailure =*/ false));
+    }
+
+    protected void setDeviceOwnerExpectingFailure(String componentName, int userId)
+            throws Exception {
+        assertFalse(setDeviceOwner(componentName, userId, /* expectFailure =*/ true));
+    }
+
     protected String getSettings(String namespace, String name, int userId)
             throws DeviceNotAvailableException {
         String command = "settings --user " + userId + " get " + namespace + " " + name;
diff --git a/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/DeviceAndProfileOwnerTest.java b/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/DeviceAndProfileOwnerTest.java
index d36e473..7427570 100644
--- a/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/DeviceAndProfileOwnerTest.java
+++ b/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/DeviceAndProfileOwnerTest.java
@@ -106,6 +106,7 @@
             getDevice().uninstallPackage(INTENT_RECEIVER_PKG);
             getDevice().uninstallPackage(INTENT_SENDER_PKG);
             getDevice().uninstallPackage(CUSTOMIZATION_APP_PKG);
+            getDevice().uninstallPackage(TEST_APP_PKG);
 
             // Press the HOME key to close any alart dialog that may be shown.
             getDevice().executeShellCommand("input keyevent 3");
@@ -288,11 +289,9 @@
         // We need to ensure that the policy is deactivated for the device owner case, so making
         // sure the second test is run even if the first one fails
         try {
-            executeDeviceTestMethod(".ScreenCaptureDisabledTest",
-                    "testSetScreenCaptureDisabled_true");
+            setScreenCaptureDisabled(mUserId, true);
         } finally {
-            executeDeviceTestMethod(".ScreenCaptureDisabledTest",
-                    "testSetScreenCaptureDisabled_false");
+            setScreenCaptureDisabled(mUserId, false);
         }
     }
 
@@ -457,6 +456,10 @@
         if (!mHasFeature) {
             return;
         }
+        boolean mIsWatch = hasDeviceFeature("android.hardware.type.watch");
+        if (mIsWatch) {
+            return;
+        }
         // UserManager.DISALLOW_INSTALL_UNKNOWN_SOURCES
         final String DISALLOW_INSTALL_UNKNOWN_SOURCES = "no_install_unknown_sources";
         final String UNKNOWN_SOURCES_SETTING = "install_non_market_apps";
@@ -496,12 +499,7 @@
             putSettings(SECURE_SETTING_CATEGORY, PACKAGE_VERIFIER_USER_CONSENT_SETTING, "-1",
                     mUserId);
             putSettings(GLOBAL_SETTING_CATEGORY, PACKAGE_VERIFIER_ENABLE_SETTING, "0", mUserId);
-            assertEquals("1",
-                    getSettings(SECURE_SETTING_CATEGORY, UNKNOWN_SOURCES_SETTING, mUserId));
-            assertEquals("-1", getSettings(SECURE_SETTING_CATEGORY,
-                    PACKAGE_VERIFIER_USER_CONSENT_SETTING, mUserId));
-            assertEquals("0", getSettings(GLOBAL_SETTING_CATEGORY,
-                    PACKAGE_VERIFIER_ENABLE_SETTING, mUserId));
+            // Skip verifying above setting values as some of them may be overrided.
             assertTrue(runDeviceTestsAsUser(PACKAGE_INSTALLER_PKG, ".ManualPackageInstallTest",
                     "testManualInstallSucceeded", mUserId));
         } finally {
@@ -617,4 +615,38 @@
         assertTrue("Command was expected to succeed " + commandOutput,
                 commandOutput.contains("Status: ok"));
     }
+
+    /**
+     * Start SimpleActivity synchronously in a particular user.
+     */
+    protected void startScreenCaptureDisabledActivity(int userId) throws Exception {
+        installAppAsUser(TEST_APP_APK, userId);
+        String command = "am start -W --user " + userId + " " + TEST_APP_PKG + "/"
+                + TEST_APP_PKG + ".SimpleActivity";
+        getDevice().executeShellCommand(command);
+    }
+
+    // TODO: Remove this after investigation in b/28995242 is done
+    // So we can check which one is the top window / activity.
+    private void runDumpsysWindow() throws Exception {
+        String command = "dumpsys window displays";
+        CLog.d("Output for command " + command + ": " + getDevice().executeShellCommand(command));
+        command = "dumpsys activity a";
+        CLog.d("Output for command " + command + ": " + getDevice().executeShellCommand(command));
+    }
+
+    protected void setScreenCaptureDisabled(int userId, boolean disabled) throws Exception {
+        String testMethodName = disabled
+                ? "testSetScreenCaptureDisabled_true"
+                : "testSetScreenCaptureDisabled_false";
+        executeDeviceTestMethod(".ScreenCaptureDisabledTest", testMethodName);
+        startScreenCaptureDisabledActivity(userId);
+        // [b/28995242], dump windows to make sure the top window is
+        // ScreenCaptureDisabledActivity.
+        runDumpsysWindow();
+        testMethodName = disabled
+                ? "testScreenCaptureImpossible"
+                : "testScreenCapturePossible";
+        executeDeviceTestMethod(".ScreenCaptureDisabledTest", testMethodName);
+    }
 }
diff --git a/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/MixedManagedProfileOwnerTest.java b/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/MixedManagedProfileOwnerTest.java
index b467aed..afc4e34 100644
--- a/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/MixedManagedProfileOwnerTest.java
+++ b/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/MixedManagedProfileOwnerTest.java
@@ -73,29 +73,13 @@
         if (!mHasFeature) {
             return;
         }
-        runDumpsysWindow();
-        try {
-            executeDeviceTestMethod(".ScreenCaptureDisabledTest",
-                    "testSetScreenCaptureDisabled_true");
-            // start the ScreenCaptureDisabledActivity in the parent
-            installAppAsUser(DEVICE_ADMIN_APK, mParentUserId);
-            String command = "am start -W --user " + mParentUserId + " " + DEVICE_ADMIN_PKG + "/"
-                    + DEVICE_ADMIN_PKG + ".ScreenCaptureDisabledActivity";
-            getDevice().executeShellCommand(command);
-            executeDeviceTestMethod(".ScreenCaptureDisabledTest", "testScreenCapturePossible");
-        } catch (AssertionError e) {
-            runDumpsysWindow();
-            CLog.e("testScreenCaptureDisabled_allowedPrimaryUser failed", e);
-            fail("testScreenCaptureDisabled_allowedPrimaryUser failed");
-        }
-    }
+        // disable screen capture in profile
+        setScreenCaptureDisabled(mUserId, true);
 
-    // TODO: Remove this after investigation in b/28995242 is done
-    private void runDumpsysWindow() throws Exception {
-        String command = "dumpsys window displays";
-        CLog.d("Output for command " + command + ": " + getDevice().executeShellCommand(command));
-        command = "dumpsys window policy";
-        CLog.d("Output for command " + command + ": " + getDevice().executeShellCommand(command));
+        // start the ScreenCaptureDisabledActivity in the parent
+        installAppAsUser(DEVICE_ADMIN_APK, mParentUserId);
+        startScreenCaptureDisabledActivity(mParentUserId);
+        executeDeviceTestMethod(".ScreenCaptureDisabledTest", "testScreenCapturePossible");
     }
 
     @Override
diff --git a/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/UserRestrictionsTest.java b/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/UserRestrictionsTest.java
index 789ce87..bc61a81 100644
--- a/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/UserRestrictionsTest.java
+++ b/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/UserRestrictionsTest.java
@@ -45,7 +45,8 @@
                         removeAdmin(DEVICE_ADMIN_PKG + "/" + ADMIN_RECEIVER_TEST_CLASS,
                                 mDeviceOwnerUserId));
                 assertTrue("Some user restrictions are still set",
-                        runTests("userrestrictions.CheckNoOwnerRestrictionsTest", mDeviceOwnerUserId));
+                        runTests("userrestrictions.CheckNoOwnerRestrictionsTest",
+                                mDeviceOwnerUserId));
             }
 
             // DO/PO might have set DISALLOW_REMOVE_USER, so it needs to be done after removing
diff --git a/hostsidetests/net/app/src/com/android/cts/net/hostside/AbstractAppIdleTestCase.java b/hostsidetests/net/app/src/com/android/cts/net/hostside/AbstractAppIdleTestCase.java
index fb773cb..831b387 100644
--- a/hostsidetests/net/app/src/com/android/cts/net/hostside/AbstractAppIdleTestCase.java
+++ b/hostsidetests/net/app/src/com/android/cts/net/hostside/AbstractAppIdleTestCase.java
@@ -16,6 +16,7 @@
 
 package com.android.cts.net.hostside;
 
+import android.os.SystemClock;
 import android.util.Log;
 
 /**
@@ -129,4 +130,42 @@
         assertsForegroundAlwaysHasNetworkAccess();
         assertBackgroundNetworkAccess(true);
     }
+
+    public void testAppIdleNetworkAccess_whenCharging() throws Exception {
+        if (!isSupported()) return;
+
+        // Check that app is paroled when charging
+        setAppIdle(true);
+        assertBackgroundNetworkAccess(false);
+        turnBatteryOn();
+        assertBackgroundNetworkAccess(true);
+        turnBatteryOff();
+        assertBackgroundNetworkAccess(false);
+
+        // Check that app is restricted when not idle but power-save is on
+        setAppIdle(false);
+        assertBackgroundNetworkAccess(true);
+        setBatterySaverMode(true);
+        assertBackgroundNetworkAccess(false);
+        // Use setBatterySaverMode API to leave power-save mode instead of plugging in charger
+        setBatterySaverMode(false);
+        turnBatteryOn();
+        assertBackgroundNetworkAccess(true);
+
+        // And when no longer charging, it still has network access, since it's not idle
+        turnBatteryOff();
+        assertBackgroundNetworkAccess(true);
+    }
+
+    public void testAppIdle_toast() throws Exception {
+        if (!isSupported()) return;
+
+        setAppIdle(true);
+        assertAppIdle(true);
+        assertEquals("Shown", showToast());
+        assertAppIdle(true);
+        // Wait for a couple of seconds for the toast to actually be shown
+        SystemClock.sleep(2000);
+        assertAppIdle(true);
+    }
 }
diff --git a/hostsidetests/net/app/src/com/android/cts/net/hostside/AbstractBatterySaverModeTestCase.java b/hostsidetests/net/app/src/com/android/cts/net/hostside/AbstractBatterySaverModeTestCase.java
index ed738a6..b5637be 100644
--- a/hostsidetests/net/app/src/com/android/cts/net/hostside/AbstractBatterySaverModeTestCase.java
+++ b/hostsidetests/net/app/src/com/android/cts/net/hostside/AbstractBatterySaverModeTestCase.java
@@ -84,16 +84,24 @@
         assertsForegroundAlwaysHasNetworkAccess();
         assertBackgroundNetworkAccess(false);
 
-        // Make sure foreground app doesn't lose access upon enabling it.
+        // Make sure foreground app doesn't lose access upon Battery Saver.
         setBatterySaverMode(false);
         launchActivity();
         assertForegroundNetworkAccess();
         setBatterySaverMode(true);
         assertForegroundNetworkAccess();
+
+        // Although it should not have access while the screen is off.
+        turnScreenOff();
+        assertBackgroundNetworkAccess(false);
+        turnScreenOn();
+        assertForegroundNetworkAccess();
+
+        // Goes back to background state.
         finishActivity();
         assertBackgroundNetworkAccess(false);
 
-        // Same for foreground service.
+        // Make sure foreground service doesn't lose access upon enabling Battery Saver.
         setBatterySaverMode(false);
         startForegroundService();
         assertForegroundNetworkAccess();
diff --git a/hostsidetests/net/app/src/com/android/cts/net/hostside/AbstractRestrictBackgroundNetworkTestCase.java b/hostsidetests/net/app/src/com/android/cts/net/hostside/AbstractRestrictBackgroundNetworkTestCase.java
index bd93232..c01736f 100644
--- a/hostsidetests/net/app/src/com/android/cts/net/hostside/AbstractRestrictBackgroundNetworkTestCase.java
+++ b/hostsidetests/net/app/src/com/android/cts/net/hostside/AbstractRestrictBackgroundNetworkTestCase.java
@@ -29,6 +29,7 @@
 import android.content.BroadcastReceiver;
 import android.content.Context;
 import android.content.Intent;
+import android.content.pm.PackageManager;
 import android.net.ConnectivityManager;
 import android.net.NetworkInfo;
 import android.net.NetworkInfo.DetailedState;
@@ -64,6 +65,8 @@
             "com.android.cts.net.hostside.app2.action.RECEIVER_READY";
     static final String ACTION_SEND_NOTIFICATION =
             "com.android.cts.net.hostside.app2.action.SEND_NOTIFICATION";
+    static final String ACTION_SHOW_TOAST =
+            "com.android.cts.net.hostside.app2.action.SHOW_TOAST";
     private static final String EXTRA_ACTION = "com.android.cts.net.hostside.app2.extra.ACTION";
     private static final String EXTRA_RECEIVER_NAME =
             "com.android.cts.net.hostside.app2.extra.RECEIVER_NAME";
@@ -97,6 +100,8 @@
     protected WifiManager mWfm;
     protected int mUid;
     private String mMeteredWifi;
+    private boolean mHasWatch;
+    private String mDeviceIdleConstantsSetting;
     private boolean mSupported;
 
     @Override
@@ -109,6 +114,13 @@
         mWfm = (WifiManager) mContext.getSystemService(Context.WIFI_SERVICE);
         mUid = getUid(TEST_APP2_PKG);
         final int myUid = getUid(mContext.getPackageName());
+        mHasWatch = mContext.getPackageManager().hasSystemFeature(
+                PackageManager.FEATURE_WATCH);
+        if (mHasWatch) {
+            mDeviceIdleConstantsSetting = "device_idle_constants_watch";
+        } else {
+            mDeviceIdleConstantsSetting = "device_idle_constants";
+        }
         mSupported = setUpActiveNetworkMeteringState();
 
         Log.i(TAG, "Apps status on " + getName() + ":\n"
@@ -248,7 +260,7 @@
             if (isBackground(state.state)) {
                 return;
             }
-            Log.d(TAG, "App not on background state on attempt #" + i
+            Log.d(TAG, "App not on background state (" + state + ") on attempt #" + i
                     + "; sleeping 1s before trying again");
             SystemClock.sleep(SECOND_IN_MS);
         }
@@ -764,14 +776,14 @@
     }
 
     protected void setPendingIntentWhitelistDuration(int durationMs) throws Exception {
-        final String command = String.format(
-                "settings put global device_idle_constants %s=%d",
-                "notification_whitelist_duration", durationMs);
-        executeSilentShellCommand(command);
+        executeSilentShellCommand(String.format(
+                "settings put global %s %s=%d", mDeviceIdleConstantsSetting,
+                "notification_whitelist_duration", durationMs));
     }
 
     protected void resetDeviceIdleSettings() throws Exception {
-        executeShellCommand("settings delete global device_idle_constants");
+        executeShellCommand(String.format("settings delete global %s",
+                mDeviceIdleConstantsSetting));
     }
 
     protected void startForegroundService() throws Exception {
@@ -823,6 +835,17 @@
         mContext.sendBroadcast(intent);
     }
 
+    protected String showToast() {
+        final Intent intent = new Intent(ACTION_SHOW_TOAST);
+        intent.setPackage(TEST_APP2_PKG);
+        Log.d(TAG, "Sending request to show toast");
+        try {
+            return sendOrderedBroadcast(intent, 3 * SECOND_IN_MS);
+        } catch (Exception e) {
+            return "";
+        }
+    }
+
     private String toString(int status) {
         switch (status) {
             case RESTRICT_BACKGROUND_STATUS_DISABLED:
diff --git a/hostsidetests/net/app/src/com/android/cts/net/hostside/DataSaverModeTest.java b/hostsidetests/net/app/src/com/android/cts/net/hostside/DataSaverModeTest.java
index ac35bd4..9e4b0c1 100644
--- a/hostsidetests/net/app/src/com/android/cts/net/hostside/DataSaverModeTest.java
+++ b/hostsidetests/net/app/src/com/android/cts/net/hostside/DataSaverModeTest.java
@@ -102,16 +102,24 @@
         assertsForegroundAlwaysHasNetworkAccess();
         assertDataSaverStatusOnBackground(RESTRICT_BACKGROUND_STATUS_ENABLED);
 
-        // Make sure foreground app doesn't lose access upon enabling it.
+        // Make sure foreground app doesn't lose access upon enabling Data Saver.
         setRestrictBackground(false);
         launchActivity();
         assertForegroundNetworkAccess();
         setRestrictBackground(true);
         assertForegroundNetworkAccess();
+
+        // Although it should not have access while the screen is off.
+        turnScreenOff();
+        assertBackgroundNetworkAccess(false);
+        turnScreenOn();
+        assertForegroundNetworkAccess();
+
+        // Goes back to background state.
         finishActivity();
         assertBackgroundNetworkAccess(false);
 
-        // Same for foreground service.
+        // Make sure foreground service doesn't lose access upon enabling Data Saver.
         setRestrictBackground(false);
         startForegroundService();
         assertForegroundNetworkAccess();
diff --git a/hostsidetests/net/app/src/com/android/cts/net/hostside/RemoteSocketFactoryClient.java b/hostsidetests/net/app/src/com/android/cts/net/hostside/RemoteSocketFactoryClient.java
index 799fe50..80f99b6 100644
--- a/hostsidetests/net/app/src/com/android/cts/net/hostside/RemoteSocketFactoryClient.java
+++ b/hostsidetests/net/app/src/com/android/cts/net/hostside/RemoteSocketFactoryClient.java
@@ -22,11 +22,15 @@
 import android.content.ServiceConnection;
 import android.os.ConditionVariable;
 import android.os.IBinder;
+import android.os.ParcelFileDescriptor;
 import android.os.RemoteException;
+import android.system.ErrnoException;
+import android.system.Os;
 
 import com.android.cts.net.hostside.IRemoteSocketFactory;
 
 import java.io.FileDescriptor;
+import java.io.IOException;
 
 public class RemoteSocketFactoryClient {
     private static final int TIMEOUT_MS = 5000;
@@ -76,9 +80,14 @@
         }
     }
 
-    public FileDescriptor openSocketFd(
-            String host, int port, int timeoutMs) throws RemoteException {
-        return mService.openSocketFd(host, port, timeoutMs).getFileDescriptor();
+    public FileDescriptor openSocketFd(String host, int port, int timeoutMs)
+            throws RemoteException, ErrnoException, IOException {
+        // Dup the filedescriptor so ParcelFileDescriptor's finalizer doesn't garbage collect it
+        // and cause our fd to become invalid. http://b/35927643 .
+        ParcelFileDescriptor pfd = mService.openSocketFd(host, port, timeoutMs);
+        FileDescriptor fd = Os.dup(pfd.getFileDescriptor());
+        pfd.close();
+        return fd;
     }
 
     public String getPackageName() throws RemoteException {
diff --git a/hostsidetests/net/app/src/com/android/cts/net/hostside/VpnTest.java b/hostsidetests/net/app/src/com/android/cts/net/hostside/VpnTest.java
index 12fe625..075fce6 100755
--- a/hostsidetests/net/app/src/com/android/cts/net/hostside/VpnTest.java
+++ b/hostsidetests/net/app/src/com/android/cts/net/hostside/VpnTest.java
@@ -476,7 +476,11 @@
     private FileDescriptor openSocketFd(String host, int port, int timeoutMs) throws Exception {
         Socket s = new Socket(host, port);
         s.setSoTimeout(timeoutMs);
-        return ParcelFileDescriptor.fromSocket(s).getFileDescriptor();
+        // Dup the filedescriptor so ParcelFileDescriptor's finalizer doesn't garbage collect it
+        // and cause our fd to become invalid. http://b/35927643 .
+        FileDescriptor fd = Os.dup(ParcelFileDescriptor.fromSocket(s).getFileDescriptor());
+        s.close();
+        return fd;
     }
 
     private FileDescriptor openSocketFdInOtherApp(
@@ -506,7 +510,9 @@
 
     private void assertSocketStillOpen(FileDescriptor fd, String host) throws Exception {
         try {
+            assertTrue(fd.valid());
             sendRequest(fd, host);
+            assertTrue(fd.valid());
         } finally {
             Os.close(fd);
         }
@@ -514,10 +520,12 @@
 
     private void assertSocketClosed(FileDescriptor fd, String host) throws Exception {
         try {
+            assertTrue(fd.valid());
             sendRequest(fd, host);
             fail("Socket opened before VPN connects should be closed when VPN connects");
         } catch (ErrnoException expected) {
             assertEquals(ECONNABORTED, expected.errno);
+            assertTrue(fd.valid());
         } finally {
             Os.close(fd);
         }
diff --git a/hostsidetests/net/app2/AndroidManifest.xml b/hostsidetests/net/app2/AndroidManifest.xml
index 1fa49ba..adf0045 100644
--- a/hostsidetests/net/app2/AndroidManifest.xml
+++ b/hostsidetests/net/app2/AndroidManifest.xml
@@ -46,6 +46,7 @@
                 <action android:name="com.android.cts.net.hostside.app2.action.GET_RESTRICT_BACKGROUND_STATUS" />
                 <action android:name="com.android.cts.net.hostside.app2.action.CHECK_NETWORK" />
                 <action android:name="com.android.cts.net.hostside.app2.action.SEND_NOTIFICATION" />
+                <action android:name="com.android.cts.net.hostside.app2.action.SHOW_TOAST" />
                 </intent-filter>
         </receiver>
     </application>
diff --git a/hostsidetests/net/app2/src/com/android/cts/net/hostside/app2/Common.java b/hostsidetests/net/app2/src/com/android/cts/net/hostside/app2/Common.java
index 8806e3b..e07c0f5 100644
--- a/hostsidetests/net/app2/src/com/android/cts/net/hostside/app2/Common.java
+++ b/hostsidetests/net/app2/src/com/android/cts/net/hostside/app2/Common.java
@@ -38,6 +38,8 @@
             "com.android.cts.net.hostside.app2.action.FINISH_ACTIVITY";
     static final String ACTION_SEND_NOTIFICATION =
             "com.android.cts.net.hostside.app2.action.SEND_NOTIFICATION";
+    static final String ACTION_SHOW_TOAST =
+            "com.android.cts.net.hostside.app2.action.SHOW_TOAST";
     static final String EXTRA_ACTION = "com.android.cts.net.hostside.app2.extra.ACTION";
     static final String EXTRA_RECEIVER_NAME =
             "com.android.cts.net.hostside.app2.extra.RECEIVER_NAME";
diff --git a/hostsidetests/net/app2/src/com/android/cts/net/hostside/app2/MyBroadcastReceiver.java b/hostsidetests/net/app2/src/com/android/cts/net/hostside/app2/MyBroadcastReceiver.java
index 6d01b15..733c3aa 100644
--- a/hostsidetests/net/app2/src/com/android/cts/net/hostside/app2/MyBroadcastReceiver.java
+++ b/hostsidetests/net/app2/src/com/android/cts/net/hostside/app2/MyBroadcastReceiver.java
@@ -23,6 +23,7 @@
 import static com.android.cts.net.hostside.app2.Common.ACTION_GET_RESTRICT_BACKGROUND_STATUS;
 import static com.android.cts.net.hostside.app2.Common.ACTION_RECEIVER_READY;
 import static com.android.cts.net.hostside.app2.Common.ACTION_SEND_NOTIFICATION;
+import static com.android.cts.net.hostside.app2.Common.ACTION_SHOW_TOAST;
 import static com.android.cts.net.hostside.app2.Common.EXTRA_ACTION;
 import static com.android.cts.net.hostside.app2.Common.EXTRA_NOTIFICATION_ID;
 import static com.android.cts.net.hostside.app2.Common.EXTRA_NOTIFICATION_TYPE;
@@ -51,6 +52,7 @@
 import android.net.NetworkInfo;
 import android.os.Bundle;
 import android.util.Log;
+import android.widget.Toast;
 
 import java.net.HttpURLConnection;
 import java.net.URL;
@@ -104,6 +106,9 @@
             case ACTION_SEND_NOTIFICATION:
                 sendNotification(context, intent);
                 break;
+            case ACTION_SHOW_TOAST:
+                showToast(context);
+                break;
             default:
                 Log.e(TAG, "received unexpected action: " + action);
         }
@@ -302,4 +307,9 @@
         ((NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE))
             .notify(notificationId, notification);
     }
+
+    private void showToast(Context context) {
+        Toast.makeText(context, "Toast from CTS test", Toast.LENGTH_SHORT).show();
+        setResultData("Shown");
+    }
 }
diff --git a/hostsidetests/net/src/com/android/cts/net/HostsideRestrictBackgroundNetworkTests.java b/hostsidetests/net/src/com/android/cts/net/HostsideRestrictBackgroundNetworkTests.java
index 7d5f817..faf75d9 100644
--- a/hostsidetests/net/src/com/android/cts/net/HostsideRestrictBackgroundNetworkTests.java
+++ b/hostsidetests/net/src/com/android/cts/net/HostsideRestrictBackgroundNetworkTests.java
@@ -171,6 +171,22 @@
                 "testBackgroundNetworkAccess_enabled");
     }
 
+    public void testAppIdleNonMetered_whenCharging() throws Exception {
+        runDeviceTests(TEST_PKG, TEST_PKG + ".AppIdleNonMeteredTest",
+                "testAppIdleNetworkAccess_whenCharging");
+    }
+
+    public void testAppIdleMetered_whenCharging() throws Exception {
+        runDeviceTests(TEST_PKG, TEST_PKG + ".AppIdleMeteredTest",
+                "testAppIdleNetworkAccess_whenCharging");
+    }
+
+    public void testAppIdle_toast() throws Exception {
+        // Check that showing a toast doesn't bring an app out of standby
+        runDeviceTests(TEST_PKG, TEST_PKG + ".AppIdleNonMeteredTest",
+                "testAppIdle_toast");
+    }
+
     /********************
      * Doze Mode tests. *
      ********************/
diff --git a/hostsidetests/retaildemo/Android.mk b/hostsidetests/retaildemo/Android.mk
new file mode 100644
index 0000000..0aa5ee1
--- /dev/null
+++ b/hostsidetests/retaildemo/Android.mk
@@ -0,0 +1,35 @@
+# Copyright (C) 2016 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+LOCAL_PATH:= $(call my-dir)
+
+include $(CLEAR_VARS)
+
+LOCAL_MODULE := CtsRetailDemoHostTestCases
+
+LOCAL_MODULE_TAGS := optional
+
+LOCAL_SRC_FILES := $(call all-java-files-under, src)
+
+LOCAL_JAVA_LIBRARIES := tools-common-prebuilt cts-tradefed tradefed-prebuilt
+
+LOCAL_CTS_TEST_PACKAGE := android.host.retaildemo
+
+# tag this module as a cts test artifact
+LOCAL_COMPATIBILITY_SUITE := cts
+
+include $(BUILD_CTS_HOST_JAVA_LIBRARY)
+
+# Build the test APKs using their own makefiles
+include $(call all-makefiles-under,$(LOCAL_PATH))
diff --git a/hostsidetests/retaildemo/AndroidTest.xml b/hostsidetests/retaildemo/AndroidTest.xml
new file mode 100644
index 0000000..c174489
--- /dev/null
+++ b/hostsidetests/retaildemo/AndroidTest.xml
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2016 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+<configuration description="Config for the CTS retaildemo host tests">
+
+    <target_preparer class="com.android.compatibility.common.tradefed.targetprep.ApkInstaller">
+        <option name="test-file-name" value="CtsRetailDemoApp.apk" />
+        <option name="cleanup-apks" value="true" />
+    </target_preparer>
+
+    <test class="com.android.compatibility.common.tradefed.testtype.JarHostTest" >
+        <option name="jar" value="CtsRetailDemoHostTestCases.jar" />
+    </test>
+
+</configuration>
\ No newline at end of file
diff --git a/hostsidetests/retaildemo/app/Android.mk b/hostsidetests/retaildemo/app/Android.mk
new file mode 100644
index 0000000..e91e1da
--- /dev/null
+++ b/hostsidetests/retaildemo/app/Android.mk
@@ -0,0 +1,35 @@
+# Copyright (C) 2016 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+LOCAL_PATH:= $(call my-dir)
+
+include $(CLEAR_VARS)
+
+# Don't include this package in any target
+LOCAL_MODULE_TAGS := tests
+# When built, explicitly put it in the data partition.
+LOCAL_MODULE_PATH := $(TARGET_OUT_DATA_APPS)
+
+LOCAL_STATIC_JAVA_LIBRARIES := android-support-test
+
+LOCAL_SRC_FILES := $(call all-java-files-under, src)
+
+# tag this module as a cts test artifact
+LOCAL_COMPATIBILITY_SUITE := cts
+
+LOCAL_PACKAGE_NAME := CtsRetailDemoApp
+
+LOCAL_SDK_VERSION := current
+
+include $(BUILD_CTS_PACKAGE)
diff --git a/hostsidetests/retaildemo/app/AndroidManifest.xml b/hostsidetests/retaildemo/app/AndroidManifest.xml
new file mode 100644
index 0000000..b36ee1b
--- /dev/null
+++ b/hostsidetests/retaildemo/app/AndroidManifest.xml
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ -->
+
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+        package="com.android.cts.retaildemo">
+
+    <application>
+        <uses-library android:name="android.test.runner" />
+    </application>
+
+    <instrumentation android:name="android.support.test.runner.AndroidJUnitRunner"
+            android:targetPackage="com.android.cts.retaildemo"
+            android:label="RetailDemo device side tests" />
+</manifest>
diff --git a/hostsidetests/retaildemo/app/src/com/android/cts/retaildemo/DemoUserTest.java b/hostsidetests/retaildemo/app/src/com/android/cts/retaildemo/DemoUserTest.java
new file mode 100644
index 0000000..bb20b1a
--- /dev/null
+++ b/hostsidetests/retaildemo/app/src/com/android/cts/retaildemo/DemoUserTest.java
@@ -0,0 +1,50 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.cts.retaildemo;
+
+import static junit.framework.Assert.assertFalse;
+import static junit.framework.Assert.assertTrue;
+
+import android.content.Context;
+import android.os.UserManager;
+import android.support.test.InstrumentationRegistry;
+import android.support.test.filters.SmallTest;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.JUnit4;
+
+@SmallTest
+@RunWith(JUnit4.class)
+public class DemoUserTest {
+    private UserManager mUm;
+
+    @Before
+    public void setUp() {
+        mUm = InstrumentationRegistry.getContext().getSystemService(UserManager.class);
+    }
+
+    @Test
+    public void testIsDemoUser_success() {
+        assertTrue(mUm.isDemoUser());
+    }
+
+    @Test
+    public void testIsDemoUser_failure() {
+        assertFalse(mUm.isDemoUser());
+    }
+}
diff --git a/hostsidetests/retaildemo/src/android/host/retaildemo/BaseTestCase.java b/hostsidetests/retaildemo/src/android/host/retaildemo/BaseTestCase.java
new file mode 100644
index 0000000..5033b6d
--- /dev/null
+++ b/hostsidetests/retaildemo/src/android/host/retaildemo/BaseTestCase.java
@@ -0,0 +1,129 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package android.host.retaildemo;
+
+import com.android.compatibility.common.tradefed.build.CompatibilityBuildHelper;
+import com.android.ddmlib.testrunner.RemoteAndroidTestRunner;
+import com.android.ddmlib.testrunner.TestIdentifier;
+import com.android.ddmlib.testrunner.TestResult;
+import com.android.ddmlib.testrunner.TestResult.TestStatus;
+import com.android.ddmlib.testrunner.TestRunResult;
+import com.android.tradefed.build.IBuildInfo;
+import com.android.tradefed.device.DeviceNotAvailableException;
+import com.android.tradefed.log.LogUtil.CLog;
+import com.android.tradefed.result.CollectingTestListener;
+import com.android.tradefed.testtype.DeviceTestCase;
+import com.android.tradefed.testtype.IBuildReceiver;
+
+import java.io.File;
+import java.io.FileNotFoundException;
+import java.util.ArrayList;
+import java.util.Map;
+
+public class BaseTestCase extends DeviceTestCase implements IBuildReceiver {
+    private static final String RETAIL_DEMO_TEST_PKG = "com.android.cts.retaildemo";
+    private static final String RUNNER = "android.support.test.runner.AndroidJUnitRunner";
+
+    private IBuildInfo mBuildInfo;
+    private CompatibilityBuildHelper mBuildHelper;
+
+    private ArrayList<Integer> mTestUsers;
+
+    @Override
+    public void setBuild(IBuildInfo buildInfo) {
+        mBuildInfo = buildInfo;
+        mBuildHelper = new CompatibilityBuildHelper(mBuildInfo);
+    }
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+        assertNotNull(mBuildInfo); // ensure build has been set before test is run.
+        mTestUsers = new ArrayList<>();
+    }
+
+    @Override
+    protected void tearDown() throws Exception {
+        for (int userId : mTestUsers) {
+            getDevice().removeUser(userId);
+        }
+        super.tearDown();
+    }
+
+    protected int createDemoUser() throws DeviceNotAvailableException, IllegalStateException {
+        final String command = "pm create-user --ephemeral --demo "
+                + "TestUser_" + System.currentTimeMillis();
+        CLog.d("Starting command: " + command);
+        final String output = getDevice().executeShellCommand(command);
+        CLog.d("Output for command " + command + ": " + output);
+
+        if (output.startsWith("Success")) {
+            try {
+                int userId = Integer.parseInt(output.substring(output.lastIndexOf(" ")).trim());
+                mTestUsers.add(userId);
+                return userId;
+            } catch (NumberFormatException e) {
+                CLog.e("Failed to parse result: %s", output);
+            }
+        } else {
+            CLog.e("Failed to create demo user: %s", output);
+        }
+        throw new IllegalStateException();
+    }
+
+    protected void installAppAsUser(String appFileName, int userId)
+            throws FileNotFoundException, DeviceNotAvailableException {
+        CLog.d("Installing app " + appFileName + " for user " + userId);
+        File apkFile = new File(mBuildHelper.getTestsDir(), appFileName);
+        final String result = getDevice().installPackageForUser(
+                apkFile, true, true, userId, "-t");
+        assertNull("Failed to install " + appFileName + " for user " + userId + ": " + result,
+                result);
+    }
+
+    protected boolean runDeviceTestsAsUser(String testClassName, String testMethodName, int userId)
+            throws Exception {
+        if (testClassName != null && testClassName.startsWith(".")) {
+            testClassName = RETAIL_DEMO_TEST_PKG + testClassName;
+        }
+
+        RemoteAndroidTestRunner testRunner = new RemoteAndroidTestRunner(
+                RETAIL_DEMO_TEST_PKG, RUNNER, getDevice().getIDevice());
+        if (testClassName != null && testMethodName != null) {
+            testRunner.setMethodName(testClassName, testMethodName);
+        } else if (testClassName != null) {
+            testRunner.setClassName(testClassName);
+        }
+
+        CollectingTestListener listener = new CollectingTestListener();
+        assertTrue(getDevice().runInstrumentationTestsAsUser(testRunner, userId, listener));
+
+        TestRunResult runResult = listener.getCurrentRunResults();
+        printTestResult(runResult);
+        return !runResult.hasFailedTests() && runResult.getNumTestsInState(TestStatus.PASSED) > 0;
+    }
+
+    private void printTestResult(TestRunResult runResult) {
+        for (Map.Entry<TestIdentifier, TestResult> testEntry :
+                runResult.getTestResults().entrySet()) {
+            TestResult testResult = testEntry.getValue();
+            CLog.d("Test " + testEntry.getKey() + ": " + testResult.getStatus());
+            if (testResult.getStatus() != TestStatus.PASSED) {
+                CLog.d(testResult.getStackTrace());
+            }
+        }
+    }
+}
diff --git a/hostsidetests/retaildemo/src/android/host/retaildemo/DemoModeTest.java b/hostsidetests/retaildemo/src/android/host/retaildemo/DemoModeTest.java
new file mode 100644
index 0000000..3fdfd72
--- /dev/null
+++ b/hostsidetests/retaildemo/src/android/host/retaildemo/DemoModeTest.java
@@ -0,0 +1,38 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package android.host.retaildemo;
+
+import static junit.framework.Assert.assertTrue;
+
+public class DemoModeTest extends BaseTestCase {
+    private static final String RETAIL_DEMO_TEST_APK = "CtsRetailDemoApp.apk";
+
+    public void testIsDemoUser_inPrimaryUser() throws Exception {
+        assertTrue(runDeviceTestsAsUser(
+                ".DemoUserTest", "testIsDemoUser_failure", getDevice().getPrimaryUserId()));
+    }
+
+    public void testIsDemoUser_inDemoUser() throws Exception {
+        if (!getDevice().isMultiUserSupported()) {
+            return;
+        }
+        final int demoUserId = createDemoUser();
+        getDevice().startUser(demoUserId);
+        installAppAsUser(RETAIL_DEMO_TEST_APK, demoUserId);
+        assertTrue(runDeviceTestsAsUser(
+                ".DemoUserTest", "testIsDemoUser_success", demoUserId));
+    }
+}
diff --git a/hostsidetests/security/res/ab3857191_file_contexts.bin b/hostsidetests/security/res/ab3857191_file_contexts.bin
new file mode 100644
index 0000000..881c706
--- /dev/null
+++ b/hostsidetests/security/res/ab3857191_file_contexts.bin
Binary files differ
diff --git a/hostsidetests/security/res/ab3857191_service_contexts b/hostsidetests/security/res/ab3857191_service_contexts
new file mode 100644
index 0000000..1e50d87
--- /dev/null
+++ b/hostsidetests/security/res/ab3857191_service_contexts
@@ -0,0 +1,149 @@
+#line 1 "system/sepolicy/service_contexts"
+accessibility                             u:object_r:accessibility_service:s0
+account                                   u:object_r:account_service:s0
+activity                                  u:object_r:activity_service:s0
+alarm                                     u:object_r:alarm_service:s0
+android.os.UpdateEngineService            u:object_r:update_engine_service:s0
+android.security.keystore                 u:object_r:keystore_service:s0
+android.service.gatekeeper.IGateKeeperService    u:object_r:gatekeeper_service:s0
+appops                                    u:object_r:appops_service:s0
+appwidget                                 u:object_r:appwidget_service:s0
+assetatlas                                u:object_r:assetatlas_service:s0
+audio                                     u:object_r:audio_service:s0
+backup                                    u:object_r:backup_service:s0
+batteryproperties                         u:object_r:batteryproperties_service:s0
+batterystats                              u:object_r:batterystats_service:s0
+battery                                   u:object_r:battery_service:s0
+bluetooth_manager                         u:object_r:bluetooth_manager_service:s0
+bluetooth                                 u:object_r:bluetooth_service:s0
+carrier_config                            u:object_r:radio_service:s0
+clipboard                                 u:object_r:clipboard_service:s0
+com.android.net.IProxyService             u:object_r:IProxyService_service:s0
+commontime_management                     u:object_r:commontime_management_service:s0
+common_time.clock                         u:object_r:mediaserver_service:s0
+common_time.config                        u:object_r:mediaserver_service:s0
+connectivity                              u:object_r:connectivity_service:s0
+connmetrics                               u:object_r:connmetrics_service:s0
+consumer_ir                               u:object_r:consumer_ir_service:s0
+content                                   u:object_r:content_service:s0
+contexthub_service                        u:object_r:contexthub_service:s0
+country_detector                          u:object_r:country_detector_service:s0
+cpuinfo                                   u:object_r:cpuinfo_service:s0
+dbinfo                                    u:object_r:dbinfo_service:s0
+device_policy                             u:object_r:device_policy_service:s0
+deviceidle                                u:object_r:deviceidle_service:s0
+devicestoragemonitor                      u:object_r:devicestoragemonitor_service:s0
+diskstats                                 u:object_r:diskstats_service:s0
+display.qservice                          u:object_r:surfaceflinger_service:s0
+display                                   u:object_r:display_service:s0
+dns_listener                              u:object_r:dns_listener_service:s0
+DockObserver                              u:object_r:DockObserver_service:s0
+dreams                                    u:object_r:dreams_service:s0
+drm.drmManager                            u:object_r:drmserver_service:s0
+dropbox                                   u:object_r:dropbox_service:s0
+ethernet                                  u:object_r:ethernet_service:s0
+fingerprint                               u:object_r:fingerprint_service:s0
+android.hardware.fingerprint.IFingerprintDaemon u:object_r:fingerprintd_service:s0
+gfxinfo                                   u:object_r:gfxinfo_service:s0
+graphicsstats                             u:object_r:graphicsstats_service:s0
+gpu                                       u:object_r:gpu_service:s0
+hardware                                  u:object_r:hardware_service:s0
+hardware_properties                       u:object_r:hardware_properties_service:s0
+hdmi_control                              u:object_r:hdmi_control_service:s0
+inputflinger                              u:object_r:inputflinger_service:s0
+input_method                              u:object_r:input_method_service:s0
+input                                     u:object_r:input_service:s0
+iphonesubinfo_msim                        u:object_r:radio_service:s0
+iphonesubinfo2                            u:object_r:radio_service:s0
+iphonesubinfo                             u:object_r:radio_service:s0
+ims                                       u:object_r:radio_service:s0
+imms                                      u:object_r:imms_service:s0
+isms_msim                                 u:object_r:radio_service:s0
+isms2                                     u:object_r:radio_service:s0
+isms                                      u:object_r:radio_service:s0
+isub                                      u:object_r:radio_service:s0
+jobscheduler                              u:object_r:jobscheduler_service:s0
+launcherapps                              u:object_r:launcherapps_service:s0
+location                                  u:object_r:location_service:s0
+lock_settings                             u:object_r:lock_settings_service:s0
+media.audio_flinger                       u:object_r:audioserver_service:s0
+media.audio_policy                        u:object_r:audioserver_service:s0
+media.camera                              u:object_r:cameraserver_service:s0
+media.camera.proxy                        u:object_r:cameraproxy_service:s0
+media.log                                 u:object_r:audioserver_service:s0
+media.player                              u:object_r:mediaserver_service:s0
+media.extractor                           u:object_r:mediaextractor_service:s0
+media.codec                               u:object_r:mediacodec_service:s0
+media.resource_manager                    u:object_r:mediaserver_service:s0
+media.radio                               u:object_r:audioserver_service:s0
+media.sound_trigger_hw                    u:object_r:audioserver_service:s0
+media.drm                                 u:object_r:mediadrmserver_service:s0
+media_projection                          u:object_r:media_projection_service:s0
+media_resource_monitor                    u:object_r:media_session_service:s0
+media_router                              u:object_r:media_router_service:s0
+media_session                             u:object_r:media_session_service:s0
+meminfo                                   u:object_r:meminfo_service:s0
+midi                                      u:object_r:midi_service:s0
+mount                                     u:object_r:mount_service:s0
+netd                                      u:object_r:netd_service:s0
+netpolicy                                 u:object_r:netpolicy_service:s0
+netstats                                  u:object_r:netstats_service:s0
+network_management                        u:object_r:network_management_service:s0
+network_score                             u:object_r:network_score_service:s0
+network_time_update_service               u:object_r:network_time_update_service:s0
+nfc                                       u:object_r:nfc_service:s0
+notification                              u:object_r:notification_service:s0
+otadexopt                                 u:object_r:otadexopt_service:s0
+package                                   u:object_r:package_service:s0
+permission                                u:object_r:permission_service:s0
+persistent_data_block                     u:object_r:persistent_data_block_service:s0
+phone_msim                                u:object_r:radio_service:s0
+phone1                                    u:object_r:radio_service:s0
+phone2                                    u:object_r:radio_service:s0
+phone                                     u:object_r:radio_service:s0
+pinner                                    u:object_r:pinner_service:s0
+power                                     u:object_r:power_service:s0
+print                                     u:object_r:print_service:s0
+processinfo                               u:object_r:processinfo_service:s0
+procstats                                 u:object_r:procstats_service:s0
+radio.phonesubinfo                        u:object_r:radio_service:s0
+radio.phone                               u:object_r:radio_service:s0
+radio.sms                                 u:object_r:radio_service:s0
+recovery                                  u:object_r:recovery_service:s0
+restrictions                              u:object_r:restrictions_service:s0
+rttmanager                                u:object_r:rttmanager_service:s0
+samplingprofiler                          u:object_r:samplingprofiler_service:s0
+scheduling_policy                         u:object_r:scheduling_policy_service:s0
+search                                    u:object_r:search_service:s0
+sensorservice                             u:object_r:sensorservice_service:s0
+serial                                    u:object_r:serial_service:s0
+servicediscovery                          u:object_r:servicediscovery_service:s0
+shortcut                                  u:object_r:shortcut_service:s0
+simphonebook_msim                         u:object_r:radio_service:s0
+simphonebook2                             u:object_r:radio_service:s0
+simphonebook                              u:object_r:radio_service:s0
+sip                                       u:object_r:radio_service:s0
+soundtrigger                              u:object_r:voiceinteraction_service:s0
+statusbar                                 u:object_r:statusbar_service:s0
+SurfaceFlinger                            u:object_r:surfaceflinger_service:s0
+task                                      u:object_r:task_service:s0
+telecom                                   u:object_r:telecom_service:s0
+telephony.registry                        u:object_r:registry_service:s0
+textservices                              u:object_r:textservices_service:s0
+trust                                     u:object_r:trust_service:s0
+tv_input                                  u:object_r:tv_input_service:s0
+uimode                                    u:object_r:uimode_service:s0
+updatelock                                u:object_r:updatelock_service:s0
+usagestats                                u:object_r:usagestats_service:s0
+usb                                       u:object_r:usb_service:s0
+user                                      u:object_r:user_service:s0
+vibrator                                  u:object_r:vibrator_service:s0
+voiceinteraction                          u:object_r:voiceinteraction_service:s0
+vrmanager                                 u:object_r:vr_manager_service:s0
+wallpaper                                 u:object_r:wallpaper_service:s0
+webviewupdate                             u:object_r:webviewupdate_service:s0
+wifip2p                                   u:object_r:wifip2p_service:s0
+wifiscanner                               u:object_r:wifiscanner_service:s0
+wifi                                      u:object_r:wifi_service:s0
+window                                    u:object_r:window_service:s0
+*                                         u:object_r:default_android_service:s0
diff --git a/hostsidetests/security/src/android/security/cts/SELinuxHostTest.java b/hostsidetests/security/src/android/security/cts/SELinuxHostTest.java
index b74eba7..c7368d8 100644
--- a/hostsidetests/security/src/android/security/cts/SELinuxHostTest.java
+++ b/hostsidetests/security/src/android/security/cts/SELinuxHostTest.java
@@ -23,10 +23,13 @@
 import com.android.tradefed.device.CollectingOutputReceiver;
 import com.android.tradefed.device.DeviceNotAvailableException;
 import com.android.tradefed.device.ITestDevice;
+import com.android.tradefed.log.LogUtil.CLog;
 import com.android.tradefed.testtype.DeviceTestCase;
 import com.android.tradefed.testtype.IBuildReceiver;
 import com.android.tradefed.testtype.IDeviceTest;
 
+import com.android.compatibility.common.util.CddTest;
+
 import java.io.BufferedReader;
 import java.io.File;
 import java.io.FileReader;
@@ -123,6 +126,7 @@
      *
      * @throws Exception
      */
+    @CddTest(requirement="9.7")
     public void testGlobalEnforcing() throws Exception {
         CollectingOutputReceiver out = new CollectingOutputReceiver();
         mDevice.executeShellCommand("cat /sys/fs/selinux/enforce", out);
@@ -134,6 +138,7 @@
      *
      * @throws Exception
      */
+    @CddTest(requirement="9.7")
     @RestrictedBuildTest
     public void testAllDomainsEnforcing() throws Exception {
 
@@ -188,6 +193,7 @@
      *
      * @throws Exception
      */
+    @CddTest(requirement="9.7")
     public void testMLSAttributes() throws Exception {
         assertNotInAttribute("mlstrustedsubject", "untrusted_app");
         assertNotInAttribute("mlstrustedobject", "app_data_file");
@@ -198,6 +204,7 @@
      *
      * @throws Exception
      */
+    @CddTest(requirement="9.7")
     public void testValidSeappContexts() throws Exception {
 
         /* obtain seapp_contexts file from running device */
@@ -252,11 +259,37 @@
     }
 
     /**
+     * Returns {@code true} if the actual file contents starts with the expected
+     * file contents.
+     *
+     * @param expectedFile
+     *  The file with the expected contents.
+     * @param actualFile
+     *  The actual file being checked.
+     */
+    private boolean isFileStartsWith(File expectedFile, File actualFile) throws Exception {
+        BufferedReader expectedReader = new BufferedReader(new FileReader(expectedFile.getAbsolutePath()));
+        BufferedReader actualReader = new BufferedReader(new FileReader(actualFile.getAbsolutePath()));
+        String expectedLine, actualLine;
+        boolean startsWith = true;
+        while ((expectedLine = expectedReader.readLine()) != null) {
+            actualLine = actualReader.readLine();
+            if (!expectedLine.equals(actualLine)) {
+                startsWith = false;
+                CLog.d("Lines do not match, expected:" + expectedLine +
+                        " actual:" + actualLine);
+            }
+        }
+        return startsWith;
+    }
+
+    /**
      * Tests that the seapp_contexts file on the device contains
      * the standard AOSP entries.
      *
      * @throws Exception
      */
+    @CddTest(requirement="9.7")
     public void testAospSeappContexts() throws Exception {
 
         /* obtain seapp_contexts file from running device */
@@ -276,6 +309,7 @@
      *
      * @throws Exception
      */
+    @CddTest(requirement="9.7")
     public void testAospFileContexts() throws Exception {
 
         /* retrieve the checkfc executable from jar */
@@ -287,22 +321,40 @@
         deviceFcFile.deleteOnExit();
         mDevice.pullFile("/file_contexts.bin", deviceFcFile);
 
-        /* retrieve the AOSP file_contexts file from jar */
-        aospFcFile = copyResourceToTempFile("/general_file_contexts.bin");
+        /* Compares with AOSP file_contexts file from jar */
+        String line = checkFileContexts("/general_file_contexts.bin");
 
-        /* run checkfc -c general_file_contexts.bin file_contexts.bin */
+        if(line.equals("equal") || line.equals("subset")) {
+            CLog.d("The file_contexts.bin file includes the latest AOSP entries.\n");
+        } else {
+            CLog.d("The file_contexts.bin file did not include the latest AOSP entries:\n"
+                       + line + "\n");
+
+            /* Compares with NMR1 AOSP file_contexts */
+            line = checkFileContexts("/ab3857191_file_contexts.bin");
+            assertTrue("The file_contexts.bin file did not include the AOSP entries:\n"
+                       + line + "\n",
+                       line.equals("equal") || line.equals("subset"));
+        }
+    }
+
+    /**
+     * Check deviceFcFile with a file_contexts file and returns the result string
+     *
+     * @param fcFileName
+     *  The file_contexts file name that with the expected contents in jar.
+     */
+    private String checkFileContexts(String fcFileName) throws Exception {
+        File fcFile = copyResourceToTempFile(fcFileName);
         ProcessBuilder pb = new ProcessBuilder(checkFc.getAbsolutePath(),
-                "-c", aospFcFile.getAbsolutePath(),
+                "-c", fcFile.getAbsolutePath(),
                 deviceFcFile.getAbsolutePath());
         pb.redirectOutput(ProcessBuilder.Redirect.PIPE);
         pb.redirectErrorStream(true);
         Process p = pb.start();
         p.waitFor();
         BufferedReader result = new BufferedReader(new InputStreamReader(p.getInputStream()));
-        String line = result.readLine();
-        assertTrue("The file_contexts.bin file did not include the AOSP entries:\n"
-                   + line + "\n",
-                   line.equals("equal") || line.equals("subset"));
+        return result.readLine();
     }
 
     /**
@@ -311,6 +363,7 @@
      *
      * @throws Exception
      */
+    @CddTest(requirement="9.7")
     public void testAospPropertyContexts() throws Exception {
 
         /* obtain property_contexts file from running device */
@@ -330,6 +383,7 @@
      *
      * @throws Exception
      */
+    @CddTest(requirement="9.7")
     public void testAospServiceContexts() throws Exception {
 
         /* obtain service_contexts file from running device */
@@ -340,7 +394,11 @@
         /* retrieve the AOSP service_contexts file from jar */
         aospSvcFile = copyResourceToTempFile("/general_service_contexts");
 
-        assertFileStartsWith(aospSvcFile, deviceSvcFile);
+        /* retrieve NMR1 AOSP service_contexts file from jar */
+        if (!isFileStartsWith(aospSvcFile, deviceSvcFile)) {
+            aospSvcFile = copyResourceToTempFile("/ab3857191_service_contexts");
+            assertFileStartsWith(aospSvcFile, deviceSvcFile);
+        }
     }
 
     /**
@@ -348,6 +406,7 @@
      *
      * @throws Exception
      */
+    @CddTest(requirement="9.7")
     public void testValidFileContexts() throws Exception {
 
         /* retrieve the checkfc executable from jar */
@@ -383,6 +442,7 @@
      *
      * @throws Exception
      */
+    @CddTest(requirement="9.7")
     public void testValidPropertyContexts() throws Exception {
 
         /* retrieve the checkfc executable from jar */
@@ -418,6 +478,7 @@
      *
      * @throws Exception
      */
+    @CddTest(requirement="9.7")
     public void testValidServiceContexts() throws Exception {
 
         /* retrieve the checkfc executable from jar */
@@ -453,6 +514,7 @@
      *
      * @throws Exception
      */
+    @CddTest(requirement="9.7")
     public void testNoBooleans() throws Exception {
 
         /* run sepolicy-analyze booleans check on policy file */
@@ -629,67 +691,80 @@
     }
 
     /* Init is always there */
+    @CddTest(requirement="9.7")
     public void testInitDomain() throws DeviceNotAvailableException {
         assertDomainOne("u:r:init:s0", "/init");
     }
 
     /* Ueventd is always there */
+    @CddTest(requirement="9.7")
     public void testUeventdDomain() throws DeviceNotAvailableException {
         assertDomainOne("u:r:ueventd:s0", "/sbin/ueventd");
     }
 
     /* Devices always have healthd */
+    @CddTest(requirement="9.7")
     public void testHealthdDomain() throws DeviceNotAvailableException {
         assertDomainOne("u:r:healthd:s0", "/sbin/healthd");
     }
 
     /* Servicemanager is always there */
+    @CddTest(requirement="9.7")
     public void testServicemanagerDomain() throws DeviceNotAvailableException {
         assertDomainOne("u:r:servicemanager:s0", "/system/bin/servicemanager");
     }
 
     /* Vold is always there */
+    @CddTest(requirement="9.7")
     public void testVoldDomain() throws DeviceNotAvailableException {
         assertDomainOne("u:r:vold:s0", "/system/bin/vold");
     }
 
     /* netd is always there */
+    @CddTest(requirement="9.7")
     public void testNetdDomain() throws DeviceNotAvailableException {
-        assertDomainOne("u:r:netd:s0", "/system/bin/netd");
+        assertDomainN("u:r:netd:s0", "/system/bin/netd", "/system/bin/iptables-restore", "/system/bin/ip6tables-restore");
     }
 
     /* Debuggerd is always there */
+    @CddTest(requirement="9.7")
     public void testDebuggerdDomain() throws DeviceNotAvailableException {
         assertDomainN("u:r:debuggerd:s0", "/system/bin/debuggerd", "/system/bin/debuggerd64",
                 "debuggerd:signaller", "debuggerd64:signaller");
     }
 
     /* Surface flinger is always there */
+    @CddTest(requirement="9.7")
     public void testSurfaceflingerDomain() throws DeviceNotAvailableException {
         assertDomainOne("u:r:surfaceflinger:s0", "/system/bin/surfaceflinger");
     }
 
     /* Zygote is always running */
+    @CddTest(requirement="9.7")
     public void testZygoteDomain() throws DeviceNotAvailableException {
         assertDomainN("u:r:zygote:s0", "zygote", "zygote64");
     }
 
     /* Checks drmserver for devices that require it */
+    @CddTest(requirement="9.7")
     public void testDrmServerDomain() throws DeviceNotAvailableException {
         assertDomainZeroOrOne("u:r:drmserver:s0", "/system/bin/drmserver");
     }
 
     /* Installd is always running */
+    @CddTest(requirement="9.7")
     public void testInstalldDomain() throws DeviceNotAvailableException {
         assertDomainOne("u:r:installd:s0", "/system/bin/installd");
     }
 
     /* keystore is always running */
+    @CddTest(requirement="9.7")
     public void testKeystoreDomain() throws DeviceNotAvailableException {
         assertDomainOne("u:r:keystore:s0", "/system/bin/keystore");
     }
 
     /* System server better be running :-P */
+    @CddTest(requirement="9.7")
     public void testSystemServerDomain() throws DeviceNotAvailableException {
         assertDomainOne("u:r:system_server:s0", "system_server");
     }
@@ -698,26 +773,31 @@
      * Some OEMs do not use sdcardd so transient. Other OEMs have multiple sdcards
      * so they run the daemon multiple times.
      */
+    @CddTest(requirement="9.7")
     public void testSdcarddDomain() throws DeviceNotAvailableException {
         assertDomainHasExecutable("u:r:sdcardd:s0", "/system/bin/sdcard");
     }
 
     /* Watchdogd may or may not be there */
+    @CddTest(requirement="9.7")
     public void testWatchdogdDomain() throws DeviceNotAvailableException {
         assertDomainZeroOrOne("u:r:watchdogd:s0", "/sbin/watchdogd");
     }
 
     /* logd may or may not be there */
+    @CddTest(requirement="9.7")
     public void testLogdDomain() throws DeviceNotAvailableException {
         assertDomainZeroOrOne("u:r:logd:s0", "/system/bin/logd");
     }
 
     /* lmkd may or may not be there */
+    @CddTest(requirement="9.7")
     public void testLmkdDomain() throws DeviceNotAvailableException {
         assertDomainZeroOrOne("u:r:lmkd:s0", "/system/bin/lmkd");
     }
 
     /* Wifi may be off so cardinality of 0 or 1 is ok */
+    @CddTest(requirement="9.7")
     public void testWpaDomain() throws DeviceNotAvailableException {
         assertDomainZeroOrOne("u:r:wpa:s0", "/system/bin/wpa_supplicant");
     }
@@ -726,6 +806,7 @@
      * Nothing should be running in this domain, cardinality test is all thats
      * needed
      */
+    @CddTest(requirement="9.7")
     public void testInitShellDomain() throws DeviceNotAvailableException {
         assertDomainEmpty("u:r:init_shell:s0");
     }
@@ -734,6 +815,7 @@
      * Nothing should be running in this domain, cardinality test is all thats
      * needed
      */
+    @CddTest(requirement="9.7")
     public void testRecoveryDomain() throws DeviceNotAvailableException {
         assertDomainEmpty("u:r:recovery:s0");
     }
@@ -742,6 +824,7 @@
      * Nothing should be running in this domain, cardinality test is all thats
      * needed
      */
+    @CddTest(requirement="9.7")
     @RestrictedBuildTest
     public void testSuDomain() throws DeviceNotAvailableException {
         assertDomainEmpty("u:r:su:s0");
@@ -750,6 +833,7 @@
     /*
      * All kthreads should be in kernel context.
      */
+    @CddTest(requirement="9.7")
     public void testKernelDomain() throws DeviceNotAvailableException {
         String domain = "u:r:kernel:s0";
         List<ProcessDetails> procs = ProcessDetails.getProcMap(mDevice).get(domain);
diff --git a/hostsidetests/services/activitymanager/app/AndroidManifest.xml b/hostsidetests/services/activitymanager/app/AndroidManifest.xml
index ee922ff..2098cc2 100755
--- a/hostsidetests/services/activitymanager/app/AndroidManifest.xml
+++ b/hostsidetests/services/activitymanager/app/AndroidManifest.xml
@@ -22,8 +22,11 @@
     <application>
         <activity android:name=".TestActivity"
                 android:resizeableActivity="true"
-                android:exported="true"
-        />
+                android:exported="true">
+                <layout android:minWidth="1dp"
+                        android:minHeight="1dp"
+                />
+        </activity>
         <activity android:name=".ResizeableActivity"
                 android:resizeableActivity="true"
                 android:exported="true"
@@ -48,8 +51,11 @@
                 android:resizeableActivity="true"
                 android:configChanges="orientation|screenSize|smallestScreenSize|screenLayout|fontScale"
                 android:exported="true"
-                android:taskAffinity="nobody.but.NoRelaunchActivity"
-        />
+                android:taskAffinity="nobody.but.NoRelaunchActivity">
+                <layout android:minWidth="1dp"
+                        android:minHeight="1dp"
+                />
+        </activity>
         <activity android:name=".SlowCreateActivity"
                 android:resizeableActivity="true"
                 android:exported="true"
@@ -167,6 +173,9 @@
                   android:resizeableActivity="true"
                   android:exported="true"
         />
+        <activity android:name=".NoHomeScreenObserver"
+                  android:exported="true"
+        />
         <activity-alias android:enabled="true"
                 android:exported="true"
                 android:name=".EntryPointAliasActivity"
diff --git a/hostsidetests/services/activitymanager/app/src/android/server/app/AbstractLifecycleLogActivity.java b/hostsidetests/services/activitymanager/app/src/android/server/app/AbstractLifecycleLogActivity.java
index bb54bc4..8abb1c5 100644
--- a/hostsidetests/services/activitymanager/app/src/android/server/app/AbstractLifecycleLogActivity.java
+++ b/hostsidetests/services/activitymanager/app/src/android/server/app/AbstractLifecycleLogActivity.java
@@ -57,7 +57,8 @@
         final String line = "config" +
                 " size=" + buildCoordString(config.screenWidthDp, config.screenHeightDp) +
                 " displaySize=" + buildCoordString(point.x, point.y) +
-                " metricsSize=" + buildCoordString(metrics.widthPixels, metrics.heightPixels);
+                " metricsSize=" + buildCoordString(metrics.widthPixels, metrics.heightPixels) +
+                " smallestScreenWidth=" + config.smallestScreenWidthDp;
 
         Log.i(getTag(), line);
     }
diff --git a/hostsidetests/services/activitymanager/app/src/android/server/app/NoHomeScreenObserver.java b/hostsidetests/services/activitymanager/app/src/android/server/app/NoHomeScreenObserver.java
new file mode 100644
index 0000000..47e8369
--- /dev/null
+++ b/hostsidetests/services/activitymanager/app/src/android/server/app/NoHomeScreenObserver.java
@@ -0,0 +1,23 @@
+package android.server.app;
+
+import android.app.Activity;
+import android.content.res.Resources;
+import android.os.Bundle;
+import android.util.Log;
+
+public class NoHomeScreenObserver extends Activity {
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        boolean support = false;
+        try {
+            int id = Resources.getSystem().getIdentifier("config_noHomeScreen", "bool", "android");
+            support = Resources.getSystem().getBoolean(id);
+        } catch (android.content.res.Resources.NotFoundException e) {
+            // Ignore the exception.
+        }
+        Log.i(getClass().getSimpleName(), "HEAD=OK");
+        Log.i(getClass().getSimpleName(), "config_noHomeScreen=" + support);
+    }
+}
+
diff --git a/hostsidetests/services/activitymanager/src/android/server/cts/ActivityManagerActivityVisiblityTests.java b/hostsidetests/services/activitymanager/src/android/server/cts/ActivityManagerActivityVisiblityTests.java
index 2417da7..866251c 100644
--- a/hostsidetests/services/activitymanager/src/android/server/cts/ActivityManagerActivityVisiblityTests.java
+++ b/hostsidetests/services/activitymanager/src/android/server/cts/ActivityManagerActivityVisiblityTests.java
@@ -16,7 +16,9 @@
 
 package android.server.cts;
 
+import com.android.ddmlib.Log.LogLevel;
 import com.android.tradefed.device.DeviceNotAvailableException;
+import com.android.tradefed.log.LogUtil.CLog;
 
 import java.lang.Exception;
 import java.lang.String;
@@ -32,6 +34,10 @@
     private static final String BROADCAST_RECEIVER_ACTIVITY = "BroadcastReceiverActivity";
 
     public void testVisibleBehindHomeActivity() throws Exception {
+        if (noHomeScreen()) {
+            return;
+        }
+
         executeShellCommand(getAmStartCmd(VISIBLE_BEHIND_ACTIVITY));
         mAmWmState.waitForValidState(mDevice, true, new String[] {VISIBLE_BEHIND_ACTIVITY},
                 new int[] {FULLSCREEN_WORKSPACE_STACK_ID}, false /* compareTaskAndStackBounds */);
@@ -63,6 +69,10 @@
     }
 
     public void testVisibleBehindOtherActivity_OverHome() throws Exception {
+        if (noHomeScreen()) {
+            return;
+        }
+
         executeShellCommand(getAmStartCmdOverHome(VISIBLE_BEHIND_ACTIVITY));
         executeShellCommand(getAmStartCmdOverHome(TRANSLUCENT_ACTIVITY));
 
@@ -93,6 +103,10 @@
      * fullscreen stack over the home activity.
      */
     public void testTranslucentActivityOnTopOfHome() throws Exception {
+        if (noHomeScreen()) {
+            return;
+        }
+
         executeShellCommand(AM_START_HOME_ACTIVITY_COMMAND);
         executeShellCommand(getAmStartCmd(TRANSLUCENT_ACTIVITY));
 
@@ -126,6 +140,11 @@
     }
 
     public void testTranslucentActivityOverDockedStack() throws Exception {
+        if (!supportsSplitScreenMultiWindow()) {
+            CLog.logAndDisplay(LogLevel.INFO, "Skipping test: no multi-window support");
+            return;
+        }
+
         launchActivityInDockStack(DOCKED_ACTIVITY_NAME);
         mAmWmState.computeState(mDevice, new String[] {DOCKED_ACTIVITY_NAME});
         launchActivityInStack(TEST_ACTIVITY_NAME, FULLSCREEN_WORKSPACE_STACK_ID);
@@ -149,6 +168,11 @@
     }
 
     public void testFinishActivityInNonFocusedStack() throws Exception {
+        if (!supportsSplitScreenMultiWindow()) {
+            CLog.logAndDisplay(LogLevel.INFO, "Skipping test: no multi-window support");
+            return;
+        }
+
         // Launch two activities in docked stack.
         launchActivityInDockStack(LAUNCHING_ACTIVITY);
         launchActivity(false /* toSide */, false /* randomData */, false /* multipleTaskFlag */,
diff --git a/hostsidetests/services/activitymanager/src/android/server/cts/ActivityManagerAppConfigurationTests.java b/hostsidetests/services/activitymanager/src/android/server/cts/ActivityManagerAppConfigurationTests.java
index 5b21ee9..a5c3149 100644
--- a/hostsidetests/services/activitymanager/src/android/server/cts/ActivityManagerAppConfigurationTests.java
+++ b/hostsidetests/services/activitymanager/src/android/server/cts/ActivityManagerAppConfigurationTests.java
@@ -15,6 +15,9 @@
  */
 package android.server.cts;
 
+import com.android.ddmlib.Log.LogLevel;
+import com.android.tradefed.log.LogUtil.CLog;
+
 import java.awt.Rectangle;
 import java.util.ArrayList;
 import java.util.List;
@@ -33,13 +36,16 @@
      * docked state.
      */
     public void testConfigurationUpdatesWhenResizedFromFullscreen() throws Exception {
+        if (!supportsSplitScreenMultiWindow()) {
+            CLog.logAndDisplay(LogLevel.INFO, "Skipping test: no multi-window support");
+            return;
+        }
+
         launchActivityInStack(RESIZEABLE_ACTIVITY_NAME, FULLSCREEN_WORKSPACE_STACK_ID);
-        final ReportedSizes fullscreenSizes = getActivityDisplaySize(RESIZEABLE_ACTIVITY_NAME,
-                FULLSCREEN_WORKSPACE_STACK_ID);
+        final ReportedSizes fullscreenSizes = getActivityDisplaySize(RESIZEABLE_ACTIVITY_NAME);
 
         moveActivityToStack(RESIZEABLE_ACTIVITY_NAME, DOCKED_STACK_ID);
-        final ReportedSizes dockedSizes = getActivityDisplaySize(RESIZEABLE_ACTIVITY_NAME,
-                DOCKED_STACK_ID);
+        final ReportedSizes dockedSizes = getActivityDisplaySize(RESIZEABLE_ACTIVITY_NAME);
 
         assertSizesAreSane(fullscreenSizes, dockedSizes);
     }
@@ -49,13 +55,16 @@
      * from docked state to fullscreen (reverse).
      */
     public void testConfigurationUpdatesWhenResizedFromDockedStack() throws Exception {
+        if (!supportsSplitScreenMultiWindow()) {
+            CLog.logAndDisplay(LogLevel.INFO, "Skipping test: no multi-window support");
+            return;
+        }
+
         launchActivityInStack(RESIZEABLE_ACTIVITY_NAME, DOCKED_STACK_ID);
-        final ReportedSizes dockedSizes = getActivityDisplaySize(RESIZEABLE_ACTIVITY_NAME,
-                DOCKED_STACK_ID);
+        final ReportedSizes dockedSizes = getActivityDisplaySize(RESIZEABLE_ACTIVITY_NAME);
 
         moveActivityToStack(RESIZEABLE_ACTIVITY_NAME, FULLSCREEN_WORKSPACE_STACK_ID);
-        final ReportedSizes fullscreenSizes = getActivityDisplaySize(RESIZEABLE_ACTIVITY_NAME,
-                FULLSCREEN_WORKSPACE_STACK_ID);
+        final ReportedSizes fullscreenSizes = getActivityDisplaySize(RESIZEABLE_ACTIVITY_NAME);
 
         assertSizesAreSane(fullscreenSizes, dockedSizes);
     }
@@ -64,15 +73,16 @@
      * Tests whether the Display sizes change when rotating the device.
      */
     public void testConfigurationUpdatesWhenRotatingWhileFullscreen() throws Exception {
+        if (!supportsScreenRotation()) {
+            CLog.logAndDisplay(LogLevel.INFO, "Skipping test: no rotation support");
+            return;
+        }
+
         setDeviceRotation(0);
         launchActivityInStack(RESIZEABLE_ACTIVITY_NAME, FULLSCREEN_WORKSPACE_STACK_ID);
-        final ReportedSizes orientationASizes = getActivityDisplaySize(RESIZEABLE_ACTIVITY_NAME,
-                FULLSCREEN_WORKSPACE_STACK_ID);
+        final ReportedSizes initialSizes = getActivityDisplaySize(RESIZEABLE_ACTIVITY_NAME);
 
-        setDeviceRotation(1);
-        final ReportedSizes orientationBSizes = getActivityDisplaySize(RESIZEABLE_ACTIVITY_NAME,
-                FULLSCREEN_WORKSPACE_STACK_ID);
-        assertSizesRotate(orientationASizes, orientationBSizes);
+        rotateAndCheckSizes(initialSizes);
     }
 
     /**
@@ -80,15 +90,73 @@
      * is in the docked stack.
      */
     public void testConfigurationUpdatesWhenRotatingWhileDocked() throws Exception {
-        setDeviceRotation(0);
-        launchActivityInStack(RESIZEABLE_ACTIVITY_NAME, DOCKED_STACK_ID);
-        final ReportedSizes orientationASizes = getActivityDisplaySize(RESIZEABLE_ACTIVITY_NAME,
-                DOCKED_STACK_ID);
+        if (!supportsScreenRotation()) {
+            CLog.logAndDisplay(LogLevel.INFO, "Skipping test: no rotation support");
+            return;
+        }
+        if (!supportsSplitScreenMultiWindow()) {
+            CLog.logAndDisplay(LogLevel.INFO, "Skipping test: no multi-window support");
+            return;
+        }
 
-        setDeviceRotation(1);
-        final ReportedSizes orientationBSizes = getActivityDisplaySize(RESIZEABLE_ACTIVITY_NAME,
-                DOCKED_STACK_ID);
-        assertSizesRotate(orientationASizes, orientationBSizes);
+        setDeviceRotation(0);
+        launchActivityInDockStack(LAUNCHING_ACTIVITY);
+        // Launch our own activity to side in case Recents (or other activity to side) doesn't
+        // support rotation.
+        launchActivityToSide(false /* randomData */, false /* multipleTask */, TEST_ACTIVITY_NAME);
+        // Launch target activity in docked stack.
+        launchActivity(false /* toSide */, false /* randomData */, false /* multipleTask */,
+                RESIZEABLE_ACTIVITY_NAME);
+        final ReportedSizes initialSizes = getActivityDisplaySize(RESIZEABLE_ACTIVITY_NAME);
+
+        rotateAndCheckSizes(initialSizes);
+    }
+
+    /**
+     * Same as {@link #testConfigurationUpdatesWhenRotatingWhileDocked()} but when the Activity
+     * is launched to side from docked stack.
+     */
+    public void testConfigurationUpdatesWhenRotatingToSideFromDocked() throws Exception {
+        if (!supportsScreenRotation()) {
+            CLog.logAndDisplay(LogLevel.INFO, "Skipping test: no rotation support");
+            return;
+        }
+        if (!supportsSplitScreenMultiWindow()) {
+            CLog.logAndDisplay(LogLevel.INFO, "Skipping test: no multi-window support");
+            return;
+        }
+
+        setDeviceRotation(0);
+
+        launchActivityInDockStack(LAUNCHING_ACTIVITY);
+        launchActivityToSide(false /* randomData */, false /* multipleTaskFlag */,
+                RESIZEABLE_ACTIVITY_NAME);
+        final ReportedSizes initialSizes = getActivityDisplaySize(RESIZEABLE_ACTIVITY_NAME);
+
+        rotateAndCheckSizes(initialSizes);
+    }
+
+    private void rotateAndCheckSizes(ReportedSizes prevSizes) throws Exception {
+        for (int rotation = 3; rotation >= 0; --rotation) {
+            clearLogcat();
+            final int actualStackId = mAmWmState.getAmState().getTaskByActivityName(
+                    RESIZEABLE_ACTIVITY_NAME).mStackId;
+            final int displayId = mAmWmState.getAmState().getStackById(actualStackId).mDisplayId;
+            setDeviceRotation(rotation);
+            final int newDeviceRotation = getDeviceRotation(displayId);
+            if (newDeviceRotation == INVALID_DEVICE_ROTATION) {
+                CLog.logAndDisplay(LogLevel.WARN, "Got an invalid device rotation value. "
+                        + "Continuing the test despite of that, but it is likely to fail.");
+            } else if (rotation != newDeviceRotation) {
+                CLog.logAndDisplay(LogLevel.INFO, "This device doesn't support locked user "
+                        + "rotation mode. Not continuing the rotation checks.");
+                return;
+            }
+
+            final ReportedSizes rotatedSizes = getActivityDisplaySize(RESIZEABLE_ACTIVITY_NAME);
+            assertSizesRotate(prevSizes, rotatedSizes);
+            prevSizes = rotatedSizes;
+        }
     }
 
     /**
@@ -114,15 +182,19 @@
      * Asserts that initial and final reported sizes in fullscreen stack are the same.
      */
     private void moveActivityFullSplitFull(String activityName) throws Exception {
+        if (!supportsSplitScreenMultiWindow()) {
+            CLog.logAndDisplay(LogLevel.INFO, "Skipping test: no multi-window support");
+            return;
+        }
+
         // Launch to fullscreen stack and record size.
         launchActivityInStack(activityName, FULLSCREEN_WORKSPACE_STACK_ID);
-        final ReportedSizes initialFullscreenSizes = getActivityDisplaySize(activityName,
-                FULLSCREEN_WORKSPACE_STACK_ID);
+        final ReportedSizes initialFullscreenSizes = getActivityDisplaySize(activityName);
         final Rectangle displayRect = getDisplayRect(activityName);
 
         // Move to docked stack.
         moveActivityToStack(activityName, DOCKED_STACK_ID);
-        final ReportedSizes dockedSizes = getActivityDisplaySize(activityName, DOCKED_STACK_ID);
+        final ReportedSizes dockedSizes = getActivityDisplaySize(activityName);
         assertSizesAreSane(initialFullscreenSizes, dockedSizes);
         // Make sure docked stack is focused. This way when we dismiss it later fullscreen stack
         // will come up.
@@ -136,8 +208,7 @@
                 + displayRect.width + " " + displayRect.height);
         // Move activity back to fullscreen stack.
         moveActivityToStack(activityName, FULLSCREEN_WORKSPACE_STACK_ID);
-        final ReportedSizes finalFullscreenSizes = getActivityDisplaySize(activityName,
-                FULLSCREEN_WORKSPACE_STACK_ID);
+        final ReportedSizes finalFullscreenSizes = getActivityDisplaySize(activityName);
 
         // After activity configuration was changed twice it must report same size as original one.
         assertSizesAreSame(initialFullscreenSizes, finalFullscreenSizes);
@@ -163,10 +234,14 @@
      * Asserts that initial and final reported sizes in docked stack are the same.
      */
     private void moveActivitySplitFullSplit(String activityName) throws Exception {
+        if (!supportsSplitScreenMultiWindow()) {
+            CLog.logAndDisplay(LogLevel.INFO, "Skipping test: no multi-window support");
+            return;
+        }
+
         // Launch to docked stack and record size.
         launchActivityInStack(activityName, DOCKED_STACK_ID);
-        final ReportedSizes initialDockedSizes = getActivityDisplaySize(activityName,
-                DOCKED_STACK_ID);
+        final ReportedSizes initialDockedSizes = getActivityDisplaySize(activityName);
         // Make sure docked stack is focused. This way when we dismiss it later fullscreen stack
         // will come up.
         launchActivityInStack(activityName, DOCKED_STACK_ID);
@@ -175,14 +250,12 @@
 
         // Move to fullscreen stack.
         moveActivityToStack(activityName, FULLSCREEN_WORKSPACE_STACK_ID);
-        final ReportedSizes fullscreenSizes = getActivityDisplaySize(activityName,
-                FULLSCREEN_WORKSPACE_STACK_ID);
+        final ReportedSizes fullscreenSizes = getActivityDisplaySize(activityName);
         assertSizesAreSane(fullscreenSizes, initialDockedSizes);
 
         // Move activity back to docked stack.
         moveActivityToStack(activityName, DOCKED_STACK_ID);
-        final ReportedSizes finalDockedSizes = getActivityDisplaySize(activityName,
-                DOCKED_STACK_ID);
+        final ReportedSizes finalDockedSizes = getActivityDisplaySize(activityName);
 
         // After activity configuration was changed twice it must report same size as original one.
         assertSizesAreSame(initialDockedSizes, finalDockedSizes);
@@ -207,6 +280,8 @@
         final boolean afterConfigPortrait = rotationB.widthDp < rotationB.heightDp;
         assertEquals(beforePortrait, beforeConfigPortrait);
         assertEquals(afterPortrait, afterConfigPortrait);
+
+        assertEquals(rotationA.smallestWidthDp, rotationB.smallestWidthDp);
     }
 
     /**
@@ -238,13 +313,12 @@
         assertEquals(firstSize.displayHeight, secondSize.displayHeight);
         assertEquals(firstSize.metricsWidth, secondSize.metricsWidth);
         assertEquals(firstSize.metricsHeight, secondSize.metricsHeight);
+        assertEquals(firstSize.smallestWidthDp, secondSize.smallestWidthDp);
     }
 
-    private ReportedSizes getActivityDisplaySize(String activityName, int stackId)
-            throws Exception {
+    private ReportedSizes getActivityDisplaySize(String activityName) throws Exception {
         mAmWmState.computeState(mDevice, new String[] { activityName },
                 false /* compareTaskAndStackBounds */);
-        mAmWmState.assertContainsStack("Must contain stack " + stackId, stackId);
         final ReportedSizes details = getLastReportedSizesForActivity(activityName);
         assertNotNull(details);
         return details;
diff --git a/hostsidetests/services/activitymanager/src/android/server/cts/ActivityManagerConfigChangeTests.java b/hostsidetests/services/activitymanager/src/android/server/cts/ActivityManagerConfigChangeTests.java
index e5a121d..d9c8bd0 100644
--- a/hostsidetests/services/activitymanager/src/android/server/cts/ActivityManagerConfigChangeTests.java
+++ b/hostsidetests/services/activitymanager/src/android/server/cts/ActivityManagerConfigChangeTests.java
@@ -16,17 +16,30 @@
 
 package android.server.cts;
 
+import com.android.ddmlib.Log.LogLevel;
+import com.android.tradefed.log.LogUtil.CLog;
+
 public class ActivityManagerConfigChangeTests extends ActivityManagerTestBase {
 
     private static final String TEST_ACTIVITY_NAME = "TestActivity";
     private static final String NO_RELAUNCH_ACTIVITY_NAME = "NoRelaunchActivity";
 
     public void testRotation90Relaunch() throws Exception{
+        if (!supportsScreenRotation()) {
+            CLog.logAndDisplay(LogLevel.INFO, "Skipping test: no rotation support");
+            return;
+        }
+
         // Should relaunch on every rotation and receive no onConfigurationChanged()
         testRotation(TEST_ACTIVITY_NAME, 1, 1, 0);
     }
 
     public void testRotation90NoRelaunch() throws Exception {
+        if (!supportsScreenRotation()) {
+            CLog.logAndDisplay(LogLevel.INFO, "Skipping test: no rotation support");
+            return;
+        }
+
         // Should receive onConfigurationChanged() on every rotation and no relaunch
         testRotation(NO_RELAUNCH_ACTIVITY_NAME, 1, 0, 1);
     }
@@ -58,11 +71,22 @@
 
         final String[] waitForActivitiesVisible = new String[] {activityName};
         mAmWmState.computeState(mDevice, waitForActivitiesVisible);
-        mAmWmState.assertContainsStack(
-                "Must contain fullscreen stack.", FULLSCREEN_WORKSPACE_STACK_ID);
 
-        setDeviceRotation(4 - rotationStep);
+        final int initialRotation = 4 - rotationStep;
+        setDeviceRotation(initialRotation);
         mAmWmState.computeState(mDevice, waitForActivitiesVisible);
+        final int actualStackId = mAmWmState.getAmState().getTaskByActivityName(
+                activityName).mStackId;
+        final int displayId = mAmWmState.getAmState().getStackById(actualStackId).mDisplayId;
+        final int newDeviceRotation = getDeviceRotation(displayId);
+        if (newDeviceRotation == INVALID_DEVICE_ROTATION) {
+            CLog.logAndDisplay(LogLevel.WARN, "Got an invalid device rotation value. "
+                    + "Continuing the test despite of that, but it is likely to fail.");
+        } else if (newDeviceRotation != initialRotation) {
+            CLog.logAndDisplay(LogLevel.INFO, "This device doesn't support user rotation "
+                    + "mode. Not continuing the rotation checks.");
+            return;
+        }
 
         for (int rotation = 0; rotation < 4; rotation += rotationStep) {
             clearLogcat();
@@ -77,8 +101,6 @@
         executeShellCommand(getAmStartCmd(activityName));
         final String[] waitForActivitiesVisible = new String[] {activityName};
         mAmWmState.computeState(mDevice, waitForActivitiesVisible);
-        mAmWmState.assertContainsStack(
-                "Must contain fullscreen stack.", FULLSCREEN_WORKSPACE_STACK_ID);
 
         setFontScale(1.0f);
         mAmWmState.computeState(mDevice, waitForActivitiesVisible);
diff --git a/hostsidetests/services/activitymanager/src/android/server/cts/ActivityManagerDockedStackTests.java b/hostsidetests/services/activitymanager/src/android/server/cts/ActivityManagerDockedStackTests.java
index 19fc84a..773584e 100644
--- a/hostsidetests/services/activitymanager/src/android/server/cts/ActivityManagerDockedStackTests.java
+++ b/hostsidetests/services/activitymanager/src/android/server/cts/ActivityManagerDockedStackTests.java
@@ -16,6 +16,9 @@
 
 package android.server.cts;
 
+import com.android.ddmlib.Log.LogLevel;
+import com.android.tradefed.log.LogUtil.CLog;
+
 import java.awt.Rectangle;
 
 public class ActivityManagerDockedStackTests extends ActivityManagerTestBase {
@@ -31,6 +34,11 @@
     private static final int STACK_SIZE = 300;
 
     public void testStackList() throws Exception {
+        if (!supportsSplitScreenMultiWindow()) {
+            CLog.logAndDisplay(LogLevel.INFO, "Skipping test: no split multi-window support");
+            return;
+        }
+
         executeShellCommand(getAmStartCmd(TEST_ACTIVITY_NAME));
         mAmWmState.computeState(mDevice, new String[] {TEST_ACTIVITY_NAME});
         mAmWmState.assertContainsStack("Must contain home stack.", HOME_STACK_ID);
@@ -40,6 +48,11 @@
     }
 
     public void testDockActivity() throws Exception {
+        if (!supportsMultiWindowMode() || !supportsSplitScreenMultiWindow()) {
+            CLog.logAndDisplay(LogLevel.INFO, "Skipping test: no multi-window support");
+            return;
+        }
+
         launchActivityInDockStack(TEST_ACTIVITY_NAME);
         mAmWmState.computeState(mDevice, new String[] {TEST_ACTIVITY_NAME});
         mAmWmState.assertContainsStack("Must contain home stack.", HOME_STACK_ID);
@@ -47,6 +60,11 @@
     }
 
     public void testNonResizeableNotDocked() throws Exception {
+        if (!supportsSplitScreenMultiWindow()) {
+            CLog.logAndDisplay(LogLevel.INFO, "Skipping test: no split multi-window support");
+            return;
+        }
+
         launchActivityInDockStack(NON_RESIZEABLE_ACTIVITY_NAME);
         mAmWmState.computeState(mDevice, new String[] {NON_RESIZEABLE_ACTIVITY_NAME});
 
@@ -57,6 +75,11 @@
     }
 
     public void testLaunchToSide() throws Exception {
+        if (!supportsMultiWindowMode() || !supportsSplitScreenMultiWindow()) {
+            CLog.logAndDisplay(LogLevel.INFO, "Skipping test: no multi-window support");
+            return;
+        }
+
         launchActivityInDockStack(LAUNCHING_ACTIVITY);
         mAmWmState.computeState(mDevice, new String[] {LAUNCHING_ACTIVITY});
         launchActivityToSide();
@@ -67,6 +90,11 @@
     }
 
     public void testLaunchToSideAndBringToFront() throws Exception {
+        if (!supportsSplitScreenMultiWindow()) {
+            CLog.logAndDisplay(LogLevel.INFO, "Skipping test: no split multi-window support");
+            return;
+        }
+
         launchActivityInDockStack(LAUNCHING_ACTIVITY);
         final String[] waitForFirstVisible = new String[] {TEST_ACTIVITY_NAME};
         final String[] waitForSecondVisible = new String[] {NO_RELAUNCH_ACTIVITY_NAME};
@@ -102,6 +130,11 @@
     }
 
     public void testLaunchToSideMultiple() throws Exception {
+        if (!supportsSplitScreenMultiWindow()) {
+            CLog.logAndDisplay(LogLevel.INFO, "Skipping test: no split multi-window support");
+            return;
+        }
+
         launchActivityInDockStack(LAUNCHING_ACTIVITY);
         mAmWmState.computeState(mDevice, new String[] {LAUNCHING_ACTIVITY});
         final String[] waitForActivitiesVisible =
@@ -143,6 +176,11 @@
 
     private void launchTargetToSide(String targetActivityName,
                                     boolean taskCountMustIncrement) throws Exception {
+        if (!supportsSplitScreenMultiWindow()) {
+            CLog.logAndDisplay(LogLevel.INFO, "Skipping test: no split multi-window support");
+            return;
+        }
+
         launchActivityInDockStack(LAUNCHING_ACTIVITY);
         mAmWmState.computeState(mDevice, new String[] {LAUNCHING_ACTIVITY});
 
@@ -198,6 +236,11 @@
     }
 
     public void testLaunchToSideMultipleWithFlag() throws Exception {
+        if (!supportsSplitScreenMultiWindow()) {
+            CLog.logAndDisplay(LogLevel.INFO, "Skipping test: no split multi-window support");
+            return;
+        }
+
         launchActivityInDockStack(LAUNCHING_ACTIVITY);
         mAmWmState.computeState(mDevice, new String[] {LAUNCHING_ACTIVITY});
         final String[] waitForActivitiesVisible =
@@ -227,6 +270,11 @@
     }
 
     public void testRotationWhenDocked() throws Exception {
+        if (!supportsMultiWindowMode() || !supportsSplitScreenMultiWindow()) {
+            CLog.logAndDisplay(LogLevel.INFO, "Skipping test: no multi-window support");
+            return;
+        }
+
         launchActivityInDockStack(LAUNCHING_ACTIVITY);
         mAmWmState.computeState(mDevice, new String[] {LAUNCHING_ACTIVITY});
         launchActivityToSide();
@@ -262,6 +310,11 @@
     }
 
     public void testRotationWhenDockedWhileLocked() throws Exception {
+        if (!supportsMultiWindowMode() || !supportsSplitScreenMultiWindow())  {
+            CLog.logAndDisplay(LogLevel.INFO, "Skipping test: no multi-window support");
+            return;
+        }
+
         launchActivityInDockStack(LAUNCHING_ACTIVITY);
         mAmWmState.computeState(mDevice, new String[] {LAUNCHING_ACTIVITY});
         launchActivityToSide();
@@ -295,6 +348,11 @@
     }
 
     public void testResizeDockedStack() throws Exception {
+        if (!supportsMultiWindowMode() || !supportsSplitScreenMultiWindow()) {
+            CLog.logAndDisplay(LogLevel.INFO, "Skipping test: no multi-window support");
+            return;
+        }
+
         launchActivityInDockStack(DOCKED_ACTIVITY_NAME);
         mAmWmState.computeState(mDevice, new String[] {DOCKED_ACTIVITY_NAME});
         launchActivityInStack(TEST_ACTIVITY_NAME, FULLSCREEN_WORKSPACE_STACK_ID);
@@ -313,6 +371,10 @@
     }
 
     public void testActivityLifeCycleOnResizeDockedStack() throws Exception {
+        if (!supportsMultiWindowMode() || !supportsSplitScreenMultiWindow()) {
+            CLog.logAndDisplay(LogLevel.INFO, "Skipping test: no multi-window support");
+            return;
+        }
         final String[] waitTestActivityName = new String[] {TEST_ACTIVITY_NAME};
         executeShellCommand(getAmStartCmd(TEST_ACTIVITY_NAME));
         mAmWmState.computeState(mDevice, waitTestActivityName);
@@ -370,9 +432,4 @@
             throws Exception {
         launchActivityToSide(randomData, multipleTaskFlag, null);
     }
-
-    private void launchActivityToSide(boolean randomData, boolean multipleTaskFlag,
-            String targetActivity) throws Exception {
-        launchActivity(true /* toSide */, randomData, multipleTaskFlag, targetActivity);
-    }
 }
diff --git a/hostsidetests/services/activitymanager/src/android/server/cts/ActivityManagerFreeformStackTests.java b/hostsidetests/services/activitymanager/src/android/server/cts/ActivityManagerFreeformStackTests.java
index 3f755fe..cd489fd 100644
--- a/hostsidetests/services/activitymanager/src/android/server/cts/ActivityManagerFreeformStackTests.java
+++ b/hostsidetests/services/activitymanager/src/android/server/cts/ActivityManagerFreeformStackTests.java
@@ -16,6 +16,9 @@
 
 package android.server.cts;
 
+import android.server.cts.ActivityManagerState.ActivityStack;
+import android.server.cts.ActivityManagerState.ActivityTask;
+
 import java.awt.Rectangle;
 import java.util.ArrayList;
 
@@ -26,6 +29,9 @@
     private static final int TEST_TASK_OFFSET_2 = 100;
     private static final int TEST_TASK_SIZE_1 = 900;
     private static final int TEST_TASK_SIZE_2 = TEST_TASK_SIZE_1 * 2;
+    private static final int TEST_TASK_SIZE_DP_1 = 220;
+    private static final int TEST_TASK_SIZE_DP_2 = TEST_TASK_SIZE_DP_1 * 2;
+
     // NOTE: Launching the FreeformActivity will automatically launch the TestActivity
     // with bounds (0, 0, 900, 900)
     private static final String FREEFORM_ACTIVITY = "FreeformActivity";
@@ -54,15 +60,25 @@
                 mAmWmState.getAmState().getTaskByActivityName(TEST_ACTIVITY).getBounds());
     }
 
-    public void testNonResizeableActivityNotLaunchedToFreeform() throws Exception {
+    public void testNonResizeableActivityHasFullDisplayBounds() throws Exception {
         launchActivityInStack(NON_RESIZEABLE_ACTIVITY, FREEFORM_WORKSPACE_STACK_ID);
 
         mAmWmState.computeState(mDevice, new String[] {NON_RESIZEABLE_ACTIVITY});
 
-        mAmWmState.assertFrontStack(
-                "Fullscreen stack must be the front stack.", FULLSCREEN_WORKSPACE_STACK_ID);
-        mAmWmState.assertDoesNotContainStack(
-                "Must not contain freeform stack.", FREEFORM_WORKSPACE_STACK_ID);
+        final ActivityTask task =
+                mAmWmState.getAmState().getTaskByActivityName(NON_RESIZEABLE_ACTIVITY);
+        final ActivityStack stack = mAmWmState.getAmState().getStackById(task.mStackId);
+
+        if (task.isFullscreen()) {
+            // If the task is on the fullscreen stack, then we know that it will have bounds that
+            // fill the entire display.
+            return;
+        }
+
+        // If the task is not on the fullscreen stack, then compare the task bounds to the display
+        // bounds.
+        assertEquals(mAmWmState.getWmState().getDisplay(stack.mDisplayId).getDisplayRect(),
+                task.getBounds());
     }
 
     public void testActivityLifeCycleOnResizeFreeformTask() throws Exception {
@@ -77,18 +93,27 @@
             return;
         }
 
+        final int displayId = mAmWmState.getAmState().getStackById(
+                ActivityManagerTestBase.FREEFORM_WORKSPACE_STACK_ID).mDisplayId;
+        final int densityDpi =
+                mAmWmState.getWmState().getDisplay(displayId).getDpi();
+        final int testTaskSize1 =
+                ActivityAndWindowManagersState.dpToPx(TEST_TASK_SIZE_DP_1, densityDpi);
+        final int testTaskSize2 =
+                ActivityAndWindowManagersState.dpToPx(TEST_TASK_SIZE_DP_2, densityDpi);
+
         resizeActivityTask(TEST_ACTIVITY,
-                TEST_TASK_OFFSET, TEST_TASK_OFFSET, TEST_TASK_SIZE_1, TEST_TASK_SIZE_2);
+                TEST_TASK_OFFSET, TEST_TASK_OFFSET, testTaskSize1, testTaskSize2);
         resizeActivityTask(NO_RELAUNCH_ACTIVITY,
-                TEST_TASK_OFFSET_2, TEST_TASK_OFFSET_2, TEST_TASK_SIZE_1, TEST_TASK_SIZE_2);
+                TEST_TASK_OFFSET_2, TEST_TASK_OFFSET_2, testTaskSize1, testTaskSize2);
 
         mAmWmState.computeState(mDevice, new String[]{TEST_ACTIVITY, NO_RELAUNCH_ACTIVITY});
 
         clearLogcat();
         resizeActivityTask(TEST_ACTIVITY,
-                TEST_TASK_OFFSET, TEST_TASK_OFFSET, TEST_TASK_SIZE_2, TEST_TASK_SIZE_1);
+                TEST_TASK_OFFSET, TEST_TASK_OFFSET, testTaskSize2, testTaskSize1);
         resizeActivityTask(NO_RELAUNCH_ACTIVITY,
-                TEST_TASK_OFFSET_2, TEST_TASK_OFFSET_2, TEST_TASK_SIZE_2, TEST_TASK_SIZE_1);
+                TEST_TASK_OFFSET_2, TEST_TASK_OFFSET_2, testTaskSize2, testTaskSize1);
         mAmWmState.computeState(mDevice, new String[]{TEST_ACTIVITY, NO_RELAUNCH_ACTIVITY});
 
         assertActivityLifecycle(TEST_ACTIVITY, true);
diff --git a/hostsidetests/services/activitymanager/src/android/server/cts/ActivityManagerManifestLayoutTests.java b/hostsidetests/services/activitymanager/src/android/server/cts/ActivityManagerManifestLayoutTests.java
index 2395e55..66d250e 100644
--- a/hostsidetests/services/activitymanager/src/android/server/cts/ActivityManagerManifestLayoutTests.java
+++ b/hostsidetests/services/activitymanager/src/android/server/cts/ActivityManagerManifestLayoutTests.java
@@ -31,6 +31,7 @@
 import static android.server.cts.ActivityAndWindowManagersState.dpToPx;
 import static com.android.ddmlib.Log.LogLevel.INFO;
 
+import com.android.ddmlib.Log.LogLevel;
 import com.android.tradefed.device.DeviceNotAvailableException;
 import com.android.tradefed.log.LogUtil.CLog;
 
@@ -80,6 +81,10 @@
     }
 
     public void testMinimalSizeDocked() throws Exception {
+        if (!supportsSplitScreenMultiWindow()) {
+            CLog.logAndDisplay(INFO, "Skipping test: no multi-window support");
+            return;
+        }
         testMinimalSize(DOCKED_STACK_ID);
     }
 
diff --git a/hostsidetests/services/activitymanager/src/android/server/cts/ActivityManagerReplaceWindowTests.java b/hostsidetests/services/activitymanager/src/android/server/cts/ActivityManagerReplaceWindowTests.java
index 3d68334..c877cb8 100644
--- a/hostsidetests/services/activitymanager/src/android/server/cts/ActivityManagerReplaceWindowTests.java
+++ b/hostsidetests/services/activitymanager/src/android/server/cts/ActivityManagerReplaceWindowTests.java
@@ -47,6 +47,11 @@
     }
 
     private void testReplaceWindow_Dock(boolean relaunch) throws Exception {
+        if (!supportsSplitScreenMultiWindow()) {
+            CLog.logAndDisplay(INFO, "Skipping test: no split multi window support");
+            return;
+        }
+
         final String activityName =
                 relaunch ? SLOW_CREATE_ACTIVITY_NAME : NO_RELAUNCH_ACTIVITY_NAME;
         final String windowName = getWindowName(activityName);
diff --git a/hostsidetests/services/activitymanager/src/android/server/cts/ActivityManagerTestBase.java b/hostsidetests/services/activitymanager/src/android/server/cts/ActivityManagerTestBase.java
index f4d84c7..9b6bb8b 100644
--- a/hostsidetests/services/activitymanager/src/android/server/cts/ActivityManagerTestBase.java
+++ b/hostsidetests/services/activitymanager/src/android/server/cts/ActivityManagerTestBase.java
@@ -26,7 +26,9 @@
 import java.lang.Exception;
 import java.lang.Integer;
 import java.lang.String;
+import java.util.HashMap;
 import java.util.HashSet;
+import java.util.Map;
 import java.util.regex.Matcher;
 import java.util.regex.Pattern;
 
@@ -35,6 +37,8 @@
 public abstract class ActivityManagerTestBase extends DeviceTestCase {
     private static final boolean PRETEND_DEVICE_SUPPORTS_PIP = false;
     private static final boolean PRETEND_DEVICE_SUPPORTS_FREEFORM = false;
+    private static final boolean PRETEND_DEVICE_SUPPORTS_DOCKING = false;
+    private static final boolean PRETEND_DEVICE_SUPPORTS_ROTATION = false;
 
     // Constants copied from ActivityManager.StackId. If they are changed there, these must be
     // updated.
@@ -76,12 +80,21 @@
 
     private static final String AM_MOVE_TASK = "am stack movetask ";
 
+    private static final String AM_SUPPORTS_SPLIT_SCREEN_MULTIWINDOW =
+            "am supports-split-screen-multiwindow";
+
     private static final String INPUT_KEYEVENT_HOME = "input keyevent 3";
 
+    protected static final int INVALID_DEVICE_ROTATION = -1;
+
     /** A reference to the device under test. */
     protected ITestDevice mDevice;
 
     private HashSet<String> mAvailableFeatures;
+    final private String RESULT_KEY_HEAD = "HEAD";
+    final private String NO_HOME_SCREEN_OBSERVER = "NoHomeScreenObserver";
+    private static boolean mCheckedNoHomeScreen = false;
+    private static boolean mNoHomeScreen = false;
 
     protected static String getAmStartCmd(final String activityName) {
         return "am start -n " + getActivityComponentName(activityName);
@@ -190,6 +203,11 @@
         moveActivityToDockStack(activityName);
     }
 
+    protected void launchActivityToSide(boolean randomData, boolean multipleTaskFlag,
+            String targetActivity) throws Exception {
+        launchActivity(true /* toSide */, randomData, multipleTaskFlag, targetActivity);
+    }
+
     protected void moveActivityToDockStack(String activityName) throws Exception {
         moveActivityToStack(activityName, DOCKED_STACK_ID);
     }
@@ -259,6 +277,80 @@
                 || PRETEND_DEVICE_SUPPORTS_FREEFORM;
     }
 
+    protected boolean supportsMultiWindowMode() throws DeviceNotAvailableException {
+        return !hasDeviceFeature("android.hardware.type.watch")
+                || PRETEND_DEVICE_SUPPORTS_DOCKING;
+    }
+
+    protected boolean supportsScreenRotation() throws DeviceNotAvailableException {
+        return !hasDeviceFeature("android.hardware.type.watch")
+                || PRETEND_DEVICE_SUPPORTS_ROTATION;
+    }
+
+    protected boolean supportsSplitScreenMultiWindow() throws DeviceNotAvailableException {
+        CollectingOutputReceiver outputReceiver = new CollectingOutputReceiver();
+        executeShellCommand(AM_SUPPORTS_SPLIT_SCREEN_MULTIWINDOW, outputReceiver);
+        String output = outputReceiver.getOutput();
+        return !output.startsWith("false");
+    }
+
+    protected boolean noHomeScreen() throws DeviceNotAvailableException {
+        if (!mCheckedNoHomeScreen) {
+            try {
+                executeShellCommand("am start -n android.server.app/." + NO_HOME_SCREEN_OBSERVER);
+                waitForResume("android.server.app", NO_HOME_SCREEN_OBSERVER);
+                Map map = getLogResults(NO_HOME_SCREEN_OBSERVER);
+                String value = (String)map.get(RESULT_KEY_HEAD);
+                if (value != null && value.equals("OK")) {
+                    mCheckedNoHomeScreen = true;
+                    mNoHomeScreen = map.get("config_noHomeScreen").equals("true");
+                }
+                executeShellCommand(AM_FORCE_STOP_TEST_PACKAGE);
+            } catch (Exception e) {
+                e.printStackTrace();
+            }
+        }
+        return mNoHomeScreen;
+    }
+
+    private Map<String, String> getLogResults(String className) throws Exception {
+        int retryCount = 3;
+        Map<String, String> output = new HashMap<String, String>();
+        do {
+
+            String logs = executeShellCommand("logcat -v brief -d " + className + ":I" + " *:S");
+            for (String line : logs.split("\\n")) {
+                if (line.startsWith("I/" + className)) {
+                    String payload = line.split(":")[1].trim();
+                    final String[] split = payload.split("=");
+                    if (split.length > 1) {
+                        output.put(split[0], split[1]);
+                    }
+                }
+            }
+            if (output.containsKey(RESULT_KEY_HEAD)) {
+                return output;
+            }
+        } while (retryCount-- > 0);
+        return output;
+    }
+
+    private void waitForResume(String packageName, String activityName) throws Exception {
+        final String fullActivityName = packageName + "." + activityName;
+        int retryCount = 3;
+        do {
+            Thread.sleep(500);
+            String logs = executeShellCommand("logcat -d -b events");
+            for (String line : logs.split("\\n")) {
+                if(line.contains("am_on_resume_called") && line.contains(fullActivityName)) {
+                    return;
+                }
+            }
+        } while (retryCount-- > 0);
+
+        throw new Exception(fullActivityName + " has failed to start");
+    }
+
     protected boolean hasDeviceFeature(String requiredFeature) throws DeviceNotAvailableException {
         if (mAvailableFeatures == null) {
             // TODO: Move this logic to ITestDevice.
@@ -330,6 +422,20 @@
         setUserRotation(rotation);
     }
 
+    protected int getDeviceRotation(int displayId) throws DeviceNotAvailableException {
+        final String displays = runCommandAndPrintOutput("dumpsys display displays").trim();
+        Pattern pattern = Pattern.compile(
+                "(mDisplayId=" + displayId + ")([\\s\\S]*)(mOverrideDisplayInfo)(.*)"
+                        + "(rotation)(\\s+)(\\d+)");
+        Matcher matcher = pattern.matcher(displays);
+        while (matcher.find()) {
+            final String match = matcher.group(7);
+            return Integer.parseInt(match);
+        }
+
+        return INVALID_DEVICE_ROTATION;
+    }
+
     private int getAccelerometerRotation() throws DeviceNotAvailableException {
         final String rotation =
                 runCommandAndPrintOutput("settings get system accelerometer_rotation");
@@ -341,7 +447,7 @@
                 "settings put system accelerometer_rotation " + rotation);
     }
 
-    private int getUserRotation() throws DeviceNotAvailableException {
+    protected int getUserRotation() throws DeviceNotAvailableException {
         final String rotation =
                 runCommandAndPrintOutput("settings get system user_rotation").trim();
         if ("null".equals(rotation)) {
@@ -461,7 +567,7 @@
     private static final Pattern sDestroyPattern = Pattern.compile("(.+): onDestroy");
     private static final Pattern sNewConfigPattern = Pattern.compile(
             "(.+): config size=\\((\\d+),(\\d+)\\) displaySize=\\((\\d+),(\\d+)\\)" +
-            " metricsSize=\\((\\d+),(\\d+)\\)");
+            " metricsSize=\\((\\d+),(\\d+)\\) smallestScreenWidth=(\\d+)");
     private static final Pattern sDisplayStatePattern =
             Pattern.compile("Display Power: state=(.+)");
 
@@ -472,6 +578,15 @@
         int displayHeight;
         int metricsWidth;
         int metricsHeight;
+        int smallestWidthDp;
+
+        @Override
+        public String toString() {
+            return "ReportedSizes: {widthDp=" + widthDp + " heightDp=" + heightDp +
+                    " displayWidth=" + displayWidth + " displayHeight=" + displayHeight +
+                    " metricsWidth=" + metricsWidth + " metricsHeight=" + metricsHeight +
+                    " smallestWidthDp=" + smallestWidthDp + "}";
+        }
     }
 
     protected ReportedSizes getLastReportedSizesForActivity(String activityName)
@@ -488,6 +603,7 @@
                 details.displayHeight = Integer.parseInt(matcher.group(5));
                 details.metricsWidth = Integer.parseInt(matcher.group(6));
                 details.metricsHeight = Integer.parseInt(matcher.group(7));
+                details.smallestWidthDp = Integer.parseInt(matcher.group(8));
                 return details;
             }
         }
diff --git a/hostsidetests/services/windowmanager/src/android/wm/cts/CrossAppDragAndDropTests.java b/hostsidetests/services/windowmanager/src/android/wm/cts/CrossAppDragAndDropTests.java
index 8fc3264..fa1ae69 100644
--- a/hostsidetests/services/windowmanager/src/android/wm/cts/CrossAppDragAndDropTests.java
+++ b/hostsidetests/services/windowmanager/src/android/wm/cts/CrossAppDragAndDropTests.java
@@ -92,15 +92,25 @@
     @Override
     protected void setUp() throws Exception {
         super.setUp();
+
         mDevice = getDevice();
+
+        if (!supportsDragAndDrop()) {
+            return;
+        }
+
         mSourcePackageName = SOURCE_PACKAGE_NAME;
         mTargetPackageName = TARGET_PACKAGE_NAME;
-        cleanupState();
     }
 
     @Override
     protected void tearDown() throws Exception {
         super.tearDown();
+
+        if (!supportsDragAndDrop()) {
+            return;
+        }
+
         mDevice.executeShellCommand(AM_FORCE_STOP + mSourcePackageName);
         mDevice.executeShellCommand(AM_FORCE_STOP + mTargetPackageName);
     }
@@ -288,6 +298,9 @@
 
     private void doTestDragAndDrop(String sourceMode, String targetMode, String expectedDropResult)
             throws Exception {
+        if (!supportsDragAndDrop()) {
+            return;
+        }
 
         launchDockedActivity(mSourcePackageName, SOURCE_ACTIVITY_NAME, sourceMode);
         launchFullscreenActivity(mTargetPackageName, TARGET_ACTIVITY_NAME, targetMode);
@@ -303,8 +316,11 @@
         assertResult(RESULT_KEY_DROP_RESULT, expectedDropResult);
     }
 
+    private void assertResult(String resultKey, String expectedResult) throws Exception {
+        if (!supportsDragAndDrop()) {
+            return;
+        }
 
-    private void assertResult(String resultKey, String expectedResult) {
         if (expectedResult == null) {
             if (mResults.containsKey(resultKey)) {
                 fail("Unexpected " + resultKey + "=" + mResults.get(resultKey));
@@ -315,6 +331,18 @@
         }
     }
 
+    private boolean supportsDragAndDrop() throws Exception {
+        String supportsMultiwindow = mDevice.executeShellCommand("am supports-multiwindow").trim();
+        if ("true".equals(supportsMultiwindow)) {
+            return true;
+        } else if ("false".equals(supportsMultiwindow)) {
+            return false;
+        } else {
+            throw new Exception(
+                    "device does not support \"am supports-multiwindow\" shell command.");
+        }
+    }
+
     public void testCancelSoon() throws Exception {
         doTestDragAndDrop(CANCEL_SOON, REQUEST_NONE, null);
         assertResult(RESULT_KEY_DRAG_STARTED, RESULT_OK);
diff --git a/hostsidetests/shortcuts/hostside/src/android/content/pm/cts/shortcuthost/ShortcutManagerBackupTest.java b/hostsidetests/shortcuts/hostside/src/android/content/pm/cts/shortcuthost/ShortcutManagerBackupTest.java
index 75e6ef5..03e0e5c 100644
--- a/hostsidetests/shortcuts/hostside/src/android/content/pm/cts/shortcuthost/ShortcutManagerBackupTest.java
+++ b/hostsidetests/shortcuts/hostside/src/android/content/pm/cts/shortcuthost/ShortcutManagerBackupTest.java
@@ -40,16 +40,24 @@
     private static final String PUBLISHER3_PKG =
             "android.content.pm.cts.shortcut.backup.publisher3";
 
+    private static final String FEATURE_BACKUP = "android.software.backup";
+
+    private boolean mSupportsBackup;
+
     @Override
     protected void setUp() throws Exception {
         super.setUp();
 
-        clearShortcuts(LAUNCHER1_PKG, getPrimaryUserId());
-        clearShortcuts(LAUNCHER2_PKG, getPrimaryUserId());
-        clearShortcuts(LAUNCHER3_PKG, getPrimaryUserId());
-        clearShortcuts(PUBLISHER1_PKG, getPrimaryUserId());
-        clearShortcuts(PUBLISHER2_PKG, getPrimaryUserId());
-        clearShortcuts(PUBLISHER3_PKG, getPrimaryUserId());
+        mSupportsBackup = getDevice().hasFeature(FEATURE_BACKUP);
+
+        if (mSupportsBackup) {
+            clearShortcuts(LAUNCHER1_PKG, getPrimaryUserId());
+            clearShortcuts(LAUNCHER2_PKG, getPrimaryUserId());
+            clearShortcuts(LAUNCHER3_PKG, getPrimaryUserId());
+            clearShortcuts(PUBLISHER1_PKG, getPrimaryUserId());
+            clearShortcuts(PUBLISHER2_PKG, getPrimaryUserId());
+            clearShortcuts(PUBLISHER3_PKG, getPrimaryUserId());
+        }
     }
 
     @Override
@@ -58,13 +66,15 @@
             dumpsys("tearDown");
         }
 
-        getDevice().uninstallPackage(LAUNCHER1_PKG);
-        getDevice().uninstallPackage(LAUNCHER2_PKG);
-        getDevice().uninstallPackage(LAUNCHER3_PKG);
+        if (mSupportsBackup) {
+            getDevice().uninstallPackage(LAUNCHER1_PKG);
+            getDevice().uninstallPackage(LAUNCHER2_PKG);
+            getDevice().uninstallPackage(LAUNCHER3_PKG);
 
-        getDevice().uninstallPackage(PUBLISHER1_PKG);
-        getDevice().uninstallPackage(PUBLISHER2_PKG);
-        getDevice().uninstallPackage(PUBLISHER3_PKG);
+            getDevice().uninstallPackage(PUBLISHER1_PKG);
+            getDevice().uninstallPackage(PUBLISHER2_PKG);
+            getDevice().uninstallPackage(PUBLISHER3_PKG);
+        }
 
         super.tearDown();
     }
@@ -97,6 +107,10 @@
     }
 
     public void testBackupAndRestore() throws Exception {
+        if (!mSupportsBackup) {
+            return;
+        }
+
         installAppAsUser(LAUNCHER1_APK, getPrimaryUserId());
         installAppAsUser(LAUNCHER2_APK, getPrimaryUserId());
         installAppAsUser(LAUNCHER3_APK, getPrimaryUserId());
@@ -183,6 +197,9 @@
     }
 
     public void testBackupAndRestore_withNoUninstall() throws Exception {
+        if (!mSupportsBackup) {
+            return;
+        }
 
         installAppAsUser(PUBLISHER1_APK, getPrimaryUserId());
 
diff --git a/hostsidetests/sustainedperf/src/android/SustainedPerformance/cts/SustainedPerformanceHostTest.java b/hostsidetests/sustainedperf/src/android/SustainedPerformance/cts/SustainedPerformanceHostTest.java
index 683aded..fffeeb8 100644
--- a/hostsidetests/sustainedperf/src/android/SustainedPerformance/cts/SustainedPerformanceHostTest.java
+++ b/hostsidetests/sustainedperf/src/android/SustainedPerformance/cts/SustainedPerformanceHostTest.java
@@ -193,27 +193,7 @@
         appResultsWithMode.clear();
         dhrystoneResultsWithoutMode.clear();
         dhrystoneResultsWithMode.clear();
-        /*
-         * Run the test without the mode.
-         * Start the application and collect stats.
-         * Run two threads of dhrystone and collect stats.
-         */
-        setUpEnvironment();
-        device.executeShellCommand(START_COMMAND);
-        Thread dhrystone = new Thread(new Dhrystone(false, 1));
-        Thread dhrystone1 = new Thread(new Dhrystone(false, 2));
-        dhrystone.start();
-        dhrystone1.start();
-        Thread.sleep(testDuration);
-        device.executeShellCommand(STOP_COMMAND);
-        dhrystone.join();
-        dhrystone1.join();
-        logs = device.executeAdbCommand("logcat", "-v", "brief", "-d", CLASS + ":I", "*:S");
-        analyzeResults(logs, false);
-        double diff = (dhryMax - dhryMin)*100/dhryMax;
-        dhrystoneResultsWithoutMode.add(0, dhryMin);
-        dhrystoneResultsWithoutMode.add(1, dhryMax);
-        dhrystoneResultsWithoutMode.add(2, diff);
+
         /*
          * Run the test with the mode.
          * Start the application and collect stats.
@@ -221,8 +201,8 @@
          */
         setUpEnvironment();
         device.executeShellCommand(START_COMMAND_MODE);
-        dhrystone = new Thread(new Dhrystone(true, 1));
-        dhrystone1 = new Thread(new Dhrystone(true, 2));
+        Thread dhrystone = new Thread(new Dhrystone(true, 1));
+        Thread dhrystone1 = new Thread(new Dhrystone(true, 2));
         dhrystone.start();
         dhrystone1.start();
         Thread.sleep(testDuration);
@@ -231,7 +211,7 @@
         dhrystone1.join();
         logs = device.executeAdbCommand("logcat", "-v", "brief", "-d", CLASS + ":I", "*:S");
         analyzeResults(logs, true);
-        diff = (dhryMax - dhryMin)*100/dhryMax;
+        double diff = (dhryMax - dhryMin)*100/dhryMax;
         dhrystoneResultsWithMode.add(0, dhryMin);
         dhrystoneResultsWithMode.add(1, dhryMax);
         dhrystoneResultsWithMode.add(2, diff);
@@ -239,21 +219,12 @@
         device.executeShellCommand("settings put global airplane_mode_on 0");
         device.executeShellCommand("am broadcast -a android.intent.action.AIRPLANE_MODE --ez state false");
 
-        double resDhry = dhrystoneResultsWithMode.get(2);
-        double resApp = appResultsWithMode.get(2);
-
-        /* Report if performance is below 5% margin for both dhrystone and shader */
-        if ((resDhry > 5) || (resApp > 5)) {
-            Log.w("SustainedPerformanceHostTests",
-                  "Sustainable mode results, Dhrystone: " + resDhry + " App: " + resApp);
-        }
-
         /*
-         * Error if the performance in the mode is not consistent with
+         * Checks if the performance in the mode is consistent with
          * 5% error margin for shader and 10% error margin for dhrystone.
          */
         assertFalse("Results in the mode are not sustainable",
-                    (resDhry > 15) ||
-                    (resApp > 5));
+                (dhrystoneResultsWithMode.get(2) > 10) ||
+                (appResultsWithMode.get(2)) > 5);
     }
 }
diff --git a/hostsidetests/theme/README b/hostsidetests/theme/README
index b2ae8de..76902e4 100644
--- a/hostsidetests/theme/README
+++ b/hostsidetests/theme/README
@@ -39,7 +39,7 @@
      adb devices
 
   2. Image generation occurs on all devices in parallel. Resulting sets of
-     reference images are saved in assets/<api>/<dpi>.zip and will overwrite
+     reference images are saved in assets/<dpi>.zip and will overwrite
      any existing sets. Image generation may be started using:
 
      ./cts/hostsidetests/theme/generate_images.sh
diff --git a/hostsidetests/theme/app/AndroidManifest.xml b/hostsidetests/theme/app/AndroidManifest.xml
index d39f1ae..d9a89c6 100755
--- a/hostsidetests/theme/app/AndroidManifest.xml
+++ b/hostsidetests/theme/app/AndroidManifest.xml
@@ -31,7 +31,7 @@
                 <category android:name="android.intent.category.LAUNCHER" />
             </intent-filter>
         </activity>
-        <activity android:name=".GenerateImagesActivity"
+        <activity android:name=".GenerateImagesActivity" android:screenOrientation="portrait"
                   android:exported="true" />
     </application>
 
diff --git a/hostsidetests/theme/assets/260dpi.zip b/hostsidetests/theme/assets/260dpi.zip
new file mode 100644
index 0000000..12e1bc2
--- /dev/null
+++ b/hostsidetests/theme/assets/260dpi.zip
Binary files differ
diff --git a/hostsidetests/theme/assets/280dpi.zip b/hostsidetests/theme/assets/280dpi.zip
new file mode 100644
index 0000000..6e40616
--- /dev/null
+++ b/hostsidetests/theme/assets/280dpi.zip
Binary files differ
diff --git a/hostsidetests/theme/assets/420dpi.zip b/hostsidetests/theme/assets/420dpi.zip
index 1c380ff..bf70d35 100644
--- a/hostsidetests/theme/assets/420dpi.zip
+++ b/hostsidetests/theme/assets/420dpi.zip
Binary files differ
diff --git a/hostsidetests/theme/assets/560dpi.zip b/hostsidetests/theme/assets/560dpi.zip
index a171f7c..74e2228 100644
--- a/hostsidetests/theme/assets/560dpi.zip
+++ b/hostsidetests/theme/assets/560dpi.zip
Binary files differ
diff --git a/hostsidetests/theme/assets/hdpi.zip b/hostsidetests/theme/assets/hdpi.zip
new file mode 100644
index 0000000..6cc2d50
--- /dev/null
+++ b/hostsidetests/theme/assets/hdpi.zip
Binary files differ
diff --git a/hostsidetests/theme/assets/mdpi.zip b/hostsidetests/theme/assets/mdpi.zip
new file mode 100644
index 0000000..a350ff6
--- /dev/null
+++ b/hostsidetests/theme/assets/mdpi.zip
Binary files differ
diff --git a/hostsidetests/theme/assets/tvdpi.zip b/hostsidetests/theme/assets/tvdpi.zip
new file mode 100755
index 0000000..553657f
--- /dev/null
+++ b/hostsidetests/theme/assets/tvdpi.zip
Binary files differ
diff --git a/hostsidetests/theme/assets/xhdpi.zip b/hostsidetests/theme/assets/xhdpi.zip
index 96d4ae0..cceab80 100644
--- a/hostsidetests/theme/assets/xhdpi.zip
+++ b/hostsidetests/theme/assets/xhdpi.zip
Binary files differ
diff --git a/hostsidetests/theme/assets/xxhdpi.zip b/hostsidetests/theme/assets/xxhdpi.zip
index 60529ca..05f2b8d 100644
--- a/hostsidetests/theme/assets/xxhdpi.zip
+++ b/hostsidetests/theme/assets/xxhdpi.zip
Binary files differ
diff --git a/hostsidetests/theme/assets/24/xxxhdpi.zip b/hostsidetests/theme/assets/xxxhdpi.zip
similarity index 89%
rename from hostsidetests/theme/assets/24/xxxhdpi.zip
rename to hostsidetests/theme/assets/xxxhdpi.zip
index 4049156..f4e0713 100644
--- a/hostsidetests/theme/assets/24/xxxhdpi.zip
+++ b/hostsidetests/theme/assets/xxxhdpi.zip
Binary files differ
diff --git a/hostsidetests/theme/run_theme_capture_device.py b/hostsidetests/theme/run_theme_capture_device.py
index 8d4c72f..a516717 100755
--- a/hostsidetests/theme/run_theme_capture_device.py
+++ b/hostsidetests/theme/run_theme_capture_device.py
@@ -97,7 +97,6 @@
     print "Found device: " + deviceSerial
     device = androidDevice(deviceSerial)
 
-    outPath = outPath + "/%d" % (device.getSdkLevel())
     density = device.getDensity()
     if CTS_THEME_dict.has_key(density):
         resName = CTS_THEME_dict[density]
diff --git a/hostsidetests/theme/src/android/theme/cts/ComparisonTask.java b/hostsidetests/theme/src/android/theme/cts/ComparisonTask.java
index 5f4a741..d9ed8a1 100755
--- a/hostsidetests/theme/src/android/theme/cts/ComparisonTask.java
+++ b/hostsidetests/theme/src/android/theme/cts/ComparisonTask.java
@@ -36,6 +36,9 @@
 
     private static final int IMAGE_THRESHOLD = 2;
 
+    /** Maximum allowable number of consecutive failed pixels. */
+    private static final int MAX_CONSECUTIVE_FAILURES = 1;
+
     private final File mExpected;
     private final File mActual;
 
@@ -95,6 +98,8 @@
         }
 
         for (int i = 0; i < w; i++) {
+            int consecutive = 0;
+
             for (int j = 0; j < h; j++) {
                 final int p1 = reference.getRGB(i, j);
                 final int p2 = generated.getRGB(i, j);
@@ -106,7 +111,13 @@
                 if (Math.abs(db) > threshold ||
                         Math.abs(dg) > threshold ||
                         Math.abs(dr) > threshold) {
-                    return false;
+                    consecutive++;
+
+                    if (consecutive > MAX_CONSECUTIVE_FAILURES) {
+                        return false;
+                    }
+                } else {
+                    consecutive = 0;
                 }
             }
         }
diff --git a/hostsidetests/theme/src/android/theme/cts/ThemeHostTest.java b/hostsidetests/theme/src/android/theme/cts/ThemeHostTest.java
index e04a10b..eb2cb80 100644
--- a/hostsidetests/theme/src/android/theme/cts/ThemeHostTest.java
+++ b/hostsidetests/theme/src/android/theme/cts/ThemeHostTest.java
@@ -125,7 +125,7 @@
         mCompletionService = new ExecutorCompletionService<>(mExecutionService);
     }
 
-    private Map<String, File> extractReferenceImages(String zipFile) {
+    private Map<String, File> extractReferenceImages(String zipFile) throws Exception {
         final Map<String, File> references = new HashMap<>();
         final InputStream zipStream = ThemeHostTest.class.getResourceAsStream(zipFile);
         if (zipStream != null) {
@@ -150,7 +150,12 @@
                 fail("Failed to unzip assets: " + zipFile);
             }
         } else {
-            fail("Failed to get resource: " + zipFile);
+            if (checkHardwareTypeSkipTest(mDevice.executeShellCommand(HARDWARE_TYPE_CMD).trim())) {
+                Log.logAndDisplay(LogLevel.WARN, LOG_TAG,
+                        "Could not obtain resources for skipped themes test: " + zipFile);
+            } else {
+                fail("Failed to get resource: " + zipFile);
+            }
         }
 
         return references;
diff --git a/hostsidetests/trustedvoice/src/android/trustedvoice/cts/TrustedVoiceHostTest.java b/hostsidetests/trustedvoice/src/android/trustedvoice/cts/TrustedVoiceHostTest.java
index 4b15157..7cea5e5 100644
--- a/hostsidetests/trustedvoice/src/android/trustedvoice/cts/TrustedVoiceHostTest.java
+++ b/hostsidetests/trustedvoice/src/android/trustedvoice/cts/TrustedVoiceHostTest.java
@@ -99,11 +99,9 @@
             getDevice().executeShellCommand(SLEEP_COMMAND);
             // Start the APK and wait for it to complete.
             getDevice().executeShellCommand(START_COMMAND);
-
             // Adding delay for OEM specific features which could delay the time of printing the
             // test log. Please refer to b/62075150 for additional details.
             Thread.sleep(1000);
-
             // Dump logcat.
             String logs = getDevice().executeAdbCommand(
                     "logcat", "-v", "brief", "-d", CLASS + ":I", "*:S");
diff --git a/tests/accessibilityservice/AndroidManifest.xml b/tests/accessibilityservice/AndroidManifest.xml
index 3381f48..e13cdee 100644
--- a/tests/accessibilityservice/AndroidManifest.xml
+++ b/tests/accessibilityservice/AndroidManifest.xml
@@ -67,8 +67,7 @@
 
         <activity
             android:label="@string/accessibility_soft_keyboard_modes_activity"
-            android:name=".AccessibilitySoftKeyboardModesTest$SoftKeyboardModesActivity"
-            android:windowSoftInputMode="stateAlwaysVisible" />
+            android:name=".AccessibilitySoftKeyboardModesTest$SoftKeyboardModesActivity" />
 
         <service
             android:name=".InstrumentedAccessibilityService"
diff --git a/tests/accessibilityservice/src/android/accessibilityservice/cts/AccessibilityEndToEndTest.java b/tests/accessibilityservice/src/android/accessibilityservice/cts/AccessibilityEndToEndTest.java
index d8a1be1..a94345c 100644
--- a/tests/accessibilityservice/src/android/accessibilityservice/cts/AccessibilityEndToEndTest.java
+++ b/tests/accessibilityservice/src/android/accessibilityservice/cts/AccessibilityEndToEndTest.java
@@ -24,6 +24,7 @@
 import android.app.Service;
 import android.app.UiAutomation;
 import android.content.Intent;
+import android.content.pm.PackageManager;
 import android.content.res.Configuration;
 import android.test.suitebuilder.annotation.MediumTest;
 import android.text.TextUtils;
@@ -314,12 +315,18 @@
     @SuppressWarnings("deprecation")
     public void testTypeNotificationStateChangedAccessibilityEvent() throws Throwable {
         // No notification UI on televisions.
-        if((getActivity().getResources().getConfiguration().uiMode
+        if ((getActivity().getResources().getConfiguration().uiMode
                 & Configuration.UI_MODE_TYPE_MASK) == Configuration.UI_MODE_TYPE_TELEVISION) {
             Log.i(LOG_TAG, "Skipping: testTypeNotificationStateChangedAccessibilityEvent" +
                     " - No notification UI on televisions.");
             return;
         }
+        PackageManager pm = getInstrumentation().getTargetContext().getPackageManager();
+        if (pm.hasSystemFeature(pm.FEATURE_WATCH)) {
+            Log.i(LOG_TAG, "Skipping: testTypeNotificationStateChangedAccessibilityEvent" +
+                    " - Watches have different notification system.");
+            return;
+        }
 
         String message = getActivity().getString(R.string.notification_message);
 
@@ -346,32 +353,41 @@
         expected.getText().add(message);
         expected.setParcelableData(notification);
 
-        AccessibilityEvent awaitedEvent =
-            getInstrumentation().getUiAutomation().executeAndWaitForEvent(
-                new Runnable() {
-            @Override
-            public void run() {
-                // trigger the event
-                getActivity().runOnUiThread(new Runnable() {
-                    @Override
-                    public void run() {
-                        // trigger the event
-                        NotificationManager notificationManager =
-                            (NotificationManager) getActivity().getSystemService(
-                                    Service.NOTIFICATION_SERVICE);
-                        notificationManager.notify(notificationId, notification);
-                        getActivity().finish();
-                    }
-                });
-            }},
-            new UiAutomation.AccessibilityEventFilter() {
-                // check the received event
+        AccessibilityEvent awaitedEvent;
+        NotificationManager notificationManager =
+                (NotificationManager) getActivity().getSystemService(Service.NOTIFICATION_SERVICE);
+        try {
+            awaitedEvent = getInstrumentation().getUiAutomation().executeAndWaitForEvent(
+                    new Runnable() {
                 @Override
-                public boolean accept(AccessibilityEvent event) {
-                    return equalsAccessiblityEvent(event, expected);
+                public void run() {
+                    // trigger the event
+                    getActivity().runOnUiThread(new Runnable() {
+                        @Override
+                        public void run() {
+                            // trigger the event
+                            notificationManager.notify(notificationId, notification);
+                        }
+                    });
+                }},
+                new UiAutomation.AccessibilityEventFilter() {
+                    // check the received event
+                    @Override
+                    public boolean accept(AccessibilityEvent event) {
+                        return equalsAccessiblityEvent(event, expected);
+                    }
+                },
+                TIMEOUT_ASYNC_PROCESSING);
+        } finally {
+            getActivity().runOnUiThread(new Runnable() {
+                @Override
+                public void run() {
+                    notificationManager.cancel(notificationId);
+                    getActivity().finish();
                 }
-            },
-            TIMEOUT_ASYNC_PROCESSING);
+            });
+        }
+
         assertNotNull("Did not receive expected event: " + expected, awaitedEvent);
     }
 
diff --git a/tests/accessibilityservice/src/android/accessibilityservice/cts/AccessibilityGestureDispatchTest.java b/tests/accessibilityservice/src/android/accessibilityservice/cts/AccessibilityGestureDispatchTest.java
index 6542778..8dbbeef 100644
--- a/tests/accessibilityservice/src/android/accessibilityservice/cts/AccessibilityGestureDispatchTest.java
+++ b/tests/accessibilityservice/src/android/accessibilityservice/cts/AccessibilityGestureDispatchTest.java
@@ -333,39 +333,38 @@
         }
     }
 
+    // This test assumes device's screen contains its center (W/2, H/2) with some surroundings
+    // and should work for rectangular, round and round with chin screens.
     public void testClickWhenMagnified_matchesActualTouch() throws InterruptedException {
         if (!mHasTouchScreen) {
             return;
         }
 
-        final int clickXInsideView = 10;
-        final int clickYInsideView = 20;
-        int clickX = clickXInsideView + mViewBounds.left;
-        int clickY = clickYInsideView + mViewBounds.top;
+        final int clickShiftFromCenterX = 10;
+        final int clickShiftFromCenterY = 20;
+        final Resources res = getInstrumentation().getTargetContext().getResources();
+        final DisplayMetrics metrics = res.getDisplayMetrics();
+        final int centerX = metrics.widthPixels / 2;
+        final int centerY = metrics.heightPixels / 2;
         final float TOUCH_TOLERANCE = 2.0f;
 
         StubMagnificationAccessibilityService magnificationService =
                 StubMagnificationAccessibilityService.enableSelf(this);
         android.accessibilityservice.AccessibilityService.MagnificationController
                 magnificationController = magnificationService.getMagnificationController();
-        final Resources res = getInstrumentation().getTargetContext().getResources();
-        final DisplayMetrics metrics = res.getDisplayMetrics();
         try {
-            // Magnify screen by 2x from upper left corner
+            // Magnify screen by 2x with a magnification center in the center of the screen
             final AtomicBoolean setScale = new AtomicBoolean();
             final float magnificationFactor = 2.0f;
-            // Center to have (0,0) in the upper-left corner
-            final float centerX = metrics.widthPixels / (2.0f * magnificationFactor) - 1.0f;
-            final float centerY = metrics.heightPixels / (2.0f * magnificationFactor) - 1.0f;
             magnificationService.runOnServiceSync(() -> {
                         setScale.set(magnificationController.setScale(magnificationFactor, false));
-                        // Make sure the upper right corner is on the screen
                         magnificationController.setCenter(centerX, centerY, false);
                     });
             assertTrue("Failed to set scale", setScale.get());
 
-            GestureDescription click = createClick((int) (clickX * magnificationFactor),
-                    (int) (clickY * magnificationFactor));
+            final int clickMagnifiedX = (int) (centerX + magnificationFactor * clickShiftFromCenterX);
+            final int clickMagnifiedY = (int) (centerY + magnificationFactor * clickShiftFromCenterY);
+            GestureDescription click = createClick(clickMagnifiedX, clickMagnifiedY);
             mService.runOnServiceSync(() -> mService.doDispatchGesture(click, mCallback, null));
             mCallback.assertGestureCompletes(GESTURE_COMPLETION_TIMEOUT);
             waitForMotionEvents(3);
@@ -382,14 +381,18 @@
         MotionEvent clickDown = mMotionEvents.get(0);
         MotionEvent clickUp = mMotionEvents.get(1);
 
+        final int centerXInsideView = centerX - mViewBounds.left;
+        final int centerYInsideView = centerY - mViewBounds.top;
+        final int expectedClickXInsideView = centerXInsideView + clickShiftFromCenterX;
+        final int expectedClickYInsideView = centerYInsideView + clickShiftFromCenterY;
         assertEquals(MotionEvent.ACTION_DOWN, clickDown.getActionMasked());
-        assertEquals((float) clickXInsideView, clickDown.getX(), TOUCH_TOLERANCE);
-        assertEquals((float) clickYInsideView, clickDown.getY(), TOUCH_TOLERANCE);
+        assertEquals((float) expectedClickXInsideView, clickDown.getX(), TOUCH_TOLERANCE);
+        assertEquals((float) expectedClickYInsideView, clickDown.getY(), TOUCH_TOLERANCE);
         assertEquals(clickDown.getDownTime(), clickDown.getEventTime());
 
         assertEquals(MotionEvent.ACTION_UP, clickUp.getActionMasked());
-        assertEquals((float) clickXInsideView, clickUp.getX(), TOUCH_TOLERANCE);
-        assertEquals((float) clickYInsideView, clickUp.getY(), TOUCH_TOLERANCE);
+        assertEquals((float) expectedClickXInsideView, clickUp.getX(), TOUCH_TOLERANCE);
+        assertEquals((float) expectedClickYInsideView, clickUp.getY(), TOUCH_TOLERANCE);
     }
 
 
diff --git a/tests/accessibilityservice/src/android/accessibilityservice/cts/AccessibilityGlobalActionsTest.java b/tests/accessibilityservice/src/android/accessibilityservice/cts/AccessibilityGlobalActionsTest.java
index bbda333..486e4fa 100644
--- a/tests/accessibilityservice/src/android/accessibilityservice/cts/AccessibilityGlobalActionsTest.java
+++ b/tests/accessibilityservice/src/android/accessibilityservice/cts/AccessibilityGlobalActionsTest.java
@@ -58,20 +58,23 @@
 
     @MediumTest
     public void testPerformGlobalActionRecents() throws Exception {
-        // Check whether the action succeeded.
-        assertTrue(getInstrumentation().getUiAutomation().performGlobalAction(
-                AccessibilityService.GLOBAL_ACTION_RECENTS));
+        // Perform the action.
+        boolean actionWasPerformed =
+                getInstrumentation().getUiAutomation().performGlobalAction(
+                        AccessibilityService.GLOBAL_ACTION_RECENTS);
 
         // Sleep a bit so the UI is settled.
         waitForIdle();
 
-        // This is a necessary since the back action does not
-        // dismiss recents until they stop animating. Sigh...
-        SystemClock.sleep(5000);
+        if (actionWasPerformed) {
+            // This is a necessary since the back action does not
+            // dismiss recents until they stop animating. Sigh...
+            SystemClock.sleep(5000);
 
-        // Clean up.
-        getInstrumentation().getUiAutomation().performGlobalAction(
-                AccessibilityService.GLOBAL_ACTION_BACK);
+            // Clean up.
+            getInstrumentation().getUiAutomation().performGlobalAction(
+                    AccessibilityService.GLOBAL_ACTION_BACK);
+        }
 
         // Sleep a bit so the UI is settled.
         waitForIdle();
diff --git a/tests/accessibilityservice/src/android/accessibilityservice/cts/AccessibilitySoftKeyboardModesTest.java b/tests/accessibilityservice/src/android/accessibilityservice/cts/AccessibilitySoftKeyboardModesTest.java
index 263c402..58d8355 100644
--- a/tests/accessibilityservice/src/android/accessibilityservice/cts/AccessibilitySoftKeyboardModesTest.java
+++ b/tests/accessibilityservice/src/android/accessibilityservice/cts/AccessibilitySoftKeyboardModesTest.java
@@ -16,25 +16,25 @@
 
 import android.accessibilityservice.AccessibilityServiceInfo;
 import android.accessibilityservice.AccessibilityService.SoftKeyboardController;
+import android.app.Activity;
 import android.app.UiAutomation;
-import android.content.ContentResolver;
-import android.content.Context;
 import android.os.Bundle;
-import android.os.ParcelFileDescriptor;
+import android.os.Handler;
+import android.os.IBinder;
+import android.os.ResultReceiver;
 import android.os.SystemClock;
-import android.provider.Settings;
 import android.test.ActivityInstrumentationTestCase2;
+import android.view.View;
 import android.view.accessibility.AccessibilityEvent;
-import android.view.accessibility.AccessibilityManager;
 
 import android.accessibilityservice.cts.R;
+import android.view.accessibility.AccessibilityWindowInfo;
+import android.view.inputmethod.InputMethodManager;
 
-import java.io.BufferedReader;
-import java.io.FileInputStream;
-import java.io.InputStream;
-import java.io.InputStreamReader;
-import java.nio.charset.StandardCharsets;
 import java.util.List;
+import java.util.concurrent.ArrayBlockingQueue;
+import java.util.concurrent.BlockingQueue;
+import java.util.concurrent.TimeUnit;
 import java.util.concurrent.TimeoutException;
 
 /**
@@ -56,6 +56,12 @@
      */
     private static final long TIMEOUT_ACCESSIBILITY_STATE_IDLE = 500;
 
+    /**
+     * The timeout since {@link InputMethodManager#showSoftInput(View, int, ResultReceiver)}
+     * is called to {@link ResultReceiver#onReceiveResult(int, Bundle)} is called back.
+     */
+    private static final int TIMEOUT_SHOW_SOFTINPUT_RESULT = 2000;
+
     private static final int SHOW_MODE_AUTO = 0;
     private static final int SHOW_MODE_HIDDEN = 1;
 
@@ -91,7 +97,11 @@
 
     @Override
     public void tearDown() throws Exception {
+        mKeyboardController.setShowMode(SHOW_MODE_AUTO);
         mService.runOnServiceSync(() -> mService.disableSelf());
+        Activity activity = getActivity();
+        activity.getSystemService(InputMethodManager.class)
+                .hideSoftInputFromWindow(activity.getCurrentFocus().getWindowToken(), 0);
     }
 
     public void testApiReturnValues_shouldChangeValueOnRequestAndSendCallback() throws Exception {
@@ -109,7 +119,7 @@
                 };
         mKeyboardController.addOnShowModeChangedListener(listener);
 
-        // The soft keyboard should be in its' default mode.
+        // The soft keyboard should be in its default mode.
         assertEquals(SHOW_MODE_AUTO, mKeyboardController.getShowMode());
 
         // Set the show mode to SHOW_MODE_HIDDEN.
@@ -130,56 +140,24 @@
         assertTrue(mKeyboardController.removeOnShowModeChangedListener(listener));
     }
 
-    public void testHideSoftKeyboard_shouldHideAndShowKeyboardOnRequest() throws Exception {
-        // The soft keyboard should be in its' default mode.
+    public void testHideSoftKeyboard_shouldHideKeyboardOnRequest() throws Exception {
+        // The soft keyboard should be in its default mode.
         assertEquals(SHOW_MODE_AUTO, mKeyboardController.getShowMode());
 
-        // Note: This Activity always has a visible keyboard (due to windowSoftInputMode being set
-        // to stateAlwaysVisible).
-        waitForIdle();
-        int numWindowsWithIme = mUiAutomation.getWindows().size();
+        if (!tryShowSoftInput()) {
+            // If the current (default) IME declined to show its window, then there is nothing we
+            // can test here.
+            // TODO: Create a mock IME so that we can test only the framework behavior.
+            return;
+        }
 
+        waitForImePresentToBe(true);
         // Request the keyboard be hidden.
         assertTrue(mKeyboardController.setShowMode(SHOW_MODE_HIDDEN));
-        waitForWindowStateChanged();
-        waitForIdle();
 
-        // Make sure the keyboard is hidden.
-        assertEquals(numWindowsWithIme - 1, mUiAutomation.getWindows().size());
+        waitForImePresentToBe(false);
 
-        // Request the default keyboard mode.
         assertTrue(mKeyboardController.setShowMode(SHOW_MODE_AUTO));
-        waitForWindowStateChanged();
-        waitForIdle();
-
-        // Make sure the keyboard is visible.
-        assertEquals(numWindowsWithIme, mUiAutomation.getWindows().size());
-    }
-
-    public void testHideSoftKeyboard_shouldHideKeyboardUntilServiceIsDisabled() throws Exception {
-        // The soft keyboard should be in its' default mode.
-        assertEquals(SHOW_MODE_AUTO, mKeyboardController.getShowMode());
-
-        // Note: This Activity always has a visible keyboard (due to windowSoftInputMode being set
-        // to stateAlwaysVisible).
-        waitForIdle();
-        int numWindowsWithIme = mUiAutomation.getWindows().size();
-
-        // Set the show mode to SHOW_MODE_HIDDEN.
-        assertTrue(mKeyboardController.setShowMode(SHOW_MODE_HIDDEN));
-        waitForWindowStateChanged();
-        waitForIdle();
-
-        // Make sure the keyboard is hidden.
-        assertEquals(numWindowsWithIme - 1, mUiAutomation.getWindows().size());
-
-        // Make sure we can see the soft keyboard once all Accessibility Services are disabled.
-        mService.disableSelf();
-        waitForWindowStateChanged();
-        waitForIdle();
-
-        // See how many windows are present.
-        assertEquals(numWindowsWithIme, mUiAutomation.getWindows().size());
     }
 
     private void waitForCallbackValueWithLock(int expectedValue) throws Exception {
@@ -202,7 +180,7 @@
                 + "> does not match expected value < " + expectedValue + ">");
     }
 
-    private void waitForWindowStateChanged() throws Exception {
+    private void waitForWindowChanges() {
         try {
             mUiAutomation.executeAndWaitForEvent(new Runnable() {
                 @Override
@@ -223,8 +201,64 @@
         }
     }
 
-    private void waitForIdle() throws TimeoutException {
-        mUiAutomation.waitForIdle(TIMEOUT_ACCESSIBILITY_STATE_IDLE, TIMEOUT_ASYNC_PROCESSING);
+    private boolean isImeWindowPresent() {
+        List<AccessibilityWindowInfo> windows = mUiAutomation.getWindows();
+        for (int i = 0; i < windows.size(); i++) {
+            if (windows.get(i).getType() == AccessibilityWindowInfo.TYPE_INPUT_METHOD) {
+                return true;
+            }
+        }
+        return false;
+    }
+
+    private void waitForImePresentToBe(boolean imeShown) {
+        long timeOutTime = System.currentTimeMillis() + TIMEOUT_ASYNC_PROCESSING;
+        while (isImeWindowPresent() != imeShown) {
+            assertTrue(System.currentTimeMillis() < timeOutTime);
+            waitForWindowChanges();
+        }
+    }
+
+    /**
+     * Tries to call {@link InputMethodManager#hideSoftInputFromWindow(IBinder, int)} to see if
+     * software keyboard is shown as a result or not.
+     * @return {@code true} if the current input method reported that it is currently shown
+     * @throws Exception when the result is unknown, including the system did not return the result
+     *                   within {@link #TIMEOUT_SHOW_SOFTINPUT_RESULT}
+     */
+    private boolean tryShowSoftInput() throws Exception {
+        final BlockingQueue<Integer> queue = new ArrayBlockingQueue<>(1);
+
+        getInstrumentation().runOnMainSync(() -> {
+            Activity activity = getActivity();
+            ResultReceiver resultReceiver =
+                    new ResultReceiver(new Handler(activity.getMainLooper())) {
+                            @Override
+                            protected void onReceiveResult(int resultCode, Bundle resultData) {
+                                queue.add(resultCode);
+                            }
+                    };
+            View editText = activity.findViewById(R.id.edit_text);
+            activity.getSystemService(InputMethodManager.class)
+                    .showSoftInput(editText, InputMethodManager.SHOW_FORCED, resultReceiver);
+        });
+
+        Integer result;
+        try {
+            result = queue.poll(TIMEOUT_SHOW_SOFTINPUT_RESULT, TimeUnit.MILLISECONDS);
+        } catch (InterruptedException e) {
+            throw new Exception("Failed to get the result of showSoftInput().", e);
+        }
+        if (result == null) {
+            throw new Exception("Failed to get the result of showSoftInput() within timeout.");
+        }
+        switch (result) {
+            case InputMethodManager.RESULT_SHOWN:
+            case InputMethodManager.RESULT_UNCHANGED_SHOWN:
+                return true;
+            default:
+                return false;
+        }
     }
 
     /**
diff --git a/tests/accessibilityservice/src/android/accessibilityservice/cts/AccessibilityWindowQueryTest.java b/tests/accessibilityservice/src/android/accessibilityservice/cts/AccessibilityWindowQueryTest.java
index fae014e..4a00f77 100755
--- a/tests/accessibilityservice/src/android/accessibilityservice/cts/AccessibilityWindowQueryTest.java
+++ b/tests/accessibilityservice/src/android/accessibilityservice/cts/AccessibilityWindowQueryTest.java
@@ -31,6 +31,7 @@
 import android.graphics.Rect;
 import android.test.suitebuilder.annotation.MediumTest;
 import android.view.Gravity;
+import android.view.View;
 import android.view.Window;
 import android.view.WindowManager;
 import android.view.accessibility.AccessibilityEvent;
@@ -54,7 +55,8 @@
  */
 public class AccessibilityWindowQueryTest
         extends AccessibilityActivityTestCase<AccessibilityWindowQueryActivity> {
-
+    private static String CONTENT_VIEW_RES_NAME =
+            "android.accessibilityservice.cts:id/added_content";
     private static final long TIMEOUT_WINDOW_STATE_IDLE = 500;
 
     public AccessibilityWindowQueryTest() {
@@ -62,10 +64,27 @@
     }
 
     @MediumTest
-    public void testFindByText() throws Exception {
+    public void testFindByText() throws Throwable {
+        // First, make the root view of the activity an accessibility node. This allows us to
+        // later exclude views that are part of the activity's DecorView.
+        runTestOnUiThread(new Runnable() {
+            @Override
+            public void run() {
+                getActivity().findViewById(R.id.added_content)
+                    .setImportantForAccessibility(View.IMPORTANT_FOR_ACCESSIBILITY_YES);
+            }
+        });
+
+        // Start looking from the added content instead of from the root accessibility node so
+        // that nodes that we don't expect (i.e. window control buttons) are not included in the
+        // list of accessibility nodes returned by findAccessibilityNodeInfosByText.
+        final AccessibilityNodeInfo addedContent = getInstrumentation().getUiAutomation()
+                .getRootInActiveWindow().findAccessibilityNodeInfosByViewId(CONTENT_VIEW_RES_NAME)
+                        .get(0);
+
         // find a view by text
-        List<AccessibilityNodeInfo> buttons = getInstrumentation().getUiAutomation()
-                .getRootInActiveWindow().findAccessibilityNodeInfosByText("b");
+        List<AccessibilityNodeInfo> buttons = addedContent.findAccessibilityNodeInfosByText("b");
+
         assertEquals(9, buttons.size());
     }
 
@@ -825,7 +844,6 @@
             classNameAndTextList.add("android.widget.ButtonB8");
             classNameAndTextList.add("android.widget.ButtonB9");
 
-            String contentViewIdResName = "android.accessibilityservice.cts:id/added_content";
             boolean verifyContent = false;
 
             Queue<AccessibilityNodeInfo> fringe = new LinkedList<AccessibilityNodeInfo>();
@@ -836,7 +854,7 @@
                 AccessibilityNodeInfo current = fringe.poll();
 
                 if (!verifyContent
-                        && contentViewIdResName.equals(current.getViewIdResourceName())) {
+                        && CONTENT_VIEW_RES_NAME.equals(current.getViewIdResourceName())) {
                     verifyContent = true;
                 }
 
diff --git a/tests/app/app/AndroidManifest.xml b/tests/app/app/AndroidManifest.xml
index 10a6792..b5460a6 100644
--- a/tests/app/app/AndroidManifest.xml
+++ b/tests/app/app/AndroidManifest.xml
@@ -329,6 +329,21 @@
 
         <activity android:name="android.app.stubs.KeyboardShortcutsActivity" />
 
+        <service
+            android:name="android.app.stubs.LiveWallpaper"
+            android:icon="@drawable/robot"
+            android:label="@string/wallpaper_title"
+            android:permission="android.permission.BIND_WALLPAPER">
+            <intent-filter>
+                <action android:name="android.service.wallpaper.WallpaperService">
+                </action>
+            </intent-filter>
+            <meta-data
+                android:name="android.service.wallpaper"
+                android:resource="@xml/wallpaper">
+            </meta-data>
+        </service>
+
     </application>
 
 </manifest>
diff --git a/tests/app/app/res/values/strings.xml b/tests/app/app/res/values/strings.xml
index 5e9e6d7..839e398 100644
--- a/tests/app/app/res/values/strings.xml
+++ b/tests/app/app/res/values/strings.xml
@@ -177,4 +177,10 @@
 I think so, so how about double this string, like copy and paste! </string>
     <string name="rectangle200">"M 0,0 l 200,0 l 0, 200 l -200, 0 z"</string>
     <string name="hello">Hello World</string>
+
+    <string name="wallpaper_description">Description</string>
+    <string name="wallpaper_collection">Collection</string>
+    <string name="wallpaper_title">Title</string>
+    <string name="wallpaper_context">Context</string>
+    <string name="wallpaper_context_uri">http://android.com</string>
 </resources>
diff --git a/tests/app/app/res/xml/wallpaper.xml b/tests/app/app/res/xml/wallpaper.xml
new file mode 100644
index 0000000..f70b20f
--- /dev/null
+++ b/tests/app/app/res/xml/wallpaper.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  ~ Copyright (C) 2016 The Android Open Source Project
+  ~
+  ~ Licensed under the Apache License, Version 2.0 (the "License");
+  ~ you may not use this file except in compliance with the License.
+  ~ You may obtain a copy of the License at
+  ~
+  ~      http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing, software
+  ~ distributed under the License is distributed on an "AS IS" BASIS,
+  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  ~ See the License for the specific language governing permissions and
+  ~ limitations under the License
+  -->
+<wallpaper
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    android:thumbnail="@drawable/icon_red"
+    android:author="@string/wallpaper_collection"
+    android:description="@string/wallpaper_description"
+    android:showMetadataInPreview="true"
+    android:contextDescription="@string/wallpaper_context"
+    android:contextUri="@string/wallpaper_context_uri"
+/>
\ No newline at end of file
diff --git a/tests/app/app/src/android/app/stubs/LiveWallpaper.java b/tests/app/app/src/android/app/stubs/LiveWallpaper.java
new file mode 100644
index 0000000..5b8a82e
--- /dev/null
+++ b/tests/app/app/src/android/app/stubs/LiveWallpaper.java
@@ -0,0 +1,27 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.app.stubs;
+
+import android.service.wallpaper.WallpaperService;
+
+public class LiveWallpaper extends WallpaperService {
+
+    @Override
+    public Engine onCreateEngine() {
+        return new Engine();
+    }
+}
diff --git a/tests/app/src/android/app/cts/ActivityManagerMemoryClassTest.java b/tests/app/src/android/app/cts/ActivityManagerMemoryClassTest.java
index 2b84be6..fefa546 100644
--- a/tests/app/src/android/app/cts/ActivityManagerMemoryClassTest.java
+++ b/tests/app/src/android/app/cts/ActivityManagerMemoryClassTest.java
@@ -27,6 +27,8 @@
 import android.view.Display;
 import android.view.WindowManager;
 
+import com.android.compatibility.common.util.CddTest;
+
 import java.util.HashMap;
 import java.util.Map;
 
@@ -148,6 +150,7 @@
         }
     }
 
+    @CddTest(requirement="3.7")
     public void testGetMemoryClass() throws Exception {
         int memoryClass = getMemoryClass();
         int screenDensity = getScreenDensity();
diff --git a/tests/app/src/android/app/cts/ActivityManagerTest.java b/tests/app/src/android/app/cts/ActivityManagerTest.java
index 9049171..5b0706b 100644
--- a/tests/app/src/android/app/cts/ActivityManagerTest.java
+++ b/tests/app/src/android/app/cts/ActivityManagerTest.java
@@ -36,6 +36,7 @@
 import android.content.Intent;
 import android.content.IntentFilter;
 import android.content.pm.ConfigurationInfo;
+import android.content.res.Resources;
 import android.platform.test.annotations.RestrictedBuildTest;
 import android.test.InstrumentationTestCase;
 
@@ -395,6 +396,20 @@
         Thread.sleep(WAIT_TIME);
     }
 
+   /**
+    * Gets the value of com.android.internal.R.bool.config_noHomeScreen.
+    * @return true if no home screen is supported, false otherwise.
+    */
+   private boolean noHomeScreen() {
+       try {
+           return getInstrumentation().getContext().getResources().getBoolean(
+                   Resources.getSystem().getIdentifier("config_noHomeScreen", "bool", "android"));
+       } catch (Resources.NotFoundException e) {
+           // Assume there's a home screen.
+           return false;
+       }
+    }
+
     /**
      * Verify that the TimeTrackingAPI works properly when starting and ending an activity.
      */
@@ -426,10 +441,20 @@
         assertEquals(RESULT_PASS, appEndReceiver.waitForActivity());
         appEndReceiver.close();
 
-        // At this time the timerReceiver should not fire, even though the activity has shut down,
-        // because we are back to the home screen.
-        assertEquals(RESULT_TIMEOUT, timeReceiver.waitForActivity());
-        assertTrue(timeReceiver.mTimeUsed == 0);
+        if (!noHomeScreen()) {
+            // At this time the timerReceiver should not fire, even though the activity has shut
+            // down, because we are back to the home screen. Going to the home screen does not
+            // qualify as the user leaving the activity's flow. The time tracking is considered
+            // complete only when the user switches to another activity that is not part of the
+            // tracked flow.
+            assertEquals(RESULT_TIMEOUT, timeReceiver.waitForActivity());
+            assertTrue(timeReceiver.mTimeUsed == 0);
+        } else {
+            // With platforms that have no home screen, focus is returned to something else that is
+            // considered a completion of the tracked activity flow, and hence time tracking is
+            // triggered.
+            assertEquals(RESULT_PASS, timeReceiver.waitForActivity());
+        }
 
         // Issuing now another activity will trigger the timing information release.
         final Intent dummyIntent = new Intent(context, MockApplicationActivity.class);
@@ -522,9 +547,20 @@
         assertEquals(RESULT_PASS, appEndReceiver.waitForActivity());
         appEndReceiver.close();
 
-        // At this time the timerReceiver should not fire, even though the activity has shut down.
-        assertEquals(RESULT_TIMEOUT, timeReceiver.waitForActivity());
-        assertTrue(timeReceiver.mTimeUsed == 0);
+        if (!noHomeScreen()) {
+            // At this time the timerReceiver should not fire, even though the activity has shut
+            // down, because we are back to the home screen. Going to the home screen does not
+            // qualify as the user leaving the activity's flow. The time tracking is considered
+            // complete only when the user switches to another activity that is not part of the
+            // tracked flow.
+            assertEquals(RESULT_TIMEOUT, timeReceiver.waitForActivity());
+            assertTrue(timeReceiver.mTimeUsed == 0);
+        } else {
+            // With platforms that have no home screen, focus is returned to something else that is
+            // considered a completion of the tracked activity flow, and hence time tracking is
+            // triggered.
+            assertEquals(RESULT_PASS, timeReceiver.waitForActivity());
+        }
 
         // Issue another activity so that the timing information gets released.
         final Intent dummyIntent = new Intent(context, MockApplicationActivity.class);
diff --git a/tests/app/src/android/app/cts/ApplicationTest.java b/tests/app/src/android/app/cts/ApplicationTest.java
index aaed064..664d3ee 100644
--- a/tests/app/src/android/app/cts/ApplicationTest.java
+++ b/tests/app/src/android/app/cts/ApplicationTest.java
@@ -57,7 +57,13 @@
             }
         });
         instrumentation.waitForIdleSync();
-        assertTrue(mockApp.isOnConfigurationChangedCalled);
+        final boolean isInMultiwindowMode = activity.isInMultiWindowMode();
+        if (activity.isInMultiWindowMode()) {
+            assertFalse("Orientation change should not trigger global configuration change when "
+                    + " in multi-window mode.", mockApp.isOnConfigurationChangedCalled);
+        } else {
+            assertTrue(mockApp.isOnConfigurationChangedCalled);
+        }
     }
 
 }
diff --git a/tests/app/src/android/app/cts/DownloadManagerTest.java b/tests/app/src/android/app/cts/DownloadManagerTest.java
index 50eb96b..1bec983 100644
--- a/tests/app/src/android/app/cts/DownloadManagerTest.java
+++ b/tests/app/src/android/app/cts/DownloadManagerTest.java
@@ -34,6 +34,8 @@
 import android.util.Log;
 import android.webkit.cts.CtsTestServer;
 
+import com.android.compatibility.common.util.CddTest;
+
 import java.io.File;
 import java.util.Arrays;
 import java.util.HashSet;
@@ -181,6 +183,7 @@
         }
     }
 
+    @CddTest(requirement="7.6.1")
     public void testMinimumDownload() throws Exception {
         final DownloadCompleteReceiver receiver = new DownloadCompleteReceiver();
         try {
diff --git a/tests/app/src/android/app/cts/PipNotResizeableActivityTest.java b/tests/app/src/android/app/cts/PipNotResizeableActivityTest.java
index 7189dc1..e2a4aff 100644
--- a/tests/app/src/android/app/cts/PipNotResizeableActivityTest.java
+++ b/tests/app/src/android/app/cts/PipNotResizeableActivityTest.java
@@ -51,7 +51,6 @@
                         pipSupportDisabled = true;
                     }
                     assertTrue(pipSupportDisabled);
-                    assertFalse(mActivity.isInMultiWindowMode());
                     assertFalse(mActivity.isInPictureInPictureMode());
                 }
             });
diff --git a/tests/app/src/android/app/cts/PipNotSupportedActivityTest.java b/tests/app/src/android/app/cts/PipNotSupportedActivityTest.java
index e8d13dc..d33ff4d 100644
--- a/tests/app/src/android/app/cts/PipNotSupportedActivityTest.java
+++ b/tests/app/src/android/app/cts/PipNotSupportedActivityTest.java
@@ -51,7 +51,6 @@
                     pipSupportDisabled = true;
                 }
                 assertTrue(pipSupportDisabled);
-                assertFalse(mActivity.isInMultiWindowMode());
                 assertFalse(mActivity.isInPictureInPictureMode());
             }
         });
diff --git a/tests/app/src/android/app/cts/SearchManagerTest.java b/tests/app/src/android/app/cts/SearchManagerTest.java
index 13a8073..bf7e2f9 100644
--- a/tests/app/src/android/app/cts/SearchManagerTest.java
+++ b/tests/app/src/android/app/cts/SearchManagerTest.java
@@ -16,11 +16,13 @@
 
 package android.app.cts;
 
+import android.app.SearchManager;
+import android.app.UiModeManager;
 import android.app.stubs.CTSActivityTestCaseBase;
 import android.app.stubs.SearchManagerStubActivity;
 import android.content.Context;
 import android.content.Intent;
-import android.content.pm.PackageManager;
+import android.content.res.Configuration;
 
 public class SearchManagerTest extends CTSActivityTestCaseBase {
 
@@ -33,7 +35,7 @@
     }
 
     public void testStopSearch() throws InterruptedException {
-        if (isTelevision()) {
+        if (!hasGlobalSearchActivity()) {
             return;
         }
         SearchManagerStubActivity.setCTSResult(this);
@@ -42,7 +44,7 @@
     }
 
     public void testSetOnDismissListener() throws InterruptedException {
-        if (isTelevision()) {
+        if (!hasGlobalSearchActivity()) {
             return;
         }
         SearchManagerStubActivity.setCTSResult(this);
@@ -51,7 +53,7 @@
     }
 
     public void testSetOnCancelListener() throws InterruptedException {
-        if (isTelevision()) {
+        if (!hasGlobalSearchActivity()) {
             return;
         }
         SearchManagerStubActivity.setCTSResult(this);
@@ -59,10 +61,22 @@
         waitForResult();
     }
 
-    private boolean isTelevision() {
+    private boolean hasGlobalSearchActivity() {
         Context context = getInstrumentation().getTargetContext();
-        PackageManager pm = context.getPackageManager();
-        return pm.hasSystemFeature(PackageManager.FEATURE_TELEVISION)
-                || pm.hasSystemFeature(PackageManager.FEATURE_LEANBACK);
+        UiModeManager uiModeManager = context.getSystemService(UiModeManager.class);
+        if (uiModeManager.getCurrentModeType() == Configuration.UI_MODE_TYPE_TELEVISION) {
+            return false;
+        }
+        SearchManager searchManager =
+                (SearchManager) context.getSystemService(Context.SEARCH_SERVICE);
+        if (searchManager == null) {
+            return false;
+        }
+        try {
+            return searchManager.getGlobalSearchActivity() != null;
+        } catch (NullPointerException e) {
+            // Means there is no internal search service.
+            return false;
+        }
     }
 }
diff --git a/tests/app/src/android/app/cts/SystemFeaturesTest.java b/tests/app/src/android/app/cts/SystemFeaturesTest.java
index 979d18a..f03c549 100644
--- a/tests/app/src/android/app/cts/SystemFeaturesTest.java
+++ b/tests/app/src/android/app/cts/SystemFeaturesTest.java
@@ -474,6 +474,10 @@
         if (!mPackageManager.hasSystemFeature(PackageManager.FEATURE_AUTOMOTIVE) &&
                 !mPackageManager.hasSystemFeature(PackageManager.FEATURE_TELEVISION) &&
                 !mPackageManager.hasSystemFeature(PackageManager.FEATURE_WATCH)) {
+            // USB accessory mode is only a requirement for devices with USB ports supporting
+            // peripheral mode. As there is no public API to distinguish a device with only host
+            // mode support from having both peripheral and host support, the test may have
+            // false negatives.
             assertAvailable(PackageManager.FEATURE_USB_ACCESSORY);
         }
     }
diff --git a/tests/app/src/android/app/cts/WallpaperInfoTest.java b/tests/app/src/android/app/cts/WallpaperInfoTest.java
new file mode 100644
index 0000000..1b30902
--- /dev/null
+++ b/tests/app/src/android/app/cts/WallpaperInfoTest.java
@@ -0,0 +1,58 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.app.cts;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+
+import android.app.WallpaperInfo;
+import android.content.Context;
+import android.content.Intent;
+import android.content.pm.PackageManager;
+import android.content.pm.ResolveInfo;
+import android.service.wallpaper.WallpaperService;
+import android.support.test.InstrumentationRegistry;
+import android.support.test.runner.AndroidJUnit4;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import java.util.List;
+
+@RunWith(AndroidJUnit4.class)
+public class WallpaperInfoTest {
+
+    @Test
+    public void test() throws Exception {
+        Context context = InstrumentationRegistry.getTargetContext();
+        Intent intent = new Intent(WallpaperService.SERVICE_INTERFACE);
+        intent.setPackage("android.app.stubs");
+        PackageManager pm = context.getPackageManager();
+        List<ResolveInfo> result = pm.queryIntentServices(intent, PackageManager.GET_META_DATA);
+        assertEquals(1, result.size());
+        ResolveInfo info = result.get(0);
+        WallpaperInfo wallpaperInfo = new WallpaperInfo(context, info);
+        assertEquals("Title", wallpaperInfo.loadLabel(pm));
+        assertEquals("Description", wallpaperInfo.loadDescription(pm));
+        assertEquals("Collection", wallpaperInfo.loadAuthor(pm));
+        assertEquals("Context", wallpaperInfo.loadContextDescription(pm));
+        assertEquals("http://android.com", wallpaperInfo.loadContextUri(pm).toString());
+        assertEquals(true, wallpaperInfo.getShowMetadataInPreview());
+        assertNotNull(wallpaperInfo.loadIcon(pm));
+        assertNotNull(wallpaperInfo.loadThumbnail(pm));
+    }
+}
diff --git a/tests/backup/src/android/backup/cts/BackupQuotaTest.java b/tests/backup/src/android/backup/cts/BackupQuotaTest.java
index 01c368a..0493993 100644
--- a/tests/backup/src/android/backup/cts/BackupQuotaTest.java
+++ b/tests/backup/src/android/backup/cts/BackupQuotaTest.java
@@ -17,6 +17,7 @@
 package android.backup.cts;
 
 import android.app.Instrumentation;
+import android.content.pm.PackageManager;
 import android.os.ParcelFileDescriptor;
 import android.test.InstrumentationTestCase;
 import android.util.Log;
@@ -46,12 +47,19 @@
 
     private static final int SMALL_LOGCAT_DELAY = 1000;
 
+    private boolean isBackupSupported;
     private boolean wasBackupEnabled;
     private String oldTransport;
 
     @Override
     protected void setUp() throws Exception {
         super.setUp();
+        PackageManager packageManager = getInstrumentation().getContext().getPackageManager();
+        isBackupSupported = packageManager != null
+                && packageManager.hasSystemFeature(PackageManager.FEATURE_BACKUP);
+        if (!isBackupSupported) {
+            return;
+        }
         // Enable backup and select local backup transport
         assertTrue("LocalTransport should be available.", hasBackupTransport(LOCAL_TRANSPORT));
         wasBackupEnabled = enableBackup(true);
@@ -61,12 +69,17 @@
     @Override
     protected void tearDown() throws Exception {
         // Return old transport
-        setBackupTransport(oldTransport);
-        enableBackup(wasBackupEnabled);
+        if (isBackupSupported) {
+            setBackupTransport(oldTransport);
+            enableBackup(wasBackupEnabled);
+        }
         super.tearDown();
     }
 
     public void testQuotaExceeded() throws Exception {
+        if (!isBackupSupported) {
+            return;
+        }
         exec("logcat --clear");
         exec("setprop log.tag." + APP_LOG_TAG +" VERBOSE");
         // Launch test app and create file exceeding limit for local transport
diff --git a/tests/camera/AndroidTest.xml b/tests/camera/AndroidTest.xml
index 1358c34..0f53255 100644
--- a/tests/camera/AndroidTest.xml
+++ b/tests/camera/AndroidTest.xml
@@ -21,7 +21,7 @@
     <test class="com.android.tradefed.testtype.AndroidJUnitTest" >
         <option name="package" value="android.camera.cts" />
         <option name="runtime-hint" value="12m7s" />
-        <!-- test-timeout unit is ms, value = 40 min -->
-        <option name="test-timeout" value="2400000" />
+        <!-- test-timeout unit is ms, value = 60 min -->
+        <option name="test-timeout" value="3600000" />
     </test>
 </configuration>
diff --git a/tests/camera/src/android/hardware/camera2/cts/CameraTestUtils.java b/tests/camera/src/android/hardware/camera2/cts/CameraTestUtils.java
index a193c20..97fa6d1 100644
--- a/tests/camera/src/android/hardware/camera2/cts/CameraTestUtils.java
+++ b/tests/camera/src/android/hardware/camera2/cts/CameraTestUtils.java
@@ -1651,7 +1651,7 @@
         }
 
         if (zoomFactor < minEffectiveZoom) {
-            Log.w(TAG, "Requested zoomFactor " + zoomFactor + " > minimal zoomable factor "
+            Log.w(TAG, "Requested zoomFactor " + zoomFactor + " < minimal zoomable factor "
                     + minEffectiveZoom + ". It will be overwritten by " + minEffectiveZoom);
             zoomFactor = minEffectiveZoom;
         }
@@ -1685,6 +1685,40 @@
     }
 
     /**
+     * Get AeAvailableTargetFpsRanges with max fps not exceeding 30
+     *
+     * @param staticInfo camera static metadata
+     * @return AeAvailableTargetFpsRanges with max fps not exceeding 30
+     */
+    public static List<Range<Integer>> getTargetFpsRangesUpTo30(StaticMetadata staticInfo) {
+        Range<Integer>[] fpsRanges = staticInfo.getAeAvailableTargetFpsRangesChecked();
+        ArrayList<Range<Integer>> fpsRangesUpTo30 = new ArrayList<Range<Integer>>();
+        for (Range<Integer> fpsRange : fpsRanges) {
+            if (fpsRange.getUpper() <= 30) {
+                fpsRangesUpTo30.add(fpsRange);
+            }
+        }
+        return fpsRangesUpTo30;
+    }
+
+    /**
+     * Get AeAvailableTargetFpsRanges with max fps greater than 30
+     *
+     * @param staticInfo camera static metadata
+     * @return AeAvailableTargetFpsRanges with max fps greater than 30
+     */
+    public static List<Range<Integer>> getTargetFpsRangesGreaterThan30(StaticMetadata staticInfo) {
+        Range<Integer>[] fpsRanges = staticInfo.getAeAvailableTargetFpsRangesChecked();
+        ArrayList<Range<Integer>> fpsRangesGreaterThan30 = new ArrayList<Range<Integer>>();
+        for (Range<Integer> fpsRange : fpsRanges) {
+            if (fpsRange.getUpper() > 30) {
+                fpsRangesGreaterThan30.add(fpsRange);
+            }
+        }
+        return fpsRangesGreaterThan30;
+    }
+
+    /**
      * Calculate output 3A region from the intersection of input 3A region and cropped region.
      *
      * @param requestRegions The input 3A regions
diff --git a/tests/camera/src/android/hardware/camera2/cts/CaptureRequestTest.java b/tests/camera/src/android/hardware/camera2/cts/CaptureRequestTest.java
index ebda3dd..66756e1 100644
--- a/tests/camera/src/android/hardware/camera2/cts/CaptureRequestTest.java
+++ b/tests/camera/src/android/hardware/camera2/cts/CaptureRequestTest.java
@@ -461,6 +461,9 @@
         }
     }
 
+    /**
+     * Test edge mode control for Fps not exceeding 30.
+     */
     public void testEdgeModeControl() throws Exception {
         for (String id : mCameraIds) {
             try {
@@ -471,7 +474,8 @@
                     continue;
                 }
 
-                edgeModesTestByCamera();
+                List<Range<Integer>> fpsRanges = getTargetFpsRangesUpTo30(mStaticInfo);
+                edgeModesTestByCamera(fpsRanges);
             } finally {
                 closeDevice();
             }
@@ -479,6 +483,28 @@
     }
 
     /**
+     * Test edge mode control for Fps greater than 30.
+     */
+    public void testEdgeModeControlFastFps() throws Exception {
+        for (String id : mCameraIds) {
+            try {
+                openDevice(id);
+                if (!mStaticInfo.isEdgeModeControlSupported()) {
+                    Log.i(TAG, "Camera " + id +
+                            " doesn't support EDGE_MODE controls, skipping test");
+                    continue;
+                }
+
+                List<Range<Integer>> fpsRanges = getTargetFpsRangesGreaterThan30(mStaticInfo);
+                edgeModesTestByCamera(fpsRanges);
+            } finally {
+                closeDevice();
+            }
+        }
+
+    }
+
+    /**
      * Test focus distance control.
      */
     public void testFocusDistanceControl() throws Exception {
@@ -504,6 +530,9 @@
         }
     }
 
+    /**
+     * Test noise reduction mode for fps ranges not exceeding 30
+     */
     public void testNoiseReductionModeControl() throws Exception {
         for (String id : mCameraIds) {
             try {
@@ -514,7 +543,29 @@
                     continue;
                 }
 
-                noiseReductionModeTestByCamera();
+                List<Range<Integer>> fpsRanges = getTargetFpsRangesUpTo30(mStaticInfo);
+                noiseReductionModeTestByCamera(fpsRanges);
+            } finally {
+                closeDevice();
+            }
+        }
+    }
+
+    /**
+     * Test noise reduction mode for fps ranges greater than 30
+     */
+    public void testNoiseReductionModeControlFastFps() throws Exception {
+        for (String id : mCameraIds) {
+            try {
+                openDevice(id);
+                if (!mStaticInfo.isNoiseReductionModeControlSupported()) {
+                    Log.i(TAG, "Camera " + id +
+                            " doesn't support noise reduction mode, skipping test");
+                    continue;
+                }
+
+                List<Range<Integer>> fpsRanges = getTargetFpsRangesGreaterThan30(mStaticInfo);
+                noiseReductionModeTestByCamera(fpsRanges);
             } finally {
                 closeDevice();
             }
@@ -824,7 +875,7 @@
         }
     }
 
-    private void noiseReductionModeTestByCamera() throws Exception {
+    private void noiseReductionModeTestByCamera(List<Range<Integer>> fpsRanges) throws Exception {
         Size maxPrevSize = mOrderedPreviewSizes.get(0);
         CaptureRequest.Builder requestBuilder =
                 mCamera.createCaptureRequest(CameraDevice.TEMPLATE_PREVIEW);
@@ -836,7 +887,7 @@
             // Test that OFF and FAST mode should not slow down the frame rate.
             if (mode == CaptureRequest.NOISE_REDUCTION_MODE_OFF ||
                     mode == CaptureRequest.NOISE_REDUCTION_MODE_FAST) {
-                verifyFpsNotSlowDown(requestBuilder, NUM_FRAMES_VERIFIED);
+                verifyFpsNotSlowDown(requestBuilder, NUM_FRAMES_VERIFIED, fpsRanges);
             }
 
             SimpleCaptureCallback resultListener = new SimpleCaptureCallback();
@@ -1079,9 +1130,9 @@
     }
 
     /**
-     * Verify edge mode control results.
+     * Verify edge mode control results for fpsRanges
      */
-    private void edgeModesTestByCamera() throws Exception {
+    private void edgeModesTestByCamera(List<Range<Integer>> fpsRanges) throws Exception {
         Size maxPrevSize = mOrderedPreviewSizes.get(0);
         int[] edgeModes = mStaticInfo.getAvailableEdgeModesChecked();
         CaptureRequest.Builder requestBuilder =
@@ -1093,7 +1144,7 @@
             // Test that OFF and FAST mode should not slow down the frame rate.
             if (mode == CaptureRequest.EDGE_MODE_OFF ||
                     mode == CaptureRequest.EDGE_MODE_FAST) {
-                verifyFpsNotSlowDown(requestBuilder, NUM_FRAMES_VERIFIED);
+                verifyFpsNotSlowDown(requestBuilder, NUM_FRAMES_VERIFIED, fpsRanges);
             }
 
             SimpleCaptureCallback resultListener = new SimpleCaptureCallback();
@@ -2075,16 +2126,35 @@
     private void digitalZoomTestByCamera(Size previewSize) throws Exception {
         final int ZOOM_STEPS = 15;
         final PointF[] TEST_ZOOM_CENTERS;
+        final float maxZoom = mStaticInfo.getAvailableMaxDigitalZoomChecked();
+        final float ZOOM_ERROR_MARGIN = 0.01f;
+        if (Math.abs(maxZoom - 1.0f) < ZOOM_ERROR_MARGIN) {
+            // It doesn't make much sense to test the zoom if the device effectively supports
+            // no zoom.
+            return;
+        }
 
         final int croppingType = mStaticInfo.getScalerCroppingTypeChecked();
-        if (croppingType ==
-                CameraCharacteristics.SCALER_CROPPING_TYPE_FREEFORM) {
+        if (croppingType == CameraCharacteristics.SCALER_CROPPING_TYPE_FREEFORM) {
+            // Set the four corners in a way that the minimally allowed zoom factor is 2x.
+            float normalizedLeft = 0.25f;
+            float normalizedTop = 0.25f;
+            float normalizedRight = 0.75f;
+            float normalizedBottom = 0.75f;
+            // If the max supported zoom is too small, make sure we at least test the max
+            // Zoom is tested for the four corners.
+            if (maxZoom < 2.0f) {
+                normalizedLeft = 0.5f / maxZoom;
+                normalizedTop = 0.5f / maxZoom;
+                normalizedRight = 1.0f - normalizedLeft;
+                normalizedBottom = 1.0f - normalizedTop;
+            }
             TEST_ZOOM_CENTERS = new PointF[] {
                 new PointF(0.5f, 0.5f),   // Center point
-                new PointF(0.25f, 0.25f), // top left corner zoom, minimal zoom: 2x
-                new PointF(0.75f, 0.25f), // top right corner zoom, minimal zoom: 2x
-                new PointF(0.25f, 0.75f), // bottom left corner zoom, minimal zoom: 2x
-                new PointF(0.75f, 0.75f), // bottom right corner zoom, minimal zoom: 2x
+                new PointF(normalizedLeft, normalizedTop),     // top left corner zoom
+                new PointF(normalizedRight, normalizedTop),    // top right corner zoom
+                new PointF(normalizedLeft, normalizedBottom),  // bottom left corner zoom
+                new PointF(normalizedRight, normalizedBottom), // bottom right corner zoom
             };
 
             if (VERBOSE) {
@@ -2101,7 +2171,6 @@
             }
         }
 
-        final float maxZoom = mStaticInfo.getAvailableMaxDigitalZoomChecked();
         final Rect activeArraySize = mStaticInfo.getActiveArraySizeChecked();
         Rect[] cropRegions = new Rect[ZOOM_STEPS];
         MeteringRectangle[][] expectRegions = new MeteringRectangle[ZOOM_STEPS][];
@@ -2539,9 +2608,10 @@
      *            these controls must be set to some values such that the frame
      *            rate is not slow down.
      * @param numFramesVerified The number of frames to be verified
+     * @param fpsRanges The fps ranges to be verified
      */
     private void verifyFpsNotSlowDown(CaptureRequest.Builder requestBuilder,
-            int numFramesVerified)  throws Exception {
+            int numFramesVerified, List<Range<Integer>> fpsRanges )  throws Exception {
         boolean frameDurationAvailable = true;
         // Allow a few frames for AE to settle on target FPS range
         final int NUM_FRAME_TO_SKIP = 6;
@@ -2552,13 +2622,12 @@
             frameDurationErrorMargin = 0.015f;
         }
 
-        Range<Integer>[] fpsRanges = getDescendingTargetFpsRanges(mStaticInfo);
         boolean antiBandingOffIsSupported = mStaticInfo.isAntiBandingOffModeSupported();
         Range<Integer> fpsRange;
         SimpleCaptureCallback resultListener;
 
-        for (int i = 0; i < fpsRanges.length; i += 1) {
-            fpsRange = fpsRanges[i];
+        for (int i = 0; i < fpsRanges.size(); i += 1) {
+            fpsRange = fpsRanges.get(i);
             Size previewSz = getMaxPreviewSizeForFpsRange(fpsRange);
             // If unable to find a preview size, then log the failure, and skip this run.
             if (previewSz == null) {
@@ -2622,7 +2691,7 @@
             }
         }
 
-        mSession.stopRepeating();
+        stopPreview();
     }
 
     /**
diff --git a/tests/camera/src/android/hardware/camera2/cts/DngCreatorTest.java b/tests/camera/src/android/hardware/camera2/cts/DngCreatorTest.java
index 6ab55b0..8f32d52 100644
--- a/tests/camera/src/android/hardware/camera2/cts/DngCreatorTest.java
+++ b/tests/camera/src/android/hardware/camera2/cts/DngCreatorTest.java
@@ -40,6 +40,7 @@
 import android.media.Image;
 import android.media.ImageReader;
 import android.os.ConditionVariable;
+import android.os.SystemClock;
 import android.util.Log;
 import android.util.Pair;
 import android.util.Size;
@@ -54,8 +55,10 @@
 import java.util.Arrays;
 import java.util.Calendar;
 import java.util.Collections;
+import java.util.Date;
 import java.util.List;
 import java.util.TimeZone;
+import java.text.SimpleDateFormat;
 
 import static android.hardware.camera2.cts.helpers.AssertHelpers.*;
 
@@ -243,10 +246,19 @@
                         previewListener));
                 captureListeners.add(previewListener);
 
+                Date beforeCaptureDate = new Date();
                 Pair<List<Image>, CaptureResult> resultPair = captureSingleRawShot(activeArraySize,
                         captureReaders, /*waitForAe*/false, captureListeners);
+                Date afterCaptureDate = new Date();
                 CameraCharacteristics characteristics = mStaticInfo.getCharacteristics();
 
+                if (VERBOSE) {
+                    Log.v(TAG, "Sensor timestamp (ms): " +
+                            resultPair.second.get(CaptureResult.SENSOR_TIMESTAMP) / 1000000);
+                    Log.v(TAG, "SystemClock.elapsedRealtimeNanos (ms): " +
+                            SystemClock.elapsedRealtimeNanos() / 1000000);
+                    Log.v(TAG, "SystemClock.uptimeMillis(): " + SystemClock.uptimeMillis());
+                }
                 // Test simple writeImage, no header checks
                 DngCreator dngCreator = new DngCreator(characteristics, resultPair.second);
                 Location l = new Location("test");
@@ -264,7 +276,7 @@
 
                 String filePath = DEBUG_FILE_NAME_BASE + "/camera_thumb_" + deviceId + "_" +
                         DEBUG_DNG_FILE;
-                // Write out captured DNG file for the first camera device if setprop is enabled
+                // Write out captured DNG file for the first camera device
                 fileStream = new FileOutputStream(filePath);
                 fileStream.write(outputStream.toByteArray());
                 fileStream.flush();
@@ -292,6 +304,30 @@
                         exifInterface.getAttributeInt(ExifInterface.TAG_ORIENTATION,
                                 ExifInterface.ORIENTATION_UNDEFINED));
 
+                // Verify the date/time
+                final SimpleDateFormat dngDateTimeStampFormat =
+                        new SimpleDateFormat("yyyy:MM:dd HH:mm:ss");
+                dngDateTimeStampFormat.setLenient(false);
+
+                String dateTimeString =
+                        exifInterface.getAttribute(ExifInterface.TAG_DATETIME);
+                assertTrue(dateTimeString != null);
+
+                Date dateTime = dngDateTimeStampFormat.parse(dateTimeString);
+                long captureTimeMs = dateTime.getTime();
+
+                Log.i(TAG, "DNG DateTime tag: " + dateTimeString);
+                Log.i(TAG, "Before capture time: " + beforeCaptureDate.getTime());
+                Log.i(TAG, "Capture time: " + captureTimeMs);
+                Log.i(TAG, "After capture time: " + afterCaptureDate.getTime());
+
+                // Offset beforeCaptureTime by 1 second to account for rounding down of
+                // DNG tag
+                long beforeCaptureTimeMs = beforeCaptureDate.getTime() - 1000;
+                long afterCaptureTimeMs = afterCaptureDate.getTime();
+                assertTrue(captureTimeMs >= beforeCaptureTimeMs);
+                assertTrue(captureTimeMs <= afterCaptureTimeMs);
+
                 if (!VERBOSE) {
                     // Delete the captured DNG file.
                     File dngFile = new File(filePath);
diff --git a/tests/camera/src/android/hardware/camera2/cts/ExtendedCameraCharacteristicsTest.java b/tests/camera/src/android/hardware/camera2/cts/ExtendedCameraCharacteristicsTest.java
index 2db28a0..cd42c4d 100644
--- a/tests/camera/src/android/hardware/camera2/cts/ExtendedCameraCharacteristicsTest.java
+++ b/tests/camera/src/android/hardware/camera2/cts/ExtendedCameraCharacteristicsTest.java
@@ -1200,8 +1200,9 @@
                 // should be advertise by the camera.
                 for (int quality = CamcorderProfile.QUALITY_HIGH_SPEED_480P;
                         quality <= CamcorderProfile.QUALITY_HIGH_SPEED_2160P; quality++) {
-                    if (CamcorderProfile.hasProfile(quality)) {
-                        CamcorderProfile profile = CamcorderProfile.get(quality);
+                    int cameraId = Integer.valueOf(mIds[counter]);
+                    if (CamcorderProfile.hasProfile(cameraId, quality)) {
+                        CamcorderProfile profile = CamcorderProfile.get(cameraId, quality);
                         Size camcorderProfileSize =
                                 new Size(profile.videoFrameWidth, profile.videoFrameHeight);
                         assertTrue("CamcorderPrfile size " + camcorderProfileSize +
diff --git a/tests/camera/src/android/hardware/camera2/cts/RecordingTest.java b/tests/camera/src/android/hardware/camera2/cts/RecordingTest.java
index d101036..d466662 100644
--- a/tests/camera/src/android/hardware/camera2/cts/RecordingTest.java
+++ b/tests/camera/src/android/hardware/camera2/cts/RecordingTest.java
@@ -1282,14 +1282,15 @@
                                          duration, expectedDurationMs));
             }
 
-            // TODO: Don't skip this for video snapshot
-            if (!mStaticInfo.isHardwareLevelLegacy()) {
-                assertTrue(String.format(
-                        "Camera %s: Video duration doesn't match: recorded %fms, expected %fms.",
-                        mCamera.getId(), duration, expectedDurationMs),
-                        Math.abs(duration - expectedDurationMs) <
-                        DURATION_MARGIN * expectedDurationMs);
-            }
+            // Do rest of validation only for better-than-LEGACY devices
+            if (mStaticInfo.isHardwareLevelLegacy()) return;
+
+            // TODO: Don't skip this one for video snapshot on LEGACY
+            assertTrue(String.format(
+                    "Camera %s: Video duration doesn't match: recorded %fms, expected %fms.",
+                    mCamera.getId(), duration, expectedDurationMs),
+                    Math.abs(duration - expectedDurationMs) <
+                    DURATION_MARGIN * expectedDurationMs);
 
             // Check for framedrop
             long lastSampleUs = 0;
diff --git a/tests/camera/src/android/hardware/camera2/cts/SurfaceViewPreviewTest.java b/tests/camera/src/android/hardware/camera2/cts/SurfaceViewPreviewTest.java
index 73845dc..8d3c5d4 100644
--- a/tests/camera/src/android/hardware/camera2/cts/SurfaceViewPreviewTest.java
+++ b/tests/camera/src/android/hardware/camera2/cts/SurfaceViewPreviewTest.java
@@ -461,7 +461,13 @@
 
         for (int i = 0; i < fpsRanges.length; i += 1) {
             fpsRange = fpsRanges[i];
-            maxPreviewSz = getMaxPreviewSizeForFpsRange(fpsRange);
+            if (mStaticInfo.isHardwareLevelLegacy()) {
+                // Legacy devices don't report minimum frame duration for preview sizes. The FPS
+                // range should be valid for any supported preview size.
+                maxPreviewSz = mOrderedPreviewSizes.get(0);
+            } else {
+                maxPreviewSz = getMaxPreviewSizeForFpsRange(fpsRange);
+            }
 
             requestBuilder.set(CaptureRequest.CONTROL_AE_TARGET_FPS_RANGE, fpsRange);
             // Turn off auto antibanding to avoid exposure time and frame duration interference
diff --git a/tests/camera/src/android/hardware/camera2/cts/testcases/Camera2SurfaceViewTestCase.java b/tests/camera/src/android/hardware/camera2/cts/testcases/Camera2SurfaceViewTestCase.java
index 8d141c4..a95f4f3 100644
--- a/tests/camera/src/android/hardware/camera2/cts/testcases/Camera2SurfaceViewTestCase.java
+++ b/tests/camera/src/android/hardware/camera2/cts/testcases/Camera2SurfaceViewTestCase.java
@@ -222,9 +222,11 @@
      * Does _not_ wait for the device to go idle
      */
     protected void stopPreview() throws Exception {
-        if (VERBOSE) Log.v(TAG, "Stopping preview");
         // Stop repeat, wait for captures to complete, and disconnect from surfaces
-        mSession.close();
+        if (mSession != null) {
+            if (VERBOSE) Log.v(TAG, "Stopping preview");
+            mSession.close();
+        }
     }
 
     /**
@@ -232,11 +234,13 @@
      * resulting in an idle device.
      */
     protected void stopPreviewAndDrain() throws Exception {
-        if (VERBOSE) Log.v(TAG, "Stopping preview and waiting for idle");
         // Stop repeat, wait for captures to complete, and disconnect from surfaces
-        mSession.close();
-        mSessionListener.getStateWaiter().waitForState(BlockingSessionCallback.SESSION_CLOSED,
-                /*timeoutMs*/WAIT_FOR_RESULT_TIMEOUT_MS);
+        if (mSession != null) {
+            if (VERBOSE) Log.v(TAG, "Stopping preview and waiting for idle");
+            mSession.close();
+            mSessionListener.getStateWaiter().waitForState(BlockingSessionCallback.SESSION_CLOSED,
+                    /*timeoutMs*/WAIT_FOR_RESULT_TIMEOUT_MS);
+        }
     }
 
     /**
diff --git a/tests/core/runner/src/com/android/cts/runner/CtsTestRunListener.java b/tests/core/runner/src/com/android/cts/runner/CtsTestRunListener.java
index 57dc7c6..1f9a939 100644
--- a/tests/core/runner/src/com/android/cts/runner/CtsTestRunListener.java
+++ b/tests/core/runner/src/com/android/cts/runner/CtsTestRunListener.java
@@ -16,6 +16,7 @@
 
 package com.android.cts.runner;
 
+import android.app.ActivityManager;
 import android.app.Instrumentation;
 import android.app.KeyguardManager;
 import android.content.Context;
@@ -219,6 +220,13 @@
             mProperties.setProperty("android.cts.device.multicast",
                     Boolean.toString(pm.hasSystemFeature(PackageManager.FEATURE_WIFI)));
             mDefaultIs24Hour = getDateFormatIs24Hour();
+
+            // There are tests in libcore that should be disabled for low ram devices. They can't
+            // access ActivityManager to call isLowRamDevice, but can read system properties.
+            ActivityManager activityManager =
+                    (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);
+            mProperties.setProperty("android.cts.device.lowram",
+                    Boolean.toString(activityManager.isLowRamDevice()));
         }
 
         void reset() {
diff --git a/tests/deviceadmin/uninstalltest/src/android/devicepolicy/cts/uiautomatertest/DeviceAdminUninstallTest.java b/tests/deviceadmin/uninstalltest/src/android/devicepolicy/cts/uiautomatertest/DeviceAdminUninstallTest.java
index a8e7cc1..d4f04de 100644
--- a/tests/deviceadmin/uninstalltest/src/android/devicepolicy/cts/uiautomatertest/DeviceAdminUninstallTest.java
+++ b/tests/deviceadmin/uninstalltest/src/android/devicepolicy/cts/uiautomatertest/DeviceAdminUninstallTest.java
@@ -15,6 +15,9 @@
  */
 package android.devicepolicy.cts.uiautomatertest;
 
+import static android.content.Intent.CATEGORY_DEFAULT;
+import static android.provider.Settings.ACTION_SETTINGS;
+
 import android.app.Activity;
 import android.app.Instrumentation;
 import android.app.admin.DevicePolicyManager;
@@ -26,6 +29,19 @@
 import android.content.pm.PackageManager.NameNotFoundException;
 import android.net.Uri;
 import android.provider.Settings;
+import android.support.test.InstrumentationRegistry;
+import android.support.test.filters.LargeTest;
+import android.support.test.runner.AndroidJUnit4;
+import android.support.test.uiautomator.By;
+import android.support.test.uiautomator.BySelector;
+import android.support.test.uiautomator.UiDevice;
+import android.support.test.uiautomator.UiObject;
+import android.support.test.uiautomator.UiObject2;
+import android.support.test.uiautomator.UiObjectNotFoundException;
+import android.support.test.uiautomator.UiScrollable;
+import android.support.test.uiautomator.UiSelector;
+import android.support.test.uiautomator.Until;
+import android.util.Log;
 import android.widget.ScrollView;
 
 import org.junit.After;
@@ -38,18 +54,6 @@
 import java.io.StringWriter;
 import java.util.List;
 import java.util.regex.Pattern;
-import android.support.test.InstrumentationRegistry;
-import android.support.test.runner.AndroidJUnit4;
-import android.support.test.filters.LargeTest;
-import android.support.test.uiautomator.By;
-import android.support.test.uiautomator.BySelector;
-import android.support.test.uiautomator.UiDevice;
-import android.support.test.uiautomator.UiObject;
-import android.support.test.uiautomator.UiObjectNotFoundException;
-import android.support.test.uiautomator.UiScrollable;
-import android.support.test.uiautomator.UiSelector;
-import android.support.test.uiautomator.Until;
-import android.util.Log;
 
 @RunWith(AndroidJUnit4.class)
 @LargeTest
@@ -60,14 +64,6 @@
     private static final String URI_PACKAGE_PREFIX = "package:";
     private static final String UNINSTALL_BUTTON_TEXT_REGEX = "(?i)uninstall";
 
-    private static final UiSelector DEACTIVATE_AND_UNINSTALL_BUTTON_SELECTOR = new UiSelector()
-            .resourceId("com.android.settings:id/action_button");
-    // Changing the below two selectors to match the button based on text due to b/29960172
-    private static final UiSelector UNINSTALL_BUTTON_SELECTOR = new UiSelector()
-            .clickable(true).textMatches(UNINSTALL_BUTTON_TEXT_REGEX);
-    private static final BySelector UNINSTALL_BUTTON_BYSELECTOR = By
-            .clickable(true).text(Pattern.compile(UNINSTALL_BUTTON_TEXT_REGEX));
-
     private static final UiSelector OK_BUTTON_SELECTOR = new UiSelector()
             .resourceId("android:id/button1");
     private static final UiSelector SCROLL_VIEW_SELECTOR =
@@ -83,7 +79,10 @@
     private DevicePolicyManager mDpm;
     private PackageManager mPm;
     private Activity mActivity;
+    private UiSelector mDeactivateAndUninstallButtonSelector;
+    private BySelector mUninstallButtonSelector;
     private boolean mHasFeature;
+    private boolean mIsWatch;
 
     @Before
     public void setUp() throws Exception {
@@ -97,6 +96,17 @@
         mInstrumentation = InstrumentationRegistry.getInstrumentation();
         mUiDevice = UiDevice.getInstance(mInstrumentation);
         mDpm = mContext.getSystemService(DevicePolicyManager.class);
+        mIsWatch = mPm.hasSystemFeature(PackageManager.FEATURE_WATCH);
+        if (mIsWatch) {
+            mUninstallButtonSelector = By.clickable(true).hasDescendant(
+                    By.text(Pattern.compile(UNINSTALL_BUTTON_TEXT_REGEX)));
+        } else {
+            mUninstallButtonSelector = By.clickable(true).text(
+                    Pattern.compile(UNINSTALL_BUTTON_TEXT_REGEX));
+        }
+        mDeactivateAndUninstallButtonSelector = new UiSelector().resourceId(
+                getDefaultSettingsPackageName() + ":id/action_button");
+
         startTestActivity();
     }
 
@@ -158,15 +168,21 @@
     private void automateUninstallThroughUi() {
         String errorMessage = "No exception in UI Automation";
 
-        UiObject uninstallButton = mUiDevice.findObject(UNINSTALL_BUTTON_SELECTOR);
         UiScrollable scrollable = new UiScrollable(SCROLL_VIEW_SELECTOR);
-        UiObject deactivateButton = mUiDevice.findObject(DEACTIVATE_AND_UNINSTALL_BUTTON_SELECTOR);
+        UiObject deactivateButton = mUiDevice.findObject(mDeactivateAndUninstallButtonSelector);
         UiObject okButton = mUiDevice.findObject(OK_BUTTON_SELECTOR);
 
-        mUiDevice.wait(Until.hasObject(UNINSTALL_BUTTON_BYSELECTOR), WAIT_FOR_ACTIVITY_TIMEOUT);
         try {
-            uninstallButton.clickAndWaitForNewWindow();
-            scrollable.scrollIntoView(DEACTIVATE_AND_UNINSTALL_BUTTON_SELECTOR);
+            UiObject2 uninstallButton = mUiDevice.wait(
+                    Until.findObject(mUninstallButtonSelector), WAIT_FOR_ACTIVITY_TIMEOUT);
+            uninstallButton.clickAndWait(Until.newWindow(), WAIT_FOR_ACTIVITY_TIMEOUT);
+
+            /** Watch specific: Extra confirm button click */
+            if (mIsWatch) {
+                okButton.clickAndWaitForNewWindow();
+            }
+
+            scrollable.scrollIntoView(mDeactivateAndUninstallButtonSelector);
             deactivateButton.clickAndWaitForNewWindow();
             waitTillNoActiveAdmin();
             okButton.clickAndWaitForNewWindow();
@@ -185,6 +201,12 @@
         return errorWriter.toString();
     }
 
+    private String getDefaultSettingsPackageName() {
+        Intent intent = new Intent(ACTION_SETTINGS).addCategory(CATEGORY_DEFAULT);
+        String packageName = intent.resolveActivity(mPm).getPackageName();
+        return packageName;
+    }
+
     @Test
     public void uninstallPackageWithActiveAdmin() {
         if (!mHasFeature) {
diff --git a/tests/filesystem/src/android/filesystem/cts/AlmostFullTest.java b/tests/filesystem/src/android/filesystem/cts/AlmostFullTest.java
index 11b150e..0fbc872 100644
--- a/tests/filesystem/src/android/filesystem/cts/AlmostFullTest.java
+++ b/tests/filesystem/src/android/filesystem/cts/AlmostFullTest.java
@@ -63,7 +63,9 @@
                 Log.i(TAG, "free disk " + freeDisk + " too small, needs " + FREE_SPACE_FINAL);
                 return;
             }
-            final long MAX_FILE_SIZE_TO_FILL = 1024L * 1024L * 1024L;
+            // Ensure MAX_SIZE_TO_FILL is an integral multiple of FileUtil.BUFFER_SIZE to avoid
+            // rounding errors caused by FileUtil.createNewFilledFile. See b/63535343.
+            final long MAX_FILE_SIZE_TO_FILL = FileUtil.BUFFER_SIZE * 100L;
             long filled = 0;
             while (filled < diskToFill) {
                 long toFill = diskToFill - filled;
diff --git a/tests/filesystem/src/android/filesystem/cts/FileUtil.java b/tests/filesystem/src/android/filesystem/cts/FileUtil.java
index fc8eee0..8149105 100755
--- a/tests/filesystem/src/android/filesystem/cts/FileUtil.java
+++ b/tests/filesystem/src/android/filesystem/cts/FileUtil.java
@@ -41,6 +41,8 @@
     private static final String TAG = "FileUtil";
     private static final Random mRandom = new Random(0);
     private static long mFileId = 0;
+
+    public static final int BUFFER_SIZE = 10 * 1024 * 1024;
     /**
      * create array with different data per each call
      *
@@ -140,7 +142,6 @@
      */
     public static File createNewFilledFile(Context context, String dirName, long length)
             throws IOException {
-        final int BUFFER_SIZE = 10 * 1024 * 1024;
         File file = createNewFile(context, dirName);
         FileOutputStream out = new FileOutputStream(file);
         byte[] data = generateRandomData(BUFFER_SIZE);
diff --git a/tests/filesystem/src/android/filesystem/cts/RandomRWTest.java b/tests/filesystem/src/android/filesystem/cts/RandomRWTest.java
index f30c7a3..7b97f8f 100644
--- a/tests/filesystem/src/android/filesystem/cts/RandomRWTest.java
+++ b/tests/filesystem/src/android/filesystem/cts/RandomRWTest.java
@@ -17,7 +17,8 @@
 package android.filesystem.cts;
 
 import android.cts.util.CtsAndroidTestCase;
-
+import android.os.Environment;
+import com.android.compatibility.common.util.CddTest;
 import com.android.compatibility.common.util.DeviceReportLog;
 
 public class RandomRWTest extends CtsAndroidTestCase {
@@ -32,6 +33,7 @@
         super.tearDown();
     }
 
+    @CddTest(requirement="8.2")
     public void testRandomRead() throws Exception {
         final int READ_BUFFER_SIZE = 4 * 1024;
         final long fileSize = FileUtil.getFileSizeExceedingMemory(getContext(), READ_BUFFER_SIZE);
@@ -46,13 +48,20 @@
     }
 
     // It is taking too long in some device, and thus cannot run multiple times
+    @CddTest(requirement="8.2")
     public void testRandomUpdate() throws Exception {
         final int WRITE_BUFFER_SIZE = 4 * 1024;
-        final long fileSize = 256 * 1024 * 1024;
+        final long usableSpace = Environment.getDataDirectory().getUsableSpace();
+        long fileSize = 256 * 1024 * 1024;
+        while (usableSpace < fileSize) {
+            fileSize = fileSize / 2;
+        }
         String streamName = "test_random_update";
         DeviceReportLog report = new DeviceReportLog(REPORT_LOG_NAME, streamName);
-        FileUtil.doRandomWriteTest(getContext(), DIR_RANDOM_WR, report, fileSize,
+        if (fileSize > FileUtil.BUFFER_SIZE) {
+            FileUtil.doRandomWriteTest(getContext(), DIR_RANDOM_WR, report, fileSize,
                 WRITE_BUFFER_SIZE);
+        }
         report.submit(getInstrumentation());
     }
 }
diff --git a/tests/filesystem/src/android/filesystem/cts/SequentialRWTest.java b/tests/filesystem/src/android/filesystem/cts/SequentialRWTest.java
index fb00bd8..5c06198 100644
--- a/tests/filesystem/src/android/filesystem/cts/SequentialRWTest.java
+++ b/tests/filesystem/src/android/filesystem/cts/SequentialRWTest.java
@@ -25,6 +25,8 @@
 import com.android.compatibility.common.util.ResultUnit;
 import com.android.compatibility.common.util.Stat;
 
+import com.android.compatibility.common.util.CddTest;
+
 import java.io.File;
 import java.io.FileInputStream;
 import java.io.IOException;
@@ -44,6 +46,7 @@
         super.tearDown();
     }
 
+    @CddTest(requirement="8.2")
     public void testSingleSequentialWrite() throws Exception {
         final long fileSize = FileUtil.getFileSizeExceedingMemory(getContext(), BUFFER_SIZE);
         if (fileSize == 0) { // not enough space, give up
@@ -85,6 +88,7 @@
                 NUMBER_REPETITION, REPORT_LOG_NAME, streamName);
     }
 
+    @CddTest(requirement="8.2")
     public void testSingleSequentialRead() throws Exception {
         final long fileSize = FileUtil.getFileSizeExceedingMemory(getContext(), BUFFER_SIZE);
         if (fileSize == 0) { // not enough space, give up
diff --git a/tests/signature/src/android/signature/cts/JDiffClassDescription.java b/tests/signature/src/android/signature/cts/JDiffClassDescription.java
index 2e13650..92f56bd 100644
--- a/tests/signature/src/android/signature/cts/JDiffClassDescription.java
+++ b/tests/signature/src/android/signature/cts/JDiffClassDescription.java
@@ -1213,7 +1213,9 @@
     private static String scrubJdiffParamType(String paramType) {
         // <? extends java.lang.Object and <?> are the same, so
         // canonicalize them to one form.
-        return paramType.replace("<? extends java.lang.Object>", "<?>");
+        return paramType
+            .replace("? extends java.lang.Object", "?")
+            .replace("? super java.lang.Object", "? super ?");
     }
 
     /**
diff --git a/tests/tests/content/src/android/content/cts/IntentTest.java b/tests/tests/content/src/android/content/cts/IntentTest.java
index 65da548..dbbbe15 100644
--- a/tests/tests/content/src/android/content/cts/IntentTest.java
+++ b/tests/tests/content/src/android/content/cts/IntentTest.java
@@ -38,6 +38,8 @@
 import android.util.AttributeSet;
 import android.util.Xml;
 
+import com.android.content.cts.DummyParcelable;
+
 import java.io.IOException;
 import java.io.Serializable;
 import java.net.URISyntaxException;
@@ -1750,6 +1752,49 @@
         assertEquals("foo/bar", Intent.normalizeMimeType("   foo/bar    "));
     }
 
+    public void testRemoveUnsafeExtras() {
+        final Intent intent = new Intent();
+        final DummyParcelable dummyParcelable = new DummyParcelable();
+        intent.removeUnsafeExtras();
+        assertNull(intent.getExtras());
+
+        // Check that removeUnsafeExtras keeps the same bundle if no changes are made.
+        Bundle origExtras = new Bundle();
+        origExtras.putString("foo", "bar");
+        intent.replaceExtras(origExtras);
+        intent.removeUnsafeExtras();
+        Bundle newExtras = intent.getExtras();
+        assertEquals(1, newExtras.size());
+        assertEquals("bar", newExtras.get("foo"));
+
+        // Check that removeUnsafeExtras will strip non-framework parcelables without modifying
+        // the original extras bundle.
+        origExtras.putParcelable("baddy", dummyParcelable);
+        intent.replaceExtras(origExtras);
+        intent.removeUnsafeExtras();
+        newExtras = intent.getExtras();
+        assertEquals(1, newExtras.size());
+        assertEquals("bar", newExtras.get("foo"));
+        assertEquals(2, origExtras.size());
+        assertEquals("bar", origExtras.get("foo"));
+        assertSame(dummyParcelable, origExtras.get("baddy"));
+
+        // Check that nested bad values will be stripped.
+        Bundle origSubExtras = new Bundle();
+        origSubExtras.putParcelable("baddy", dummyParcelable);
+        origExtras.putBundle("baddy", origSubExtras);
+        intent.replaceExtras(origExtras);
+        intent.removeUnsafeExtras();
+        newExtras = intent.getExtras();
+        assertEquals(2, newExtras.size());
+        assertEquals("bar", newExtras.get("foo"));
+        Bundle newSubExtras = newExtras.getBundle("baddy");
+        assertNotSame(origSubExtras, newSubExtras);
+        assertEquals(0, newSubExtras.size());
+        assertEquals(1, origSubExtras.size());
+        assertSame(dummyParcelable, origSubExtras.get("baddy"));
+    }
+
     private static class TestSerializable implements Serializable {
         static final long serialVersionUID = 1l;
         public String Name;
diff --git a/tests/tests/content/src/com/android/content/cts/DummyParcelable.java b/tests/tests/content/src/com/android/content/cts/DummyParcelable.java
new file mode 100644
index 0000000..5eb8418
--- /dev/null
+++ b/tests/tests/content/src/com/android/content/cts/DummyParcelable.java
@@ -0,0 +1,42 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.content.cts;
+
+import android.os.Parcel;
+import android.os.Parcelable;
+
+public class DummyParcelable implements Parcelable {
+    @Override
+    public int describeContents() {
+        return 0;
+    }
+
+    @Override
+    public void writeToParcel(Parcel dest, int flags) {
+    }
+
+    public static final Parcelable.Creator<DummyParcelable> CREATOR
+            = new Parcelable.Creator<DummyParcelable>() {
+        public DummyParcelable createFromParcel(Parcel in) {
+            return new DummyParcelable();
+        }
+
+        public DummyParcelable[] newArray(int size) {
+            return new DummyParcelable[size];
+        }
+    };
+}
diff --git a/tests/tests/dpi/src/android/dpi/cts/ConfigurationScreenLayoutTest.java b/tests/tests/dpi/src/android/dpi/cts/ConfigurationScreenLayoutTest.java
index 45418cf..3015b07 100644
--- a/tests/tests/dpi/src/android/dpi/cts/ConfigurationScreenLayoutTest.java
+++ b/tests/tests/dpi/src/android/dpi/cts/ConfigurationScreenLayoutTest.java
@@ -49,6 +49,11 @@
         // Check that all four orientations report the same configuration value.
         for (int i = 0; i < ORIENTATIONS.length; i++) {
             Activity activity = startOrientationActivity(ORIENTATIONS[i]);
+            if (activity.isInMultiWindowMode()) {
+                // activity.setRequestedOrientation has no effect in multiwindow mode.
+                tearDown();
+                return;
+            }
             Configuration mConfig = activity.getResources().getConfiguration();
             int actualSize = mConfig.screenLayout & Configuration.SCREENLAYOUT_SIZE_MASK;
             int actualLong = mConfig.screenLayout & Configuration.SCREENLAYOUT_LONG_MASK;
diff --git a/tests/tests/graphics/Android.mk b/tests/tests/graphics/Android.mk
index 7e26e07..d4d0d33 100644
--- a/tests/tests/graphics/Android.mk
+++ b/tests/tests/graphics/Android.mk
@@ -32,8 +32,6 @@
 # Tag this module as a cts test artifact
 LOCAL_COMPATIBILITY_SUITE := cts
 
-LOCAL_SDK_VERSION := current
-
 include $(BUILD_CTS_PACKAGE)
 
 include $(call all-makefiles-under,$(LOCAL_PATH))
diff --git a/tests/tests/graphics/res/drawable-nodpi/bitmap_shader_am_density_golden_160.png b/tests/tests/graphics/res/drawable-nodpi/bitmap_shader_am_density_golden_160.png
new file mode 100644
index 0000000..2e77270
--- /dev/null
+++ b/tests/tests/graphics/res/drawable-nodpi/bitmap_shader_am_density_golden_160.png
Binary files differ
diff --git a/tests/tests/graphics/res/drawable-nodpi/bitmap_shader_am_density_golden_320.png b/tests/tests/graphics/res/drawable-nodpi/bitmap_shader_am_density_golden_320.png
new file mode 100644
index 0000000..5a5c3d2
--- /dev/null
+++ b/tests/tests/graphics/res/drawable-nodpi/bitmap_shader_am_density_golden_320.png
Binary files differ
diff --git a/tests/tests/graphics/res/drawable-nodpi/bitmap_shader_am_density_golden_80.png b/tests/tests/graphics/res/drawable-nodpi/bitmap_shader_am_density_golden_80.png
new file mode 100644
index 0000000..611b27b
--- /dev/null
+++ b/tests/tests/graphics/res/drawable-nodpi/bitmap_shader_am_density_golden_80.png
Binary files differ
diff --git a/tests/tests/graphics/res/drawable-nodpi/bitmap_shader_density_golden_160.png b/tests/tests/graphics/res/drawable-nodpi/bitmap_shader_density_golden_160.png
new file mode 100644
index 0000000..2e77270
--- /dev/null
+++ b/tests/tests/graphics/res/drawable-nodpi/bitmap_shader_density_golden_160.png
Binary files differ
diff --git a/tests/tests/graphics/res/drawable-nodpi/bitmap_shader_density_golden_320.png b/tests/tests/graphics/res/drawable-nodpi/bitmap_shader_density_golden_320.png
new file mode 100644
index 0000000..e8beaa5
--- /dev/null
+++ b/tests/tests/graphics/res/drawable-nodpi/bitmap_shader_density_golden_320.png
Binary files differ
diff --git a/tests/tests/graphics/res/drawable-nodpi/bitmap_shader_density_golden_80.png b/tests/tests/graphics/res/drawable-nodpi/bitmap_shader_density_golden_80.png
new file mode 100644
index 0000000..b869ed7
--- /dev/null
+++ b/tests/tests/graphics/res/drawable-nodpi/bitmap_shader_density_golden_80.png
Binary files differ
diff --git a/tests/tests/graphics/res/drawable/bitmap_shader_am_density.xml b/tests/tests/graphics/res/drawable/bitmap_shader_am_density.xml
new file mode 100644
index 0000000..dfecfbb
--- /dev/null
+++ b/tests/tests/graphics/res/drawable/bitmap_shader_am_density.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+     Copyright (C) 2016 The Android Open Source Project
+    
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+    
+          http://www.apache.org/licenses/LICENSE-2.0
+    
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+
+<bitmap xmlns:android="http://schemas.android.com/apk/res/android"
+        android:src="@drawable/bitmap_shader_density_internal"
+        android:tileModeX="repeat"
+        android:tileModeY="clamp"
+        android:autoMirrored="true" />
diff --git a/tests/tests/graphics/res/drawable/bitmap_shader_am_density_internal.png b/tests/tests/graphics/res/drawable/bitmap_shader_am_density_internal.png
new file mode 100644
index 0000000..b6d4d89
--- /dev/null
+++ b/tests/tests/graphics/res/drawable/bitmap_shader_am_density_internal.png
Binary files differ
diff --git a/tests/tests/graphics/res/drawable/bitmap_shader_density.xml b/tests/tests/graphics/res/drawable/bitmap_shader_density.xml
new file mode 100644
index 0000000..435b06a
--- /dev/null
+++ b/tests/tests/graphics/res/drawable/bitmap_shader_density.xml
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+     Copyright (C) 2016 The Android Open Source Project
+    
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+    
+          http://www.apache.org/licenses/LICENSE-2.0
+    
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+
+<bitmap xmlns:android="http://schemas.android.com/apk/res/android"
+        android:src="@drawable/bitmap_shader_density_internal"
+        android:tileModeX="repeat"
+        android:tileModeY="clamp" />
diff --git a/tests/tests/graphics/res/drawable/bitmap_shader_density_internal.png b/tests/tests/graphics/res/drawable/bitmap_shader_density_internal.png
new file mode 100644
index 0000000..b6d4d89
--- /dev/null
+++ b/tests/tests/graphics/res/drawable/bitmap_shader_density_internal.png
Binary files differ
diff --git a/tests/tests/graphics/res/drawable/custom_animation_scale_list_drawable.xml b/tests/tests/graphics/res/drawable/custom_animation_scale_list_drawable.xml
new file mode 100644
index 0000000..1e9fbff
--- /dev/null
+++ b/tests/tests/graphics/res/drawable/custom_animation_scale_list_drawable.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ -->
+
+<com.android.internal.graphics.drawable.AnimationScaleListDrawable
+        xmlns:android="http://schemas.android.com/apk/res/android">
+    <item android:drawable="@drawable/vector_icon_create" />
+    <item android:drawable="@drawable/animation_vector_drawable_grouping_1" />
+</com.android.internal.graphics.drawable.AnimationScaleListDrawable>
diff --git a/tests/tests/graphics/res/drawable/layerdrawable_theme.xml b/tests/tests/graphics/res/drawable/layerdrawable_theme.xml
index 2a678ff..fac42b2 100644
--- a/tests/tests/graphics/res/drawable/layerdrawable_theme.xml
+++ b/tests/tests/graphics/res/drawable/layerdrawable_theme.xml
@@ -25,5 +25,6 @@
             android:dither="?attr/themeBoolean"
             android:src="?attr/themeNinePatch" />
     </item>
+    <item android:drawable="?attr/themeDrawable" />
 
-</layer-list>
\ No newline at end of file
+</layer-list>
diff --git a/tests/tests/graphics/src/android/graphics/drawable/cts/AnimatedStateListDrawableTest.java b/tests/tests/graphics/src/android/graphics/drawable/cts/AnimatedStateListDrawableTest.java
index 1bdac0a..02421a6 100644
--- a/tests/tests/graphics/src/android/graphics/drawable/cts/AnimatedStateListDrawableTest.java
+++ b/tests/tests/graphics/src/android/graphics/drawable/cts/AnimatedStateListDrawableTest.java
@@ -192,9 +192,11 @@
         DrawableTestUtils.setResourcesDensity(res, densityDpi / 2);
         final StateListDrawable halfDrawable =
                 (StateListDrawable) cs.newDrawable(res);
+        // NOTE: densityDpi may not be an even number, so account for *actual* scaling in asserts
+        final float approxHalf = (float)(densityDpi / 2) / densityDpi;
         for (int i = 0; i < count; i++) {
             halfDrawable.selectDrawable(i);
-            assertEquals(Math.round(origWidth[i] / 2f), halfDrawable.getIntrinsicWidth());
+            assertEquals(Math.round(origWidth[i] * approxHalf), halfDrawable.getIntrinsicWidth());
         }
 
         // Set density to double original.
diff --git a/tests/tests/graphics/src/android/graphics/drawable/cts/BitmapDrawableTest.java b/tests/tests/graphics/src/android/graphics/drawable/cts/BitmapDrawableTest.java
index a43fe8a..790d70d 100644
--- a/tests/tests/graphics/src/android/graphics/drawable/cts/BitmapDrawableTest.java
+++ b/tests/tests/graphics/src/android/graphics/drawable/cts/BitmapDrawableTest.java
@@ -508,29 +508,25 @@
     };
 
     private static final int[] DENSITY_IMAGES = new int[] {
-            R.drawable.bitmap_density
-    };
-
-    private static final int[][] DENSITY_GOLDEN_IMAGES = new int[][] {
-            {
-                    R.drawable.bitmap_density_golden_160,
-                    R.drawable.bitmap_density_golden_80,
-                    R.drawable.bitmap_density_golden_320,
-            }
+            R.drawable.bitmap_density,
+            R.drawable.bitmap_shader_density,
+            R.drawable.bitmap_shader_am_density,
     };
 
     public void testPreloadDensity() throws XmlPullParserException, IOException {
         final Resources res = mContext.getResources();
         final int densityDpi = res.getConfiguration().densityDpi;
         try {
-            testPreloadDensityInner(res, DENSITY_IMAGES[0], DENSITY_VALUES, DENSITY_GOLDEN_IMAGES[0]);
+            for (int i = 0; i < DENSITY_IMAGES.length; i++) {
+                testPreloadDensityInner(res, DENSITY_IMAGES[i], DENSITY_VALUES);
+            }
         } finally {
             DrawableTestUtils.setResourcesDensity(res, densityDpi);
         }
     }
 
-    private void testPreloadDensityInner(Resources res, int sourceResId, int[] densities,
-            int[] goldenResIds) throws XmlPullParserException, IOException {
+    private void testPreloadDensityInner(Resources res, int sourceResId, int[] densities)
+            throws XmlPullParserException, IOException {
         final Rect tempPadding = new Rect();
 
         // Capture initial state at preload density.
@@ -546,7 +542,7 @@
         final int origHeight = preloadedDrawable.getIntrinsicHeight();
         assertFalse(preloadedDrawable.getPadding(tempPadding));
 
-        compareOrSave(preloadedDrawable, preloadDensityDpi, sourceResId, goldenResIds[0]);
+        compareOrSave(preloadedDrawable, preloadDensityDpi, sourceResId);
 
         for (int i = 1; i < densities.length; i++) {
             final int scaledDensityDpi = densities[i];
@@ -555,6 +551,7 @@
 
             final BitmapDrawable scaledDrawable =
                     (BitmapDrawable) preloadedConstantState.newDrawable(res);
+            scaledDrawable.setLayoutDirection(LayoutDirection.RTL);
 
             // Sizes are rounded.
             assertEquals(Math.round(origWidth * scale), scaledDrawable.getIntrinsicWidth());
@@ -563,7 +560,7 @@
             // Bitmaps have no padding.
             assertFalse(scaledDrawable.getPadding(tempPadding));
 
-            compareOrSave(scaledDrawable, scaledDensityDpi, sourceResId, goldenResIds[i]);
+            compareOrSave(scaledDrawable, scaledDensityDpi, sourceResId);
 
             // Ensure theme density is applied correctly. Unlike most
             // drawables, we don't have any loss of accuracy because density
@@ -578,7 +575,7 @@
         }
     }
 
-    private void compareOrSave(Drawable dr, int densityDpi, int sourceResId, int goldenResId) {
+    private void compareOrSave(Drawable dr, int densityDpi, int sourceResId) {
         final int width = dr.getIntrinsicWidth();
         final int height = dr.getIntrinsicHeight();
         final Bitmap bitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
@@ -591,6 +588,7 @@
         if (DBG_DUMP_PNG) {
             saveGoldenImage(bitmap, sourceResId, densityDpi);
         } else {
+            final int goldenResId = getGoldenImageResId(sourceResId, densityDpi);
             final Bitmap golden = BitmapFactory.decodeResource(
                     mContext.getResources(), goldenResId);
             DrawableTestUtils.compareImages(densityDpi + " dpi", golden, bitmap,
@@ -598,28 +596,32 @@
         }
     }
 
+    private int getGoldenImageResId(int sourceResId, int densityDpi) {
+        final String name = getGoldenImageName(sourceResId, densityDpi);
+        return mContext.getResources().getIdentifier(name, "drawable", mContext.getPackageName());
+    }
+
+    private String getGoldenImageName(int sourceResId, int densityDpi) {
+        return mContext.getResources().getResourceEntryName(sourceResId) + "_golden_" + densityDpi;
+    }
+
     private void saveGoldenImage(Bitmap bitmap, int sourceResId, int densityDpi) {
         // Save the image to the disk.
         FileOutputStream out = null;
 
         try {
-            final String outputFolder = "/sdcard/temp/";
-            final File folder = new File(outputFolder);
-            if (!folder.exists()) {
-                folder.mkdir();
+            final File outputFolder = new File("/sdcard/temp/");
+            if (!outputFolder.exists()) {
+                outputFolder.mkdir();
             }
 
-            final String sourceFilename = new File(
-                    mContext.getResources().getString(sourceResId)).getName();
-            final String sourceTitle = sourceFilename.substring(0, sourceFilename.lastIndexOf("."));
-            final String outputTitle = sourceTitle + "_golden_" + densityDpi;
-            final String outputFilename = outputFolder + outputTitle + ".png";
-            final File outputFile = new File(outputFilename);
-            if (!outputFile.exists()) {
-                outputFile.createNewFile();
+            final String goldenFilename = getGoldenImageName(sourceResId, densityDpi) + ".png";
+            final File goldenFile = new File(outputFolder, goldenFilename);
+            if (!goldenFile.exists()) {
+                goldenFile.createNewFile();
             }
 
-            out = new FileOutputStream(outputFile, false);
+            out = new FileOutputStream(goldenFile, false);
             bitmap.compress(Bitmap.CompressFormat.PNG, 100, out);
         } catch (Exception e) {
             e.printStackTrace();
diff --git a/tests/tests/graphics/src/android/graphics/drawable/cts/CustomAnimationScaleListDrawableTest.java b/tests/tests/graphics/src/android/graphics/drawable/cts/CustomAnimationScaleListDrawableTest.java
new file mode 100644
index 0000000..3445641
--- /dev/null
+++ b/tests/tests/graphics/src/android/graphics/drawable/cts/CustomAnimationScaleListDrawableTest.java
@@ -0,0 +1,53 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.graphics.drawable.cts;
+
+import android.animation.ValueAnimator;
+import android.graphics.cts.R;
+import android.graphics.drawable.Animatable;
+import android.graphics.drawable.Drawable;
+import android.graphics.drawable.DrawableContainer;
+import android.test.AndroidTestCase;
+import android.test.suitebuilder.annotation.MediumTest;
+
+/**
+ * This test is used to verify that the CustomAnimationScaleListDrawable's current drawable depends
+ * on animation duration scale. When the scale is 0, it is a static drawable, otherwise, it is an
+ * animatable drawable.
+ */
+public class CustomAnimationScaleListDrawableTest extends AndroidTestCase {
+    @MediumTest
+    public void testNonZeroDurationScale() {
+        float originalScale = ValueAnimator.getDurationScale();
+        ValueAnimator.setDurationScale(2.0f);
+        Drawable dr = getContext().getDrawable(R.drawable.custom_animation_scale_list_drawable);
+        assertTrue(dr instanceof DrawableContainer);
+
+        assertTrue(dr.getCurrent() instanceof Animatable);
+        ValueAnimator.setDurationScale(originalScale);
+    }
+
+    @MediumTest
+    public void testZeroDurationScale() {
+        float originalScale = ValueAnimator.getDurationScale();
+        ValueAnimator.setDurationScale(0f);
+        Drawable dr = getContext().getDrawable(R.drawable.custom_animation_scale_list_drawable);
+        assertTrue(dr instanceof DrawableContainer);
+        assertFalse(dr.getCurrent() instanceof Animatable);
+        ValueAnimator.setDurationScale(originalScale);
+    }
+}
diff --git a/tests/tests/graphics/src/android/graphics/drawable/cts/GradientDrawableTest.java b/tests/tests/graphics/src/android/graphics/drawable/cts/GradientDrawableTest.java
index b715f2b..fe4274f 100644
--- a/tests/tests/graphics/src/android/graphics/drawable/cts/GradientDrawableTest.java
+++ b/tests/tests/graphics/src/android/graphics/drawable/cts/GradientDrawableTest.java
@@ -500,19 +500,28 @@
         final Resources res = getContext().getResources();
         final int densityDpi = res.getConfiguration().densityDpi;
         try {
-            testPreloadDensityInner(res);
+            DrawableTestUtils.setResourcesDensity(res, densityDpi);
+            verifyPreloadDensityInner(res, densityDpi);
         } finally {
             DrawableTestUtils.setResourcesDensity(res, densityDpi);
         }
     }
 
-    private void testPreloadDensityInner(Resources res) throws XmlPullParserException, IOException {
-        final Rect tempPadding = new Rect();
+    @MediumTest
+    public void testPreloadDensity_tvdpi() throws XmlPullParserException, IOException {
+        final Resources res = getContext().getResources();
+        final int densityDpi = res.getConfiguration().densityDpi;
+        try {
+            DrawableTestUtils.setResourcesDensity(res, 213);
+            verifyPreloadDensityInner(res, 213);
+        } finally {
+            DrawableTestUtils.setResourcesDensity(res, densityDpi);
+        }
+    }
 
-        // Set density to a fixed value so that we're not affected by the
-        // device's native density.
-        final int densityDpi = DisplayMetrics.DENSITY_MEDIUM;
-        DrawableTestUtils.setResourcesDensity(res, densityDpi);
+    private void verifyPreloadDensityInner(Resources res, int densityDpi)
+            throws XmlPullParserException, IOException {
+        final Rect tempPadding = new Rect();
 
         // Capture initial state at default density.
         final XmlResourceParser parser = DrawableTestUtils.getResourceParser(
@@ -525,15 +534,17 @@
         final Rect origPadding = new Rect();
         preloadedDrawable.getPadding(origPadding);
 
-        // Set density to half of original. Unlike offsets, which are
+        // Set density to approximately half of original. Unlike offsets, which are
         // truncated, dimensions are rounded to the nearest pixel.
         DrawableTestUtils.setResourcesDensity(res, densityDpi / 2);
         final GradientDrawable halfDrawable =
                 (GradientDrawable) preloadedConstantState.newDrawable(res);
-        assertEquals(Math.round(origWidth / 2f), halfDrawable.getIntrinsicWidth());
-        assertEquals(Math.round(origHeight / 2f), halfDrawable.getIntrinsicHeight());
+        // NOTE: densityDpi may not be an even number, so account for *actual* scaling in asserts
+        final float approxHalf = (float)(densityDpi / 2) / densityDpi;
+        assertEquals(Math.round(origWidth * approxHalf), halfDrawable.getIntrinsicWidth());
+        assertEquals(Math.round(origHeight * approxHalf), halfDrawable.getIntrinsicHeight());
         assertTrue(halfDrawable.getPadding(tempPadding));
-        assertEquals((int) (origPadding.left / 2f), tempPadding.left);
+        assertEquals((int) (origPadding.left * approxHalf), tempPadding.left);
 
         // Set density to double original.
         DrawableTestUtils.setResourcesDensity(res, densityDpi * 2);
@@ -553,20 +564,21 @@
         assertTrue(origDrawable.getPadding(tempPadding));
         assertEquals(origPadding, tempPadding);
 
-        // Some precision is lost when scaling the half-density
-        // drawable back up to the original density. Padding is
-        // always truncated, rather than rounded.
+        // Reproduce imprecise truncated scale down, and back up. Note these aren't rounded.
+        final float approxDouble = 1 / approxHalf;
         final Rect sloppyOrigPadding = new Rect();
-        sloppyOrigPadding.left = 2 * (origPadding.left / 2);
-        sloppyOrigPadding.top = 2 * (origPadding.top / 2);
-        sloppyOrigPadding.right = 2 * (origPadding.right / 2);
-        sloppyOrigPadding.bottom = 2 * (origPadding.bottom / 2);
+        sloppyOrigPadding.left = (int)(approxDouble * ((int)(origPadding.left * approxHalf)));
+        sloppyOrigPadding.top = (int)(approxDouble * ((int)(origPadding.top * approxHalf)));
+        sloppyOrigPadding.right = (int)(approxDouble * ((int)(origPadding.right * approxHalf)));
+        sloppyOrigPadding.bottom = (int)(approxDouble * ((int)(origPadding.bottom * approxHalf)));
 
         // Ensure theme density is applied correctly.
         final Theme t = res.newTheme();
         halfDrawable.applyTheme(t);
-        assertEquals(2 * Math.round(origWidth / 2f), halfDrawable.getIntrinsicWidth());
-        assertEquals(2 * Math.round(origHeight / 2f), halfDrawable.getIntrinsicHeight());
+        assertEquals(Math.round(approxDouble * Math.round(origWidth * approxHalf)),
+                halfDrawable.getIntrinsicWidth());
+        assertEquals(Math.round(approxDouble * Math.round(origHeight * approxHalf)),
+                halfDrawable.getIntrinsicHeight());
         assertTrue(halfDrawable.getPadding(tempPadding));
         assertEquals(sloppyOrigPadding, tempPadding);
         doubleDrawable.applyTheme(t);
diff --git a/tests/tests/graphics/src/android/graphics/drawable/cts/InsetDrawableTest.java b/tests/tests/graphics/src/android/graphics/drawable/cts/InsetDrawableTest.java
index 68223a0..81f774b 100644
--- a/tests/tests/graphics/src/android/graphics/drawable/cts/InsetDrawableTest.java
+++ b/tests/tests/graphics/src/android/graphics/drawable/cts/InsetDrawableTest.java
@@ -360,21 +360,29 @@
 
 
     public void testPreloadDensity() throws XmlPullParserException, IOException {
-        final Resources res = getContext().getResources();
+        final Resources res = mContext.getResources();
         final int densityDpi = res.getConfiguration().densityDpi;
         try {
-            testPreloadDensityInner(res);
+            DrawableTestUtils.setResourcesDensity(res, densityDpi);
+            verifyPreloadDensityInner(res, densityDpi);
         } finally {
             DrawableTestUtils.setResourcesDensity(res, densityDpi);
         }
     }
 
-    private void testPreloadDensityInner(Resources res) throws XmlPullParserException, IOException {
-        // Set density to a fixed value so that we're not affected by the
-        // device's native density.
-        final int densityDpi = DisplayMetrics.DENSITY_MEDIUM;
-        DrawableTestUtils.setResourcesDensity(res, densityDpi);
+    public void testPreloadDensity_tvdpi() throws XmlPullParserException, IOException {
+        final Resources res = mContext.getResources();
+        final int densityDpi = res.getConfiguration().densityDpi;
+        try {
+            DrawableTestUtils.setResourcesDensity(res, 213);
+            verifyPreloadDensityInner(res, 213);
+        } finally {
+            DrawableTestUtils.setResourcesDensity(res, densityDpi);
+        }
+    }
 
+    private void verifyPreloadDensityInner(Resources res, int densityDpi)
+            throws XmlPullParserException, IOException {
         // Capture initial state at default density.
         final XmlResourceParser parser = DrawableTestUtils.getResourceParser(
                 res, R.drawable.inset_density);
@@ -384,12 +392,14 @@
         final int origInsetHoriz = preloadedDrawable.getIntrinsicWidth()
                 - preloadedDrawable.getDrawable().getIntrinsicWidth();
 
-        // Set density to half of original. Unlike offsets, which are
+        // Set density to approximately half of original. Unlike offsets, which are
         // truncated, dimensions are rounded to the nearest pixel.
         DrawableTestUtils.setResourcesDensity(res, densityDpi / 2);
         final InsetDrawable halfDrawable =
                 (InsetDrawable) preloadedConstantState.newDrawable(res);
-        assertEquals(Math.round(origInsetHoriz / 2f), halfDrawable.getIntrinsicWidth()
+        // NOTE: densityDpi may not be an even number, so account for *actual* scaling in asserts
+        final float approxHalf = (float)(densityDpi / 2) / densityDpi;
+        assertEquals(Math.round(origInsetHoriz * approxHalf), halfDrawable.getIntrinsicWidth()
                 - halfDrawable.getDrawable().getIntrinsicWidth());
 
         // Set density to double original.
@@ -409,8 +419,10 @@
         // Ensure theme density is applied correctly.
         final Theme t = res.newTheme();
         halfDrawable.applyTheme(t);
-        assertEquals(origInsetHoriz, halfDrawable.getIntrinsicWidth()
-                - halfDrawable.getDrawable().getIntrinsicWidth());
+        float approxDouble = 1 / approxHalf;
+        // Reproduce imprecise truncated scale down, and back up. Note that we don't round.
+        assertEquals((int)(approxDouble * ((int)(origInsetHoriz * approxHalf))),
+                halfDrawable.getIntrinsicWidth() - halfDrawable.getDrawable().getIntrinsicWidth());
         doubleDrawable.applyTheme(t);
         assertEquals(origInsetHoriz, doubleDrawable.getIntrinsicWidth()
                 - doubleDrawable.getDrawable().getIntrinsicWidth());
diff --git a/tests/tests/graphics/src/android/graphics/drawable/cts/LayerDrawableTest.java b/tests/tests/graphics/src/android/graphics/drawable/cts/LayerDrawableTest.java
index 5a0a125..5539eed 100644
--- a/tests/tests/graphics/src/android/graphics/drawable/cts/LayerDrawableTest.java
+++ b/tests/tests/graphics/src/android/graphics/drawable/cts/LayerDrawableTest.java
@@ -1690,21 +1690,29 @@
 
 
     public void testPreloadDensity() throws XmlPullParserException, IOException {
-        final Resources res = getContext().getResources();
+        final Resources res = mContext.getResources();
         final int densityDpi = res.getConfiguration().densityDpi;
         try {
-            testPreloadDensityInner(res);
+            DrawableTestUtils.setResourcesDensity(res, densityDpi);
+            verifyPreloadDensityInner(res, densityDpi);
         } finally {
             DrawableTestUtils.setResourcesDensity(res, densityDpi);
         }
     }
 
-    private void testPreloadDensityInner(Resources res) throws XmlPullParserException, IOException {
-        // Set density to a fixed value so that we're not affected by the
-        // device's native density.
-        final int densityDpi = DisplayMetrics.DENSITY_MEDIUM;
-        DrawableTestUtils.setResourcesDensity(res, densityDpi);
+    public void testPreloadDensity_tvdpi() throws XmlPullParserException, IOException {
+        final Resources res = mContext.getResources();
+        final int densityDpi = res.getConfiguration().densityDpi;
+        try {
+            DrawableTestUtils.setResourcesDensity(res, 213);
+            verifyPreloadDensityInner(res, 213);
+        } finally {
+            DrawableTestUtils.setResourcesDensity(res, densityDpi);
+        }
+    }
 
+    private void verifyPreloadDensityInner(Resources res, int densityDpi)
+            throws XmlPullParserException, IOException {
         // Capture initial state at default density.
         final XmlResourceParser parser = DrawableTestUtils.getResourceParser(
                 res, R.drawable.layer_drawable_density);
@@ -1733,11 +1741,13 @@
         DrawableTestUtils.setResourcesDensity(res, densityDpi / 2);
         final LayerDrawable halfDrawable =
                 (LayerDrawable) preloadedConstantState.newDrawable(res);
-        final int halfContentWidth = Math.round(initialContentWidth / 2f);
-        final int halfLeftPadding = initialLeftPadding / 2;
-        final int halfRightPadding = initialRightPadding / 2;
-        final int halfContentInsetL = initialContentInsetL / 2;
-        final int halfContentInsetR = initialContentInsetR / 2;
+        // NOTE: densityDpi may not be an even number, so account for *actual* scaling in asserts
+        final float approxHalf = (float)(densityDpi / 2) / densityDpi;
+        final int halfContentWidth = Math.round(initialContentWidth * approxHalf);
+        final int halfLeftPadding = (int) (initialLeftPadding * approxHalf);
+        final int halfRightPadding = (int) (initialRightPadding * approxHalf);
+        final int halfContentInsetL = (int) (initialContentInsetL * approxHalf);
+        final int halfContentInsetR = (int) (initialContentInsetR * approxHalf);
         final int halfIntrinsicWidth = halfContentWidth + halfContentInsetL + halfContentInsetR;
         assertEquals(halfLeftPadding, halfDrawable.getLeftPadding());
         assertEquals(halfRightPadding, halfDrawable.getRightPadding());
@@ -1745,14 +1755,18 @@
         assertEquals(halfContentInsetR, halfDrawable.getLayerInsetLeft(0));
         assertEquals(halfContentWidth, halfDrawable.getLayerWidth(0));
         assertEquals(halfIntrinsicWidth, halfDrawable.getIntrinsicWidth());
-        assertEquals(initialBottomPadding / 2, halfDrawable.getBottomPadding());
-        assertEquals(initialTopPadding / 2, halfDrawable.getTopPadding());
-        assertEquals(initialLayerInsetLeft / 2,halfDrawable.getLayerInsetLeft(0));
-        assertEquals(initialLayerInsetRight / 2, halfDrawable.getLayerInsetRight(0));
-        assertEquals(initialLayerInsetTop / 2, halfDrawable.getLayerInsetTop(0));
-        assertEquals(initialLayerInsetBottom / 2, halfDrawable.getLayerInsetBottom(0));
-        assertEquals(Math.round(initialLayerWidth / 2f), halfDrawable.getLayerWidth(0));
-        assertEquals(Math.round(initialLayerHeight / 2f), halfDrawable.getLayerHeight(0));
+        assertEquals((int) (initialBottomPadding * approxHalf), halfDrawable.getBottomPadding());
+        assertEquals((int) (initialTopPadding * approxHalf), halfDrawable.getTopPadding());
+        assertEquals((int) (initialLayerInsetLeft * approxHalf),
+                halfDrawable.getLayerInsetLeft(0));
+        assertEquals((int) (initialLayerInsetRight * approxHalf),
+                halfDrawable.getLayerInsetRight(0));
+        assertEquals((int) (initialLayerInsetTop * approxHalf),
+                halfDrawable.getLayerInsetTop(0));
+        assertEquals((int) (initialLayerInsetBottom * approxHalf),
+                halfDrawable.getLayerInsetBottom(0));
+        assertEquals(Math.round(initialLayerWidth * approxHalf), halfDrawable.getLayerWidth(0));
+        assertEquals(Math.round(initialLayerHeight * approxHalf), halfDrawable.getLayerHeight(0));
 
         // Set density to double original.
         DrawableTestUtils.setResourcesDensity(res, densityDpi * 2);
@@ -1798,20 +1812,31 @@
         // The half-density drawable will scale-up all of the values that were
         // previously scaled-down, so we need to capture the rounding errors.
         halfDrawable.applyTheme(t);
-        assertEquals(halfLeftPadding * 2, halfDrawable.getLeftPadding());
-        assertEquals(halfRightPadding * 2, halfDrawable.getRightPadding());
-        assertEquals(halfContentInsetL * 2, halfDrawable.getLayerInsetRight(0));
-        assertEquals(halfContentInsetR * 2, halfDrawable.getLayerInsetLeft(0));
-        assertEquals(halfContentWidth * 2, halfDrawable.getLayerWidth(0));
+
+        // Reproduce imprecise truncated scale down, and back up. Note that we don't round.
+        float approxDouble = 1 / approxHalf;
+        assertEquals((int) (halfLeftPadding * approxDouble), halfDrawable.getLeftPadding());
+        assertEquals((int) (halfRightPadding * approxDouble), halfDrawable.getRightPadding());
+        assertEquals((int) (halfContentInsetL * approxDouble), halfDrawable.getLayerInsetRight(0));
+        assertEquals((int) (halfContentInsetR * approxDouble), halfDrawable.getLayerInsetLeft(0));
+        assertEquals((int) (halfContentWidth * approxDouble), halfDrawable.getLayerWidth(0));
         assertEquals(halfIntrinsicWidth * 2, halfDrawable.getIntrinsicWidth());
-        assertEquals(2 * (initialBottomPadding / 2), halfDrawable.getBottomPadding());
-        assertEquals(2 * (initialTopPadding / 2), halfDrawable.getTopPadding());
-        assertEquals(2 * (initialLayerInsetLeft / 2), halfDrawable.getLayerInsetLeft(0));
-        assertEquals(2 * (initialLayerInsetRight / 2), halfDrawable.getLayerInsetRight(0));
-        assertEquals(2 * (initialLayerInsetTop / 2), halfDrawable.getLayerInsetTop(0));
-        assertEquals(2 * (initialLayerInsetBottom / 2), halfDrawable.getLayerInsetBottom(0));
-        assertEquals(2 * Math.round(initialLayerWidth / 2f), halfDrawable.getLayerWidth(0));
-        assertEquals(2 * Math.round(initialLayerHeight / 2f), halfDrawable.getLayerHeight(0));
+        assertEquals((int) ((int) (initialBottomPadding * approxHalf) * approxDouble),
+                halfDrawable.getBottomPadding());
+        assertEquals((int) ((int) (initialTopPadding * approxHalf) * approxDouble),
+                halfDrawable.getTopPadding());
+        assertEquals((int) ((int) (initialLayerInsetLeft * approxHalf) * approxDouble),
+                halfDrawable.getLayerInsetLeft(0));
+        assertEquals((int) ((int) (initialLayerInsetRight * approxHalf) * approxDouble),
+                halfDrawable.getLayerInsetRight(0));
+        assertEquals((int) ((int) (initialLayerInsetTop * approxHalf) * approxDouble),
+                halfDrawable.getLayerInsetTop(0));
+        assertEquals((int) ((int) (initialLayerInsetBottom * approxHalf) * approxDouble),
+                halfDrawable.getLayerInsetBottom(0));
+        assertEquals(Math.round(Math.round(initialLayerWidth * approxHalf) * approxDouble),
+                halfDrawable.getLayerWidth(0));
+        assertEquals(Math.round(Math.round(initialLayerHeight * approxHalf) * approxDouble),
+                halfDrawable.getLayerHeight(0));
 
         // The double-density drawable will scale-down all of the values that
         // were previously scaled-up, so we don't need to worry about rounding.
diff --git a/tests/tests/graphics/src/android/graphics/drawable/cts/StateListDrawableTest.java b/tests/tests/graphics/src/android/graphics/drawable/cts/StateListDrawableTest.java
index b9f59cd..8876dc3 100644
--- a/tests/tests/graphics/src/android/graphics/drawable/cts/StateListDrawableTest.java
+++ b/tests/tests/graphics/src/android/graphics/drawable/cts/StateListDrawableTest.java
@@ -210,10 +210,12 @@
         DrawableTestUtils.setResourcesDensity(res, densityDpi / 2);
         final StateListDrawable halfDrawable =
                 (StateListDrawable) preloadedConstantState.newDrawable(res);
+        // NOTE: densityDpi may not be an even number, so account for *actual* scaling in asserts
+        final float approxHalf = (float)(densityDpi / 2) / densityDpi;
         halfDrawable.selectDrawable(0);
-        assertEquals(Math.round(origWidth0 / 2f), halfDrawable.getIntrinsicWidth());
+        assertEquals(Math.round(origWidth0 * approxHalf), halfDrawable.getIntrinsicWidth());
         halfDrawable.selectDrawable(1);
-        assertEquals(Math.round(origWidth1 / 2f), halfDrawable.getIntrinsicWidth());
+        assertEquals(Math.round(origWidth1 * approxHalf), halfDrawable.getIntrinsicWidth());
 
         // Set density to double original.
         DrawableTestUtils.setResourcesDensity(res, densityDpi * 2);
diff --git a/tests/tests/graphics/src/android/graphics/drawable/cts/ThemedDrawableTest.java b/tests/tests/graphics/src/android/graphics/drawable/cts/ThemedDrawableTest.java
index 52bef55..7c6fe7c 100644
--- a/tests/tests/graphics/src/android/graphics/drawable/cts/ThemedDrawableTest.java
+++ b/tests/tests/graphics/src/android/graphics/drawable/cts/ThemedDrawableTest.java
@@ -22,6 +22,7 @@
 import android.graphics.Color;
 import android.graphics.Rect;
 import android.graphics.Shader.TileMode;
+import android.graphics.drawable.Drawable;
 import android.graphics.drawable.BitmapDrawable;
 import android.graphics.drawable.ColorDrawable;
 import android.graphics.drawable.GradientDrawable;
@@ -34,7 +35,6 @@
 
 import android.graphics.cts.R;
 
-@TargetApi(21)
 public class ThemedDrawableTest extends AndroidTestCase {
 
     @Override
@@ -150,9 +150,14 @@
         assertEquals(true, d.isAutoMirrored());
 
         BitmapDrawable bitmapDrawable  = (BitmapDrawable) d.getDrawable(0);
+        assertEquals(d, bitmapDrawable.getCallback());
         internalTestBitmapDrawable(bitmapDrawable);
 
         NinePatchDrawable ninePatchDrawable = (NinePatchDrawable) d.getDrawable(1);
+        assertEquals(d, ninePatchDrawable.getCallback());
         internalTestNinePatchDrawable(ninePatchDrawable);
+
+        Drawable themeDrawable = (Drawable) d.getDrawable(2);
+        assertEquals(d, themeDrawable.getCallback());
     }
 }
diff --git a/tests/tests/graphics/src/android/graphics/drawable/cts/VectorDrawableTest.java b/tests/tests/graphics/src/android/graphics/drawable/cts/VectorDrawableTest.java
index 7d08519..eb02c24 100644
--- a/tests/tests/graphics/src/android/graphics/drawable/cts/VectorDrawableTest.java
+++ b/tests/tests/graphics/src/android/graphics/drawable/cts/VectorDrawableTest.java
@@ -417,17 +417,6 @@
     }
 
     @SmallTest
-    public void testPreloadDensity() throws XmlPullParserException, IOException {
-        final Resources res = getContext().getResources();
-        final int densityDpi = res.getConfiguration().densityDpi;
-        try {
-            testPreloadDensityInner(res);
-        } finally {
-            DrawableTestUtils.setResourcesDensity(res, densityDpi);
-        }
-    }
-
-    @SmallTest
     public void testGetOpacity() throws XmlPullParserException, IOException {
         VectorDrawable vectorDrawable = new VectorDrawable();
 
@@ -441,12 +430,30 @@
                 vectorDrawable.getOpacity());
     }
 
-    private void testPreloadDensityInner(Resources res) throws XmlPullParserException, IOException {
-        // Set density to a fixed value so that we're not affected by the
-        // device's native density.
-        final int densityDpi = DisplayMetrics.DENSITY_MEDIUM;
-        DrawableTestUtils.setResourcesDensity(res, densityDpi);
+    @SmallTest
+    public void testPreloadDensity() throws XmlPullParserException, IOException {
+        final int densityDpi = mResources.getConfiguration().densityDpi;
+        try {
+            DrawableTestUtils.setResourcesDensity(mResources, densityDpi);
+            verifyPreloadDensityInner(mResources, densityDpi);
+        } finally {
+            DrawableTestUtils.setResourcesDensity(mResources, densityDpi);
+        }
+    }
 
+    @SmallTest
+    public void testPreloadDensity_tvdpi() throws XmlPullParserException, IOException {
+        final int densityDpi = mResources.getConfiguration().densityDpi;
+        try {
+            DrawableTestUtils.setResourcesDensity(mResources, 213);
+            verifyPreloadDensityInner(mResources, 213);
+        } finally {
+            DrawableTestUtils.setResourcesDensity(mResources, densityDpi);
+        }
+    }
+
+    private void verifyPreloadDensityInner(Resources res, int densityDpi)
+            throws XmlPullParserException, IOException {
         // Capture initial state at default density.
         final XmlResourceParser parser = DrawableTestUtils.getResourceParser(
                 res, R.drawable.vector_density);
@@ -460,7 +467,9 @@
         DrawableTestUtils.setResourcesDensity(res, densityDpi / 2);
         final VectorDrawable halfDrawable =
                 (VectorDrawable) preloadedConstantState.newDrawable(res);
-        assertEquals(Math.round(origWidth / 2f), halfDrawable.getIntrinsicWidth());
+        // NOTE: densityDpi may not be an even number, so account for *actual* scaling in asserts
+        final float approxHalf = (float)(densityDpi / 2) / densityDpi;
+        assertEquals(Math.round(origWidth * approxHalf), halfDrawable.getIntrinsicWidth());
 
         // Set density to double original.
         DrawableTestUtils.setResourcesDensity(res, densityDpi * 2);
diff --git a/tests/tests/graphics/src/android/opengl/cts/EglConfigTest.java b/tests/tests/graphics/src/android/opengl/cts/EglConfigTest.java
old mode 100755
new mode 100644
index b22e421..1468382
--- a/tests/tests/graphics/src/android/opengl/cts/EglConfigTest.java
+++ b/tests/tests/graphics/src/android/opengl/cts/EglConfigTest.java
@@ -63,10 +63,8 @@
             EglConfigCtsActivity activity = launchActivity("android.graphics.cts",
                     EglConfigCtsActivity.class, extras);
             activity.waitToFinishDrawing();
-
             // TODO(b/30948621): Remove the sleep below once b/30948621 is fixed.
             Thread.sleep(500);
-
             activity.finish();
             mInstrumentation.waitForIdleSync();
         }
diff --git a/tests/tests/keystore/src/android/keystore/cts/KeyGeneratorTest.java b/tests/tests/keystore/src/android/keystore/cts/KeyGeneratorTest.java
index 6deaed4..4a4ea98 100644
--- a/tests/tests/keystore/src/android/keystore/cts/KeyGeneratorTest.java
+++ b/tests/tests/keystore/src/android/keystore/cts/KeyGeneratorTest.java
@@ -271,12 +271,12 @@
                             continue;
                         }
                     }
-                    if ((i > 0) && ((i % 8 ) == 0)) {
+                    if ((i >= 64) && ((i % 8 ) == 0)) {
                         keyGenerator.init(spec, rng);
                         SecretKey key = keyGenerator.generateKey();
                         assertEquals(i, TestUtils.getKeyInfo(key).getKeySize());
                         assertEquals((i + 7) / 8, rng.getOutputSizeBytes());
-                    } else {
+                    } else if (i >= 64) {
                         try {
                             keyGenerator.init(spec, rng);
                             fail();
diff --git a/tests/tests/location/src/android/location/cts/GnssStatusTest.java b/tests/tests/location/src/android/location/cts/GnssStatusTest.java
new file mode 100644
index 0000000..e8f3cb1
--- /dev/null
+++ b/tests/tests/location/src/android/location/cts/GnssStatusTest.java
@@ -0,0 +1,49 @@
+package android.location.cts;
+
+import android.location.GnssStatus;
+
+public class GnssStatusTest extends GnssTestCase  {
+
+    private static final String TAG = "GnssStatusTest";
+    private static final int LOCATION_TO_COLLECT_COUNT = 1;
+    private static final int STATUS_TO_COLLECT_COUNT = 3;
+
+  @Override
+  protected void setUp() throws Exception {
+    super.setUp();
+    mTestLocationManager = new TestLocationManager(getContext());
+  }
+
+  /**
+   * Tests that one can listen for {@link GnssStatus}.
+   */
+  public void testGnssStatusChanges() throws Exception {
+    // Checks if GPS hardware feature is present, skips test (pass) if not,
+    // and hard asserts that Location/GPS (Provider) is turned on if is Cts Verifier.
+    if (!TestMeasurementUtil.canTestRunOnCurrentDevice(mTestLocationManager,
+        TAG, MIN_HARDWARE_YEAR_MEASUREMENTS_REQUIRED, isCtsVerifierTest())) {
+      return;
+    }
+
+    // Register Gps Status Listener.
+    TestGnssStatusCallback testGnssStatusCallback =
+        new TestGnssStatusCallback(TAG, STATUS_TO_COLLECT_COUNT);
+    mTestLocationManager.registerGnssStatusCallback(testGnssStatusCallback);
+
+    TestLocationListener locationListener = new TestLocationListener(LOCATION_TO_COLLECT_COUNT);
+    mTestLocationManager.requestLocationUpdates(locationListener);
+
+    boolean success = testGnssStatusCallback.awaitStart();
+    success = success ? testGnssStatusCallback.awaitStatus() : false;
+    success = success ? testGnssStatusCallback.awaitTtff() : false;
+    mTestLocationManager.removeLocationUpdates(locationListener);
+    success = success ? testGnssStatusCallback.awaitStop() : false;
+    mTestLocationManager.unregisterGnssStatusCallback(testGnssStatusCallback);
+
+    SoftAssert.failOrWarning(isMeasurementTestStrict(),
+        "Time elapsed without getting the right status changes."
+            + " Possibly, the test has been run deep indoors."
+            + " Consider retrying test outdoors.",
+        success);
+  }
+}
diff --git a/tests/tests/location/src/android/location/cts/TestGnssStatusCallback.java b/tests/tests/location/src/android/location/cts/TestGnssStatusCallback.java
index cc4c930..c63fb01 100644
--- a/tests/tests/location/src/android/location/cts/TestGnssStatusCallback.java
+++ b/tests/tests/location/src/android/location/cts/TestGnssStatusCallback.java
@@ -18,6 +18,7 @@
 
 import android.location.GnssStatus;
 
+import android.util.Log;
 import java.util.ArrayList;
 import java.util.List;
 import java.util.concurrent.CountDownLatch;
@@ -28,34 +29,50 @@
  */
 class TestGnssStatusCallback extends GnssStatus.Callback {
 
+    private final String mTag;
     private volatile boolean mGpsStatusReceived;
     private GnssStatus mGnssStatus = null;
     // Timeout in sec for count down latch wait
     private static final int TIMEOUT_IN_SEC = 90;
-    private final CountDownLatch mCountDownLatch;
+    private final CountDownLatch mLatchStart;
+    private final CountDownLatch mLatchStatus;
+    private final CountDownLatch mLatchTtff;
+    private final CountDownLatch mLatchStop;
+
     // Store list of Prn for Satellites.
     private List<List<Integer>> mGpsSatellitePrns;
 
-    TestGnssStatusCallback(int gpsStatusCountToCollect) {
-        mCountDownLatch = new CountDownLatch(gpsStatusCountToCollect);
+    TestGnssStatusCallback(String tag, int gpsStatusCountToCollect) {
+        this.mTag = tag;
+        mLatchStart = new CountDownLatch(1);
+        mLatchStatus = new CountDownLatch(gpsStatusCountToCollect);
+        mLatchTtff = new CountDownLatch(1);
+        mLatchStop = new CountDownLatch(1);
         mGpsSatellitePrns = new ArrayList<List<Integer>>();
     }
 
     @Override
     public void onStarted() {
+        Log.i(mTag, "Gnss Status Listener Started");
+        mLatchStart.countDown();
     }
 
     @Override
     public void onStopped() {
+        Log.i(mTag, "Gnss Status Listener Stopped");
+        mLatchStop.countDown();
     }
 
     @Override
     public void onFirstFix(int ttffMillis) {
+        Log.i(mTag, "Gnss Status Listener Received TTFF");
+        mLatchTtff.countDown();
     }
 
     @Override
     public void onSatelliteStatusChanged(GnssStatus status) {
-        mCountDownLatch.countDown();
+        Log.i(mTag, "Gnss Status Listener Received Status Update");
+        mLatchStatus.countDown();
     }
 
     /**
@@ -86,7 +103,19 @@
         return mGnssStatus;
     }
 
-    public boolean await() throws InterruptedException {
-        return TestUtils.waitFor(mCountDownLatch, TIMEOUT_IN_SEC);
+    public boolean awaitStart() throws InterruptedException {
+        return TestUtils.waitFor(mLatchStart, TIMEOUT_IN_SEC);
+    }
+
+    public boolean awaitStatus() throws InterruptedException {
+        return TestUtils.waitFor(mLatchStatus, TIMEOUT_IN_SEC);
+    }
+
+    public boolean awaitTtff() throws InterruptedException {
+        return TestUtils.waitFor(mLatchTtff, TIMEOUT_IN_SEC);
+    }
+
+    public boolean awaitStop() throws InterruptedException {
+        return TestUtils.waitFor(mLatchStop, TIMEOUT_IN_SEC);
     }
 }
diff --git a/tests/tests/location/src/android/location/cts/TestLocationManager.java b/tests/tests/location/src/android/location/cts/TestLocationManager.java
index 26cc057..cca2b78 100644
--- a/tests/tests/location/src/android/location/cts/TestLocationManager.java
+++ b/tests/tests/location/src/android/location/cts/TestLocationManager.java
@@ -19,6 +19,7 @@
 import android.content.Context;
 import android.location.GnssMeasurementsEvent;
 import android.location.GnssNavigationMessage;
+import android.location.GnssStatus;
 import android.location.GpsStatus;
 import android.location.LocationListener;
 import android.location.LocationManager;
@@ -193,6 +194,28 @@
     }
 
     /**
+     * Add a GNSS Status callback.
+     *
+     * @param callback a {@link GnssStatus.Callback} object to register.
+     * @return {@code true} if the listener was added successfully, {@code false} otherwise.
+     */
+    public boolean registerGnssStatusCallback(GnssStatus.Callback callback) {
+        Log.i(TAG, "Add Gnss Status Callback.");
+        return mLocationManager.registerGnssStatusCallback(
+            callback, new Handler(Looper.getMainLooper()));
+    }
+
+    /**
+     * Removes a GNSS Status callback.
+     *
+     * @param callback a {@link GnssStatus.Callback} object to remove.
+     */
+    public void unregisterGnssStatusCallback(GnssStatus.Callback callback) {
+        Log.i(TAG, "Remove Gnss Status Callback.");
+        mLocationManager.unregisterGnssStatusCallback(callback);
+    }
+
+    /**
      * Get LocationManager
      *
      * @return locationManager
diff --git a/tests/tests/media/res/raw/largealbumart.mp3 b/tests/tests/media/res/raw/largealbumart.mp3
new file mode 100644
index 0000000..e630f0d
--- /dev/null
+++ b/tests/tests/media/res/raw/largealbumart.mp3
Binary files differ
diff --git a/tests/tests/media/src/android/media/cts/AudioNativeTest.java b/tests/tests/media/src/android/media/cts/AudioNativeTest.java
index bfc34d1..7301cc7 100644
--- a/tests/tests/media/src/android/media/cts/AudioNativeTest.java
+++ b/tests/tests/media/src/android/media/cts/AudioNativeTest.java
@@ -24,7 +24,6 @@
 import android.media.AudioManager;
 
 public class AudioNativeTest extends CtsAndroidTestCase {
-    // Assume stereo here until b/23899814 is fixed.
     public static final int MAX_CHANNEL_COUNT = 2;
     public static final int MAX_INDEX_MASK = (1 << MAX_CHANNEL_COUNT) - 1;
 
@@ -215,11 +214,7 @@
         }
         AudioTrackNative track = new AudioTrackNative();
 
-        // TODO: when b/23899814 is fixed, use AudioManager.getDevices() to enumerate
-        // actual devices and their channel counts instead of assuming stereo.
-        //
         int maxOutputChannels = 2;
-
         int validIndexMask = (1 << maxOutputChannels) - 1;
 
         for (int mask = 0; mask <= MAX_INDEX_MASK; ++mask) {
@@ -241,14 +236,20 @@
         if (!hasMicrophone()) {
             return;
         }
+
+        AudioManager audioManager =
+                (AudioManager) getContext().getSystemService(Context.AUDIO_SERVICE);
         AudioRecordNative recorder = new AudioRecordNative();
 
-        // TODO: when b/23899814 is fixed, use AudioManager.getDevices() to enumerate
-        // actual devices and their channel counts instead of assuming stereo.
-        //
-        int maxInputChannels = 2;
+        int maxInputChannels = 0;
+        for (AudioDeviceInfo deviceInfo :
+                audioManager.getDevices(AudioManager.GET_DEVICES_INPUTS)) {
+            for (int channels : deviceInfo.getChannelCounts()) {
+                maxInputChannels = Math.max(channels, maxInputChannels);
+            }
+        }
 
-        int validIndexMask = (1 << maxInputChannels) -1;
+        int validIndexMask = (1 << maxInputChannels) - 1;
 
         for (int mask = 0; mask <= MAX_INDEX_MASK; ++mask) {
             int channelCount = Long.bitCount(mask);
diff --git a/tests/tests/media/src/android/media/cts/DecoderTest.java b/tests/tests/media/src/android/media/cts/DecoderTest.java
index 13ebeff..3025306 100755
--- a/tests/tests/media/src/android/media/cts/DecoderTest.java
+++ b/tests/tests/media/src/android/media/cts/DecoderTest.java
@@ -501,9 +501,9 @@
 
     private void testTrackSelection(int resid) throws Exception {
         AssetFileDescriptor fd1 = null;
+        MediaExtractor ex1 = new MediaExtractor();
         try {
             fd1 = mResources.openRawResourceFd(resid);
-            MediaExtractor ex1 = new MediaExtractor();
             ex1.setDataSource(fd1.getFileDescriptor(), fd1.getStartOffset(), fd1.getLength());
 
             ByteBuffer buf1 = ByteBuffer.allocate(1024*1024);
@@ -664,6 +664,9 @@
             }
 
         } finally {
+            if (ex1 != null) {
+                ex1.release();
+            }
             if (fd1 != null) {
                 fd1.close();
             }
diff --git a/tests/tests/media/src/android/media/cts/DeviceUtils.java b/tests/tests/media/src/android/media/cts/DeviceUtils.java
new file mode 100644
index 0000000..9051c69
--- /dev/null
+++ b/tests/tests/media/src/android/media/cts/DeviceUtils.java
@@ -0,0 +1,58 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.media.cts;
+
+import android.content.BroadcastReceiver;
+import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.content.pm.PackageManager;
+
+import android.media.AudioDeviceInfo;
+import android.media.AudioManager;
+
+import android.util.Log;
+
+/* package */ class DeviceUtils {
+    private static final String TAG = "DeviceUtils";
+
+    /* package */ static boolean hasOutputDevice(AudioManager audioMgr) {
+        AudioDeviceInfo[] devices = audioMgr.getDevices(AudioManager.GET_DEVICES_OUTPUTS);
+        return devices.length != 0;
+    }
+
+    /* package */ static boolean hasInputDevice(AudioManager audioMgr) {
+        AudioDeviceInfo[] devices = audioMgr.getDevices(AudioManager.GET_DEVICES_INPUTS);
+        return devices.length != 0;
+    }
+
+    /* package */ static boolean isTVDevice(Context context) {
+        return context.getPackageManager().hasSystemFeature(PackageManager.FEATURE_LEANBACK);
+    }
+
+    /*
+     * HDMI
+     */
+    /* package */ static boolean isHDMIConnected(Context context) {
+        // configure the IntentFilter
+        IntentFilter intentFilter = new IntentFilter();
+        intentFilter.addAction(AudioManager.ACTION_HDMI_AUDIO_PLUG);
+        Intent intent = context.registerReceiver(null, intentFilter);
+
+        return intent != null && intent.getIntExtra(AudioManager.EXTRA_AUDIO_PLUG_STATE, 0) != 0;
+    }
+}
diff --git a/tests/tests/media/src/android/media/cts/EncoderTest.java b/tests/tests/media/src/android/media/cts/EncoderTest.java
index adb2351..e086347 100644
--- a/tests/tests/media/src/android/media/cts/EncoderTest.java
+++ b/tests/tests/media/src/android/media/cts/EncoderTest.java
@@ -161,7 +161,7 @@
         try {
             pool.shutdown();
             assertTrue("timed out waiting for encoder threads",
-                    pool.awaitTermination(5, TimeUnit.MINUTES));
+                    pool.awaitTermination(10, TimeUnit.MINUTES));
         } catch (InterruptedException e) {
             fail("interrupted while waiting for encoder threads");
         }
diff --git a/tests/tests/media/src/android/media/cts/EnumDevicesTest.java b/tests/tests/media/src/android/media/cts/EnumDevicesTest.java
index 94af087..1d84a3e 100644
--- a/tests/tests/media/src/android/media/cts/EnumDevicesTest.java
+++ b/tests/tests/media/src/android/media/cts/EnumDevicesTest.java
@@ -28,10 +28,14 @@
 
 import android.test.AndroidTestCase;
 
+import android.util.Log;
+
 /**
  * TODO: Insert description here. (generated by pmclean)
  */
 public class EnumDevicesTest extends AndroidTestCase {
+    private static final String TAG = "EnumDevicesTest";
+
     private AudioManager mAudioManager;
 
     boolean mAddCallbackCalled = false;
@@ -54,25 +58,39 @@
         assertTrue(deviceList != null);
         assertTrue(deviceList.length == 0);
 
+        PackageManager pkgMgr = mContext.getPackageManager();
+
+        boolean isTvDevice = DeviceUtils.isTVDevice(mContext);
+
         int numOutputDevices = 0;
-        if (mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_AUDIO_OUTPUT)) {
+        if (pkgMgr.hasSystemFeature(PackageManager.FEATURE_AUDIO_OUTPUT)) {
             // test OUTPUTS
             deviceList = mAudioManager.getDevices(AudioManager.GET_DEVICES_OUTPUTS);
             assertTrue(deviceList != null);
-            numOutputDevices = deviceList.length;
-            assertTrue(numOutputDevices != 0);
 
-            // all should be "sinks"
+            numOutputDevices = deviceList.length;
+            if (numOutputDevices == 0) {
+                boolean isHDMIConnected = DeviceUtils.isHDMIConnected(mContext);
+                if (isTvDevice && !isHDMIConnected) {
+                    Log.w(TAG, "getDevices test: failure due to missing reported output " +
+                               "or the test is run on a TV device with no HDMI connected");
+                }
+                assertTrue("getDevices test: failure due to missing HDMI connection " +
+                           "or missing output", false);
+            }
+
+            // any reported output devices should be "sinks"
             for(int index = 0; index < numOutputDevices; index++) {
                 assertTrue(deviceList[index].isSink());
             }
         }
 
         int numInputDevices = 0;
-        if (mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_MICROPHONE)) {
+        if (pkgMgr.hasSystemFeature(PackageManager.FEATURE_MICROPHONE)) {
             // test INPUTS
             deviceList = mAudioManager.getDevices(AudioManager.GET_DEVICES_INPUTS);
             assertTrue(deviceList != null);
+
             numInputDevices = deviceList.length;
             assertTrue(numInputDevices != 0);
 
@@ -86,6 +104,7 @@
         if (mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_AUDIO_OUTPUT) &&
                 mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_MICROPHONE)) {
             deviceList = mAudioManager.getDevices(AudioManager.GET_DEVICES_ALL);
+            assertTrue(deviceList != null);
             assertTrue(deviceList.length == (numOutputDevices + numInputDevices));
         }
     }
diff --git a/tests/tests/media/src/android/media/cts/MediaMetadataRetrieverTest.java b/tests/tests/media/src/android/media/cts/MediaMetadataRetrieverTest.java
index 0b38e1b..890073c 100644
--- a/tests/tests/media/src/android/media/cts/MediaMetadataRetrieverTest.java
+++ b/tests/tests/media/src/android/media/cts/MediaMetadataRetrieverTest.java
@@ -124,6 +124,12 @@
                 mRetriever.extractMetadata(MediaMetadataRetriever.METADATA_KEY_WRITER));
     }
 
+    public void testLargeAlbumArt() {
+        setDataSourceFd(R.raw.largealbumart);
+
+        assertNotNull("couldn't retrieve album art", mRetriever.getEmbeddedPicture());
+    }
+
     public void testSetDataSourceNullPath() {
         try {
             mRetriever.setDataSource((String)null);
diff --git a/tests/tests/media/src/android/media/cts/MediaPlayerTest.java b/tests/tests/media/src/android/media/cts/MediaPlayerTest.java
index 9e798db..3f0cc39 100644
--- a/tests/tests/media/src/android/media/cts/MediaPlayerTest.java
+++ b/tests/tests/media/src/android/media/cts/MediaPlayerTest.java
@@ -1429,10 +1429,10 @@
 
         // Run twice to check if repeated selection-deselection on the same track works well.
         for (int i = 0; i < 2; i++) {
-            // Waits until at least one subtitle is fired. Timeout is 2 seconds.
+            // Waits until at least one subtitle is fired. Timeout is 2.5 seconds.
             selectSubtitleTrack(i);
             mOnSubtitleDataCalled.reset();
-            assertTrue(mOnSubtitleDataCalled.waitForSignal(2000));
+            assertTrue(mOnSubtitleDataCalled.waitForSignal(2500));
 
             // Try deselecting track.
             deselectSubtitleTrack(i);
diff --git a/tests/tests/media/src/android/media/cts/MediaRecorderTest.java b/tests/tests/media/src/android/media/cts/MediaRecorderTest.java
index dffb653..829f3f6 100644
--- a/tests/tests/media/src/android/media/cts/MediaRecorderTest.java
+++ b/tests/tests/media/src/android/media/cts/MediaRecorderTest.java
@@ -246,6 +246,8 @@
         if (videoSizes == null) {
             videoSizes = parameters.getSupportedPreviewSizes();
         }
+        int minVideoWidth = Integer.MAX_VALUE;
+        int minVideoHeight = Integer.MAX_VALUE;
         for (Camera.Size size : videoSizes)
         {
             if (size.width == VIDEO_WIDTH && size.height == VIDEO_HEIGHT) {
@@ -253,9 +255,14 @@
                 mVideoHeight = VIDEO_HEIGHT;
                 return;
             }
+            if (size.width < minVideoWidth || size.height < minVideoHeight) {
+                minVideoWidth = size.width;
+                minVideoHeight = size.height;
+            }
         }
-        mVideoWidth = videoSizes.get(0).width;
-        mVideoHeight = videoSizes.get(0).height;
+        // Use minimum resolution to avoid that one frame size exceeds file size limit.
+        mVideoWidth = minVideoWidth;
+        mVideoHeight = minVideoHeight;
     }
 
     private void recordVideoUsingCamera(
@@ -425,8 +432,9 @@
     }
 
     public void testRecordAudioFromAudioSourceUnprocessed() throws Exception {
-        if (!hasMicrophone()) {
-            return; // skip
+        if (!hasMicrophone() || !hasAmrNb()) {
+            MediaUtils.skipTest("no audio codecs or microphone");
+            return;
         }
         mMediaRecorder.setAudioSource(MediaRecorder.AudioSource.UNPROCESSED);
         mMediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.DEFAULT);
@@ -934,13 +942,14 @@
         boolean success = false;
         Surface surface = null;
         int noOfFailure = 0;
-        final float frameRate = getMaxFrameRateForCodec(MediaRecorder.VideoEncoder.H264);
 
         if (!hasH264()) {
             MediaUtils.skipTest("no codecs");
             return true;
         }
 
+        final float frameRate = getMaxFrameRateForCodec(MediaRecorder.VideoEncoder.H264);
+
         try {
             if (persistent) {
                 surface = MediaCodec.createPersistentInputSurface();
diff --git a/tests/tests/media/src/android/media/cts/RoutingTest.java b/tests/tests/media/src/android/media/cts/RoutingTest.java
index 22aaaa3..7614568 100644
--- a/tests/tests/media/src/android/media/cts/RoutingTest.java
+++ b/tests/tests/media/src/android/media/cts/RoutingTest.java
@@ -352,6 +352,11 @@
     }
 
     public void test_audioTrack_getRoutedDevice() {
+        if (!DeviceUtils.hasOutputDevice(mAudioManager)) {
+            Log.i(TAG, "No output devices. Test skipped");
+            return; // nothing to test here
+        }
+
         int bufferSize =
                 AudioTrack.getMinBufferSize(
                     41000,
@@ -415,6 +420,11 @@
             return;
         }
 
+        if (!DeviceUtils.hasInputDevice(mAudioManager)) {
+            Log.i(TAG, "No input devices. Test skipped");
+            return; // nothing to test here
+        }
+
         int bufferSize =
                 AudioRecord.getMinBufferSize(
                     41000,
diff --git a/tests/tests/media/src/android/media/cts/VideoDecoderPerfTest.java b/tests/tests/media/src/android/media/cts/VideoDecoderPerfTest.java
index 07f00eb..c6e0578 100644
--- a/tests/tests/media/src/android/media/cts/VideoDecoderPerfTest.java
+++ b/tests/tests/media/src/android/media/cts/VideoDecoderPerfTest.java
@@ -28,6 +28,7 @@
 import android.media.MediaExtractor;
 import android.media.MediaFormat;
 import android.util.Log;
+import android.util.Pair;
 import android.view.Surface;
 
 import com.android.compatibility.common.util.DeviceReportLog;
@@ -60,7 +61,8 @@
     private static final boolean OTHER = false;
 
     private static final int MAX_SIZE_SAMPLES_IN_MEMORY_BYTES = 12 << 20;  // 12MB
-    LinkedList<ByteBuffer> mSamplesInMemory = new LinkedList<ByteBuffer>();
+    // each sample contains the buffer and the PTS offset from the frame index
+    LinkedList<Pair<ByteBuffer, Double>> mSamplesInMemory = new LinkedList<Pair<ByteBuffer, Double>>();
     private MediaFormat mDecInputFormat;
     private MediaFormat mDecOutputFormat;
     private int mBitrate;
@@ -117,6 +119,16 @@
         int trackIndex = extractor.getSampleTrackIndex();
         MediaFormat format = extractor.getTrackFormat(trackIndex);
         String mime = format.getString(MediaFormat.KEY_MIME);
+
+        // use frame rate to calculate PTS offset used for PTS scaling
+        double frameRate = 0.; // default - 0 is used for using zero PTS offset
+        if (format.containsKey(MediaFormat.KEY_FRAME_RATE)) {
+            frameRate = format.getInteger(MediaFormat.KEY_FRAME_RATE);
+        } else if (!mime.equals(MediaFormat.MIMETYPE_VIDEO_VP8)
+                && !mime.equals(MediaFormat.MIMETYPE_VIDEO_VP9)) {
+            fail("need framerate info for video file");
+        }
+
         ByteBuffer[] codecInputBuffers;
         ByteBuffer[] codecOutputBuffers;
 
@@ -125,14 +137,25 @@
             ByteBuffer tmpBuf = ByteBuffer.allocate(w * h * 3 / 2);
             int sampleSize = 0;
             int index = 0;
+            long firstPTS = 0;
+            double presentationOffset = 0.;
             while ((sampleSize = extractor.readSampleData(tmpBuf, 0 /* offset */)) > 0) {
                 if (totalMemory + sampleSize > MAX_SIZE_SAMPLES_IN_MEMORY_BYTES) {
                     break;
                 }
+                if (mSamplesInMemory.size() == 0) {
+                    firstPTS = extractor.getSampleTime();
+                }
                 ByteBuffer copied = ByteBuffer.allocate(sampleSize);
                 copied.put(tmpBuf);
-                mSamplesInMemory.addLast(copied);
+                if (frameRate > 0.) {
+                    // presentation offset is an offset from the frame index
+                    presentationOffset =
+                        (extractor.getSampleTime() - firstPTS) * frameRate / 1e6 - index;
+                }
+                mSamplesInMemory.addLast(Pair.create(copied, presentationOffset));
                 totalMemory += sampleSize;
+                ++index;
                 extractor.advance();
             }
             Log.d(TAG, mSamplesInMemory.size() + " samples in memory for " +
@@ -149,7 +172,7 @@
 
         MediaCodec codec = MediaCodec.createByCodecName(name);
         VideoCapabilities cap = codec.getCodecInfo().getCapabilitiesForType(mime).getVideoCapabilities();
-        int frameRate = cap.getSupportedFrameRatesFor(w, h).getUpper().intValue();
+        frameRate = cap.getSupportedFrameRatesFor(w, h).getUpper();
         codec.configure(format, surface, null /* crypto */, 0 /* flags */);
         codec.start();
         codecInputBuffers = codec.getInputBuffers();
@@ -174,13 +197,14 @@
 
                 if (inputBufIndex >= 0) {
                     ByteBuffer dstBuf = codecInputBuffers[inputBufIndex];
-                    ByteBuffer sample =
+                    // sample contains the buffer and the PTS offset normalized to frame index
+                    Pair<ByteBuffer, Double> sample =
                             mSamplesInMemory.get(sampleIndex++ % mSamplesInMemory.size());
-                    sample.rewind();
-                    int sampleSize = sample.remaining();
-                    dstBuf.put(sample);
-                    // use 120fps to compute pts
-                    long presentationTimeUs = inputNum * 1000000L / frameRate;
+                    sample.first.rewind();
+                    int sampleSize = sample.first.remaining();
+                    dstBuf.put(sample.first);
+                    // use max supported framerate to compute pts
+                    long presentationTimeUs = (long)((inputNum + sample.second) * 1e6 / frameRate);
 
                     long elapsed = System.currentTimeMillis() - start;
                     sawInputEOS = ((++inputNum == TOTAL_FRAMES)
diff --git a/tests/tests/mediastress/preconditions/src/android/mediastress/cts/preconditions/MediaPreparer.java b/tests/tests/mediastress/preconditions/src/android/mediastress/cts/preconditions/MediaPreparer.java
index a780317..13ff24b 100644
--- a/tests/tests/mediastress/preconditions/src/android/mediastress/cts/preconditions/MediaPreparer.java
+++ b/tests/tests/mediastress/preconditions/src/android/mediastress/cts/preconditions/MediaPreparer.java
@@ -102,6 +102,12 @@
     /* Key to retrieve resolution string in metrics upon MediaPreparerListener.testEnded() */
     private static final String RESOLUTION_STRING_KEY = "resolution";
 
+    /*
+     * In the case of MediaPreparer error, the default maximum resolution to push to the device.
+     * Pushing higher resolutions may lead to insufficient storage for installing test APKs.
+     * TODO(aaronholden): When the new detection of max resolution is proven stable, throw
+     * a TargetSetupError when detection results in error
+     */
     protected static final Resolution DEFAULT_MAX_RESOLUTION = new Resolution(480, 360);
 
     protected static final Resolution[] RESOLUTIONS = {
diff --git a/tests/tests/net/src/android/net/cts/LocalSocketTest.java b/tests/tests/net/src/android/net/cts/LocalSocketTest.java
index 77f0a44..0ff4a30 100644
--- a/tests/tests/net/src/android/net/cts/LocalSocketTest.java
+++ b/tests/tests/net/src/android/net/cts/LocalSocketTest.java
@@ -22,12 +22,18 @@
 import android.net.LocalServerSocket;
 import android.net.LocalSocket;
 import android.net.LocalSocketAddress;
+import android.system.Os;
+import android.system.OsConstants;
 
 import java.io.FileDescriptor;
 import java.io.IOException;
 import java.io.InputStream;
 import java.io.OutputStream;
+import java.util.concurrent.Callable;
 import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+import java.util.concurrent.Future;
 import java.util.concurrent.TimeUnit;
 
 public class LocalSocketTest extends TestCase {
@@ -177,58 +183,114 @@
         socket.close();
     }
 
+    // http://b/31205169
+    public void testSetSoTimeout_readTimeout() throws Exception {
+        String address = ADDRESS_PREFIX + "_testSetSoTimeout_readTimeout";
+
+        try (LocalSocketPair socketPair = LocalSocketPair.createConnectedSocketPair(address)) {
+            final LocalSocket clientSocket = socketPair.clientSocket;
+
+            // Set the timeout in millis.
+            int timeoutMillis = 1000;
+            clientSocket.setSoTimeout(timeoutMillis);
+
+            // Avoid blocking the test run if timeout doesn't happen by using a separate thread.
+            Callable<Result> reader = () -> {
+                try {
+                    clientSocket.getInputStream().read();
+                    return Result.noException("Did not block");
+                } catch (IOException e) {
+                    return Result.exception(e);
+                }
+            };
+            // Allow the configured timeout, plus some slop.
+            int allowedTime = timeoutMillis + 2000;
+            Result result = runInSeparateThread(allowedTime, reader);
+
+            // Check the message was a timeout, it's all we have to go on.
+            String expectedMessage = Os.strerror(OsConstants.EAGAIN);
+            result.assertThrewIOException(expectedMessage);
+        }
+    }
+
+    // http://b/31205169
+    public void testSetSoTimeout_writeTimeout() throws Exception {
+        String address = ADDRESS_PREFIX + "_testSetSoTimeout_writeTimeout";
+
+        try (LocalSocketPair socketPair = LocalSocketPair.createConnectedSocketPair(address)) {
+            final LocalSocket clientSocket = socketPair.clientSocket;
+
+            // Set the timeout in millis.
+            int timeoutMillis = 1000;
+            clientSocket.setSoTimeout(timeoutMillis);
+
+            // Set a small buffer size so we know we can flood it.
+            clientSocket.setSendBufferSize(100);
+            final int bufferSize = clientSocket.getSendBufferSize();
+
+            // Avoid blocking the test run if timeout doesn't happen by using a separate thread.
+            Callable<Result> writer = () -> {
+                try {
+                    byte[] toWrite = new byte[bufferSize * 2];
+                    clientSocket.getOutputStream().write(toWrite);
+                    return Result.noException("Did not block");
+                } catch (IOException e) {
+                    return Result.exception(e);
+                }
+            };
+            // Allow the configured timeout, plus some slop.
+            int allowedTime = timeoutMillis + 2000;
+
+            Result result = runInSeparateThread(allowedTime, writer);
+
+            // Check the message was a timeout, it's all we have to go on.
+            String expectedMessage = Os.strerror(OsConstants.EAGAIN);
+            result.assertThrewIOException(expectedMessage);
+        }
+    }
+
     public void testAvailable() throws Exception {
         String address = ADDRESS_PREFIX + "_testAvailable";
-        LocalServerSocket localServerSocket = new LocalServerSocket(address);
-        LocalSocket clientSocket = new LocalSocket();
 
-        // establish connection between client and server
-        LocalSocketAddress locSockAddr = new LocalSocketAddress(address);
-        clientSocket.connect(locSockAddr);
-        assertTrue(clientSocket.isConnected());
-        LocalSocket serverSocket = localServerSocket.accept();
+        try (LocalSocketPair socketPair = LocalSocketPair.createConnectedSocketPair(address)) {
+            LocalSocket clientSocket = socketPair.clientSocket;
+            LocalSocket serverSocket = socketPair.serverSocket.accept();
 
-        OutputStream clientOutputStream = clientSocket.getOutputStream();
-        InputStream serverInputStream = serverSocket.getInputStream();
-        assertEquals(0, serverInputStream.available());
+            OutputStream clientOutputStream = clientSocket.getOutputStream();
+            InputStream serverInputStream = serverSocket.getInputStream();
+            assertEquals(0, serverInputStream.available());
 
-        byte[] buffer = new byte[50];
-        clientOutputStream.write(buffer);
-        assertEquals(50, serverInputStream.available());
+            byte[] buffer = new byte[50];
+            clientOutputStream.write(buffer);
+            assertEquals(50, serverInputStream.available());
 
-        InputStream clientInputStream = clientSocket.getInputStream();
-        OutputStream serverOutputStream = serverSocket.getOutputStream();
-        assertEquals(0, clientInputStream.available());
-        serverOutputStream.write(buffer);
-        assertEquals(50, serverInputStream.available());
+            InputStream clientInputStream = clientSocket.getInputStream();
+            OutputStream serverOutputStream = serverSocket.getOutputStream();
+            assertEquals(0, clientInputStream.available());
+            serverOutputStream.write(buffer);
+            assertEquals(50, serverInputStream.available());
 
-        clientSocket.close();
-        serverSocket.close();
-        localServerSocket.close();
+            serverSocket.close();
+        }
     }
 
     public void testFlush() throws Exception {
         String address = ADDRESS_PREFIX + "_testFlush";
-        LocalServerSocket localServerSocket = new LocalServerSocket(address);
-        LocalSocket clientSocket = new LocalSocket();
 
-        // establish connection between client and server
-        LocalSocketAddress locSockAddr = new LocalSocketAddress(address);
-        clientSocket.connect(locSockAddr);
-        assertTrue(clientSocket.isConnected());
-        LocalSocket serverSocket = localServerSocket.accept();
+        try (LocalSocketPair socketPair = LocalSocketPair.createConnectedSocketPair(address)) {
+            LocalSocket clientSocket = socketPair.clientSocket;
+            LocalSocket serverSocket = socketPair.serverSocket.accept();
 
-        OutputStream clientOutputStream = clientSocket.getOutputStream();
-        InputStream serverInputStream = serverSocket.getInputStream();
-        testFlushWorks(clientOutputStream, serverInputStream);
+            OutputStream clientOutputStream = clientSocket.getOutputStream();
+            InputStream serverInputStream = serverSocket.getInputStream();
+            testFlushWorks(clientOutputStream, serverInputStream);
 
-        OutputStream serverOutputStream = serverSocket.getOutputStream();
-        InputStream clientInputStream = clientSocket.getInputStream();
-        testFlushWorks(serverOutputStream, clientInputStream);
+            OutputStream serverOutputStream = serverSocket.getOutputStream();
+            InputStream clientInputStream = clientSocket.getInputStream();
+            testFlushWorks(serverOutputStream, clientInputStream);
 
-        clientSocket.close();
-        serverSocket.close();
-        localServerSocket.close();
+            serverSocket.close();
+        }
     }
 
     private void testFlushWorks(OutputStream outputStream, InputStream inputStream)
@@ -296,4 +358,64 @@
             assertEquals(expected, bytesRead);
         }
     }
+
+    private static class Result {
+        private final String type;
+        private final Exception e;
+
+        private Result(String type, Exception e) {
+            this.type = type;
+            this.e = e;
+        }
+
+        static Result noException(String description) {
+            return new Result(description, null);
+        }
+
+        static Result exception(Exception e) {
+            return new Result(e.getClass().getName(), e);
+        }
+
+        void assertThrewIOException(String expectedMessage) {
+            assertEquals("Unexpected result type", IOException.class.getName(), type);
+            assertEquals("Unexpected exception message", expectedMessage, e.getMessage());
+        }
+    }
+
+    private static Result runInSeparateThread(int allowedTime, final Callable<Result> callable)
+            throws Exception {
+        ExecutorService service = Executors.newSingleThreadScheduledExecutor();
+        Future<Result> future = service.submit(callable);
+        Result result = future.get(allowedTime, TimeUnit.MILLISECONDS);
+        if (!future.isDone()) {
+            fail("Worker thread appears blocked");
+        }
+        return result;
+    }
+
+    private static class LocalSocketPair implements AutoCloseable {
+        static LocalSocketPair createConnectedSocketPair(String address) throws Exception {
+            LocalServerSocket localServerSocket = new LocalServerSocket(address);
+            final LocalSocket clientSocket = new LocalSocket();
+
+            // Establish connection between client and server
+            LocalSocketAddress locSockAddr = new LocalSocketAddress(address);
+            clientSocket.connect(locSockAddr);
+            assertTrue(clientSocket.isConnected());
+            return new LocalSocketPair(localServerSocket, clientSocket);
+        }
+
+        final LocalServerSocket serverSocket;
+        final LocalSocket clientSocket;
+
+        LocalSocketPair(LocalServerSocket serverSocket, LocalSocket clientSocket) {
+            this.serverSocket = serverSocket;
+            this.clientSocket = clientSocket;
+        }
+
+        public void close() throws Exception {
+            serverSocket.close();
+            clientSocket.close();
+        }
+    }
 }
diff --git a/tests/tests/os/src/android/os/cts/AsyncTaskTest.java b/tests/tests/os/src/android/os/cts/AsyncTaskTest.java
index efd1eed..1c9aaba 100644
--- a/tests/tests/os/src/android/os/cts/AsyncTaskTest.java
+++ b/tests/tests/os/src/android/os/cts/AsyncTaskTest.java
@@ -16,11 +16,14 @@
 
 package android.os.cts;
 
+import android.support.annotation.NonNull;
 
 import android.cts.util.PollingCheck;
 import android.os.AsyncTask;
 import android.test.InstrumentationTestCase;
 
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.Executor;
 import java.util.concurrent.TimeUnit;
 
 public class AsyncTaskTest extends InstrumentationTestCase {
@@ -30,7 +33,8 @@
     private static final long DURATION = 2000;
     private static final String[] PARAM = { "Test" };
 
-    private static MyAsyncTask mAsyncTask;
+    private static AsyncTask mAsyncTask;
+    private static MyAsyncTask mMyAsyncTask;
 
     public void testAsyncTask() throws Throwable {
         doTestAsyncTask(0);
@@ -43,51 +47,51 @@
     private void doTestAsyncTask(final long timeout) throws Throwable {
         startAsyncTask();
         if (timeout > 0) {
-            assertEquals(RESULT, mAsyncTask.get(DURATION, TimeUnit.MILLISECONDS).longValue());
+            assertEquals(RESULT, mMyAsyncTask.get(DURATION, TimeUnit.MILLISECONDS).longValue());
         } else {
-            assertEquals(RESULT, mAsyncTask.get().longValue());
+            assertEquals(RESULT, mMyAsyncTask.get().longValue());
         }
 
         // wait for the task to finish completely (including onPostResult()).
         new PollingCheck(DURATION) {
             protected boolean check() {
-                return mAsyncTask.getStatus() == AsyncTask.Status.FINISHED;
+                return mMyAsyncTask.getStatus() == AsyncTask.Status.FINISHED;
             }
         }.run();
 
-        assertTrue(mAsyncTask.isOnPreExecuteCalled);
-        assert(mAsyncTask.hasRun);
-        assertEquals(PARAM.length, mAsyncTask.parameters.length);
+        assertTrue(mMyAsyncTask.isOnPreExecuteCalled);
+        assert(mMyAsyncTask.hasRun);
+        assertEquals(PARAM.length, mMyAsyncTask.parameters.length);
         for (int i = 0; i < PARAM.length; i++) {
-            assertEquals(PARAM[i], mAsyncTask.parameters[i]);
+            assertEquals(PARAM[i], mMyAsyncTask.parameters[i]);
         }
         // even though the background task has run, the onPostExecute() may not have been
         // executed yet and the progress update may not have been processed. Wait until the task
         // has completed, which guarantees that onPostExecute has been called.
 
-        assertEquals(RESULT, mAsyncTask.postResult.longValue());
-        assertEquals(AsyncTask.Status.FINISHED, mAsyncTask.getStatus());
+        assertEquals(RESULT, mMyAsyncTask.postResult.longValue());
+        assertEquals(AsyncTask.Status.FINISHED, mMyAsyncTask.getStatus());
 
-        if (mAsyncTask.exception != null) {
-            throw mAsyncTask.exception;
+        if (mMyAsyncTask.exception != null) {
+            throw mMyAsyncTask.exception;
         }
 
         // wait for progress update to be processed (happens asynchronously)
         new PollingCheck(DURATION) {
             protected boolean check() {
-                return mAsyncTask.updateValue != null;
+                return mMyAsyncTask.updateValue != null;
             }
         }.run();
-        assertEquals(UPDATE_VALUE.length, mAsyncTask.updateValue.length);
+        assertEquals(UPDATE_VALUE.length, mMyAsyncTask.updateValue.length);
         for (int i = 0; i < UPDATE_VALUE.length; i++) {
-            assertEquals(UPDATE_VALUE[i], mAsyncTask.updateValue[i]);
+            assertEquals(UPDATE_VALUE[i], mMyAsyncTask.updateValue[i]);
         }
 
         runTestOnUiThread(new Runnable() {
             public void run() {
                 try {
                     // task should not be allowed to execute twice
-                    mAsyncTask.execute(PARAM);
+                    mMyAsyncTask.execute(PARAM);
                     fail("Failed to throw exception!");
                 } catch (IllegalStateException e) {
                     // expected
@@ -99,44 +103,122 @@
     public void testCancelWithInterrupt() throws Throwable {
         startAsyncTask();
         Thread.sleep(COMPUTE_TIME / 2);
-        assertTrue(mAsyncTask.cancel(true));
+        assertTrue(mMyAsyncTask.cancel(true));
         // already cancelled
-        assertFalse(mAsyncTask.cancel(true));
+        assertFalse(mMyAsyncTask.cancel(true));
         Thread.sleep(DURATION);
-        assertTrue(mAsyncTask.isCancelled());
-        assertTrue(mAsyncTask.isOnCancelledCalled);
-        assertNotNull(mAsyncTask.exception);
-        assertTrue(mAsyncTask.exception instanceof InterruptedException);
+        assertTrue(mMyAsyncTask.isCancelled());
+        assertTrue(mMyAsyncTask.isOnCancelledCalled);
+        assertNotNull(mMyAsyncTask.exception);
+        assertTrue(mMyAsyncTask.exception instanceof InterruptedException);
     }
 
     public void testCancel() throws Throwable {
         startAsyncTask();
         Thread.sleep(COMPUTE_TIME / 2);
-        assertTrue(mAsyncTask.cancel(false));
+        assertTrue(mMyAsyncTask.cancel(false));
         // already cancelled
-        assertFalse(mAsyncTask.cancel(false));
+        assertFalse(mMyAsyncTask.cancel(false));
         Thread.sleep(DURATION);
-        assertTrue(mAsyncTask.isCancelled());
-        assertTrue(mAsyncTask.isOnCancelledCalled);
-        assertNull(mAsyncTask.exception);
+        assertTrue(mMyAsyncTask.isCancelled());
+        assertTrue(mMyAsyncTask.isOnCancelledCalled);
+        assertNull(mMyAsyncTask.exception);
     }
 
     public void testCancelTooLate() throws Throwable {
         startAsyncTask();
         Thread.sleep(DURATION);
-        assertFalse(mAsyncTask.cancel(false));
-        assertTrue(mAsyncTask.isCancelled());
-        assertFalse(mAsyncTask.isOnCancelledCalled);
-        assertNull(mAsyncTask.exception);
+        assertFalse(mMyAsyncTask.cancel(false));
+        assertTrue(mMyAsyncTask.isCancelled());
+        assertFalse(mMyAsyncTask.isOnCancelledCalled);
+        assertNull(mMyAsyncTask.exception);
+    }
+
+    public void testCancellationWithException() throws Throwable {
+        final CountDownLatch readyToCancel = new CountDownLatch(1);
+        final CountDownLatch readyToThrow = new CountDownLatch(1);
+        final CountDownLatch calledOnCancelled = new CountDownLatch(1);
+        runTestOnUiThread(new Runnable() {
+            @Override
+            public void run() {
+                mAsyncTask = new AsyncTask() {
+                    @Override
+                    protected Object doInBackground(Object... params) {
+                        readyToCancel.countDown();
+                        try {
+                            readyToThrow.await();
+                        } catch (InterruptedException e) {}
+                        // This exception is expected to be caught and ignored
+                        throw new RuntimeException();
+                    }
+
+                    @Override
+                    protected void onCancelled(Object o) {
+                        calledOnCancelled.countDown();
+                    }
+                };
+            }
+        });
+
+        mAsyncTask.execute();
+        if (!readyToCancel.await(5, TimeUnit.SECONDS)) {
+            fail("Test failure: doInBackground did not run in time.");
+        }
+        mAsyncTask.cancel(false);
+        readyToThrow.countDown();
+        if (!calledOnCancelled.await(5, TimeUnit.SECONDS)) {
+            fail("onCancelled not called!");
+        }
+    }
+
+    public void testException() throws Throwable {
+        final CountDownLatch calledOnCancelled = new CountDownLatch(1);
+        runTestOnUiThread(new Runnable() {
+            @Override
+            public void run() {
+                mAsyncTask = new AsyncTask() {
+                    @Override
+                    protected Object doInBackground(Object... params) {
+                        throw new RuntimeException();
+                    }
+
+                    @Override
+                    protected void onPostExecute(Object o) {
+                        fail("onPostExecute should not be called");
+                    }
+
+                    @Override
+                    protected void onCancelled(Object o) {
+                        calledOnCancelled.countDown();
+                    }
+                };
+            }
+        });
+
+        mAsyncTask.executeOnExecutor(new Executor() {
+            @Override
+            public void execute(@NonNull Runnable command) {
+                try {
+                    command.run();
+                    fail("Exception not thrown");
+                } catch (Throwable tr) {
+                    // expected
+                }
+            }
+        });
+
+        if (!calledOnCancelled.await(5, TimeUnit.SECONDS)) {
+            fail("onCancelled not called!");
+        }
     }
 
     private void startAsyncTask() throws Throwable {
         runTestOnUiThread(new Runnable() {
             public void run() {
-                mAsyncTask = new MyAsyncTask();
-                assertEquals(AsyncTask.Status.PENDING, mAsyncTask.getStatus());
-                assertEquals(mAsyncTask, mAsyncTask.execute(PARAM));
-                assertEquals(AsyncTask.Status.RUNNING, mAsyncTask.getStatus());
+                mMyAsyncTask = new MyAsyncTask();
+                assertEquals(AsyncTask.Status.PENDING, mMyAsyncTask.getStatus());
+                assertEquals(mMyAsyncTask, mMyAsyncTask.execute(PARAM));
+                assertEquals(AsyncTask.Status.RUNNING, mMyAsyncTask.getStatus());
             }
         });
     }
diff --git a/tests/tests/os/src/android/os/cts/BuildVersionTest.java b/tests/tests/os/src/android/os/cts/BuildVersionTest.java
index 75c8db5..e39249b 100644
--- a/tests/tests/os/src/android/os/cts/BuildVersionTest.java
+++ b/tests/tests/os/src/android/os/cts/BuildVersionTest.java
@@ -30,7 +30,7 @@
 
     private static final String LOG_TAG = "BuildVersionTest";
     private static final Set<String> EXPECTED_RELEASES =
-            new HashSet<String>(Arrays.asList("7.1"));
+            new HashSet<String>(Arrays.asList("7.1","7.1.1","7.1.2"));
     private static final int EXPECTED_SDK = 25;
     private static final String EXPECTED_BUILD_VARIANT = "user";
     private static final String EXPECTED_TAG = "release-keys";
diff --git a/tests/tests/permission/src/android/permission/cts/FileSystemPermissionTest.java b/tests/tests/permission/src/android/permission/cts/FileSystemPermissionTest.java
index 698896b..277198e 100644
--- a/tests/tests/permission/src/android/permission/cts/FileSystemPermissionTest.java
+++ b/tests/tests/permission/src/android/permission/cts/FileSystemPermissionTest.java
@@ -315,8 +315,6 @@
             assertFalse(f.canRead());
             assertFalse(f.canWrite());
             assertFalse(f.canExecute());
-            assertFileOwnedBy(f, "root");
-            assertFileOwnedByGroup(f, "root");
         }
 
         if (supported_64 || supported) {
@@ -325,8 +323,6 @@
             assertFalse(f.canRead());
             assertFalse(f.canWrite());
             assertFalse(f.canExecute());
-            assertFileOwnedBy(f, "root");
-            assertFileOwnedByGroup(f, "root");
         }
     }
 
diff --git a/tests/tests/permission2/src/android/permission2/cts/PermissionPolicyTest.java b/tests/tests/permission2/src/android/permission2/cts/PermissionPolicyTest.java
index 1c9c6f1..1e72ad1 100644
--- a/tests/tests/permission2/src/android/permission2/cts/PermissionPolicyTest.java
+++ b/tests/tests/permission2/src/android/permission2/cts/PermissionPolicyTest.java
@@ -103,15 +103,8 @@
             // OEMs cannot change permission protection flags
             final int expectedProtectionFlags = expectedPermission.protectionLevel
                     & PermissionInfo.PROTECTION_MASK_FLAGS;
-            int declaredProtectionFlags = declaredPermission.protectionLevel
+            final int declaredProtectionFlags = declaredPermission.protectionLevel
                     & PermissionInfo.PROTECTION_MASK_FLAGS;
-            // Device makers are allowed to backport the framework fix on nougat mr1
-            // https://android.googlesource.com/platform/frameworks/base/+/b2457c
-            if (expectedPermissionName.equals("android.permission.PEERS_MAC_ADDRESS")
-                && declaredProtectionFlags == 0)
-            {
-                declaredProtectionFlags = PermissionInfo.PROTECTION_FLAG_SETUP;
-            }
             assertEquals("Permission " + expectedPermissionName + " invalid enforced protection"
                     + " level flags", expectedProtectionFlags, declaredProtectionFlags);
 
diff --git a/tests/tests/security/src/android/security/cts/AslrTest.java b/tests/tests/security/src/android/security/cts/AslrTest.java
index 774df87..535224f 100644
--- a/tests/tests/security/src/android/security/cts/AslrTest.java
+++ b/tests/tests/security/src/android/security/cts/AslrTest.java
@@ -47,21 +47,24 @@
         ParcelFileDescriptor pfd = getInstrumentation().getUiAutomation()
                 .executeShellCommand("/system/bin/cat /proc/self/maps");
 
-        BufferedReader reader = new BufferedReader(
-                new InputStreamReader(new FileInputStream(pfd.getFileDescriptor())));
+        String result = null;
+        try (BufferedReader reader = new BufferedReader(
+                new InputStreamReader(new ParcelFileDescriptor.AutoCloseInputStream(pfd)))) {
+            Pattern p = Pattern.compile("^([a-f0-9]+)\\-.+\\[" + mappingName + "\\]$");
+            String line;
 
-        Pattern p = Pattern.compile("^([a-f0-9]+)\\-.+\\[" + mappingName + "\\]$");
-        String line;
+            while ((line = reader.readLine()) != null) {
+                // Even after a match is found, read until the end to clean up the pipe.
+                if (result != null) continue;
 
-        while ((line = reader.readLine()) != null) {
-            Matcher m = p.matcher(line);
+                Matcher m = p.matcher(line);
 
-            if (m.matches()) {
-                return m.group(1);
+                if (m.matches()) {
+                    result = m.group(1);
+                }
             }
         }
-
-        return null;
+        return result;
     }
 
     private int calculateEntropyBits(String mappingName) throws Exception {
diff --git a/tests/tests/security/src/android/security/cts/BrowserTest.java b/tests/tests/security/src/android/security/cts/BrowserTest.java
index bb0b1c1..e6039b8 100644
--- a/tests/tests/security/src/android/security/cts/BrowserTest.java
+++ b/tests/tests/security/src/android/security/cts/BrowserTest.java
@@ -176,7 +176,13 @@
 
             // do a file request
             intent.setData(Uri.fromFile(htmlFile));
-            mContext.startActivity(intent);
+
+            try {
+                mContext.startActivity(intent);
+            } catch (SecurityException e) {
+                // If browser activity cannot be started, skip the test.
+                continue;
+            }
 
             /*
              * Wait 5 seconds for the browser to contact the server, but
diff --git a/tests/tests/security/src/android/security/cts/DeviceIdleControllerTest.java b/tests/tests/security/src/android/security/cts/DeviceIdleControllerTest.java
new file mode 100644
index 0000000..0b183aa
--- /dev/null
+++ b/tests/tests/security/src/android/security/cts/DeviceIdleControllerTest.java
@@ -0,0 +1,68 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.security.cts;
+
+import android.os.Bundle;
+import android.os.Handler;
+import android.os.IBinder;
+import android.os.PowerManager;
+import android.os.RemoteException;
+import android.os.ResultReceiver;
+import android.os.ServiceManager;
+import android.test.AndroidTestCase;
+
+import java.io.FileDescriptor;
+
+/**
+ * Check past exploits of DeviceIdleController.
+ */
+public class DeviceIdleControllerTest extends AndroidTestCase {
+    int mResult;
+
+    /**
+     * Verify that the command line interface can not be used to add an app to the whitelist.
+     */
+    public void testAddWhiteList() {
+        final IBinder service = ServiceManager.getService("deviceidle");
+        final Object mSync = new Object();
+        mResult = 0;
+        try {
+            service.shellCommand(FileDescriptor.in, FileDescriptor.out, FileDescriptor.err,
+                    new String[]{"whitelist", "+" + mContext.getPackageName()},
+                    new ResultReceiver(null) {
+                        @Override
+                        protected void onReceiveResult(int resultCode, Bundle resultData) {
+                            mResult = resultCode;
+                            synchronized (mSync) {
+                                mSync.notifyAll();
+                            }
+                        }
+                    });
+        } catch (RemoteException e) {
+        }
+        try {
+            synchronized (mSync) {
+                mSync.wait();
+            }
+        } catch (InterruptedException e) {
+        }
+        assertEquals(-1, mResult);
+        PowerManager pm = mContext.getSystemService(PowerManager.class);
+        assertFalse(pm.isIgnoringBatteryOptimizations(mContext.getPackageName()));
+    }
+}
+
diff --git a/tests/tests/security/src/android/security/cts/STKFrameworkTest.java b/tests/tests/security/src/android/security/cts/STKFrameworkTest.java
index 1b3674d..0e8b04e 100644
--- a/tests/tests/security/src/android/security/cts/STKFrameworkTest.java
+++ b/tests/tests/security/src/android/security/cts/STKFrameworkTest.java
@@ -22,12 +22,12 @@
 import android.test.AndroidTestCase;
 
 public class STKFrameworkTest extends AndroidTestCase {
-   private boolean mHasTelephony;
+    private boolean mHasTelephony;
 
-   @Override
+    @Override
     protected void setUp() throws Exception {
         super.setUp();
-	mHasTelephony = getContext().getPackageManager().hasSystemFeature(
+        mHasTelephony = getContext().getPackageManager().hasSystemFeature(
                 PackageManager.FEATURE_TELEPHONY);
     }
 
@@ -43,10 +43,10 @@
     @SecurityTest
     public void testInterceptedSIMCommandsToTelephony() {
         if (!mHasTelephony) {
-		return;
-	}
+            return;
+        }
 
-	Intent intent = new Intent();
+        Intent intent = new Intent();
         intent.setAction("android.intent.action.stk.command");
         intent.putExtra("STK CMD", "test");
         ComponentName cn =
diff --git a/tests/tests/security/src/android/security/cts/StagefrightTest.java b/tests/tests/security/src/android/security/cts/StagefrightTest.java
index b4bd3f8..4a401b1 100644
--- a/tests/tests/security/src/android/security/cts/StagefrightTest.java
+++ b/tests/tests/security/src/android/security/cts/StagefrightTest.java
@@ -119,14 +119,17 @@
         doStagefrightTest(R.raw.bug_22771132);
     }
 
+    @SecurityTest
     public void testStagefright_bug_21443020() throws Exception {
         doStagefrightTest(R.raw.bug_21443020_webm);
     }
 
+    @SecurityTest
     public void testStagefright_bug_34360591() throws Exception {
         doStagefrightTest(R.raw.bug_34360591);
     }
 
+    @SecurityTest
     public void testStagefright_bug_35763994() throws Exception {
         doStagefrightTest(R.raw.bug_35763994);
     }
@@ -216,6 +219,7 @@
         doStagefrightTest(R.raw.cve_2015_3864_b23034759);
     }
 
+    @SecurityTest
     public void testStagefright_cve_2015_6598() throws Exception {
         doStagefrightTest(R.raw.cve_2015_6598);
     }
@@ -346,26 +350,32 @@
         doStagefrightTest(R.raw.bug_25812590);
     }
 
+    @SecurityTest
     public void testStagefright_cve_2015_6600() throws Exception {
         doStagefrightTest(R.raw.cve_2015_6600);
     }
 
+    @SecurityTest
     public void testStagefright_cve_2015_6603() throws Exception {
         doStagefrightTest(R.raw.cve_2015_6603);
     }
 
+    @SecurityTest
     public void testStagefright_cve_2015_6604() throws Exception {
         doStagefrightTest(R.raw.cve_2015_6604);
     }
 
+    @SecurityTest
     public void testStagefright_cve_2015_3871() throws Exception {
         doStagefrightTest(R.raw.cve_2015_3871);
     }
 
+    @SecurityTest
     public void testStagefright_bug_26070014() throws Exception {
         doStagefrightTest(R.raw.bug_26070014);
     }
 
+    @SecurityTest
     public void testStagefright_bug_32915871() throws Exception {
         doStagefrightTest(R.raw.bug_32915871);
     }
diff --git a/tests/tests/shortcutmanager/src/android/content/pm/cts/shortcutmanager/ShortcutLaunchedActivity.java b/tests/tests/shortcutmanager/src/android/content/pm/cts/shortcutmanager/ShortcutLaunchedActivity.java
index 61f94d4..fdedc45 100644
--- a/tests/tests/shortcutmanager/src/android/content/pm/cts/shortcutmanager/ShortcutLaunchedActivity.java
+++ b/tests/tests/shortcutmanager/src/android/content/pm/cts/shortcutmanager/ShortcutLaunchedActivity.java
@@ -22,7 +22,9 @@
 import android.util.Log;
 
 import java.util.ArrayList;
+import java.util.Arrays;
 import java.util.List;
+import java.util.Objects;
 import java.util.concurrent.atomic.AtomicInteger;
 
 /**
@@ -36,9 +38,14 @@
 
     private final int mInstanceId = sNextInstanceId.getAndIncrement();
 
-    // @GuardedBy("sReceivedIntents")
+    private static final Object sLock = new Object();
+
+    // @GuardedBy("sLock")
     private static final ArrayList<Intent> sReceivedIntents = new ArrayList<>();
 
+    // @GuardedBy("sLock")
+    private static final ArrayList<String> sExpectedVisibleOrder = new ArrayList<>();
+
     private Handler mHandler = new Handler();
 
     private Intent mIntentToAdd;
@@ -48,6 +55,10 @@
                 mInstanceId, action, getIntent()));
     }
 
+    public ShortcutLaunchedActivity() {
+        log("ctor");
+    }
+
     @Override
     protected void onCreate(Bundle savedInstanceState) {
         super.onCreate(savedInstanceState);
@@ -63,22 +74,27 @@
 
         log("onResume");
 
-        synchronized (sReceivedIntents) {
+        synchronized (sLock) {
+            if (!Objects.equals(getIntent().getAction(), sExpectedVisibleOrder.get(0))) {
+                log("Not my turn yet.");
+                return;
+            }
+            sExpectedVisibleOrder.remove(0);
+
             // Make sure we only add it once, ever.
             if (mIntentToAdd != null) {
                 sReceivedIntents.add(new Intent(getIntent()));
                 mIntentToAdd = null;
             }
         }
-        mHandler.post(() -> {
-            onBackPressed();
-        });
+        finish();
     }
 
     @Override
-    public void onBackPressed() {
-        log("onBackPressed");
-        super.onBackPressed();
+    protected void onPause() {
+        log("onPause");
+
+        super.onPause();
     }
 
     @Override
@@ -88,14 +104,17 @@
         super.onDestroy();
     }
 
-    public static void clearIntents() {
-        synchronized (sReceivedIntents) {
+    public static void setExpectedOrder(String[] actions) {
+        synchronized (sLock) {
             sReceivedIntents.clear();
+
+            sExpectedVisibleOrder.clear();
+            sExpectedVisibleOrder.addAll(Arrays.asList(actions));
         }
     }
 
     public static List<Intent> getIntents() {
-        synchronized (sReceivedIntents) {
+        synchronized (sLock) {
             return new ArrayList(sReceivedIntents);
         }
     }
diff --git a/tests/tests/shortcutmanager/src/android/content/pm/cts/shortcutmanager/ShortcutManagerStartShortcutTest.java b/tests/tests/shortcutmanager/src/android/content/pm/cts/shortcutmanager/ShortcutManagerStartShortcutTest.java
index e80b66e..9cf1f89 100644
--- a/tests/tests/shortcutmanager/src/android/content/pm/cts/shortcutmanager/ShortcutManagerStartShortcutTest.java
+++ b/tests/tests/shortcutmanager/src/android/content/pm/cts/shortcutmanager/ShortcutManagerStartShortcutTest.java
@@ -20,7 +20,6 @@
 import static com.android.server.pm.shortcutmanagertest.ShortcutManagerTestUtils.retryUntil;
 import static com.android.server.pm.shortcutmanagertest.ShortcutManagerTestUtils.setDefaultLauncher;
 
-import android.app.ActivityOptions;
 import android.content.ActivityNotFoundException;
 import android.content.ComponentName;
 import android.content.Context;
@@ -29,8 +28,6 @@
 import android.os.Bundle;
 import android.test.suitebuilder.annotation.SmallTest;
 
-import org.junit.internal.runners.statements.ExpectException;
-
 import java.util.List;
 
 @SmallTest
@@ -45,14 +42,16 @@
     }
 
     private List<Intent> launchShortcutAndGetIntents(Context launcher, Context client,
-            String id, int expectedNumIntents) {
-        return launchShortcutAndGetIntents(launcher, client, id, expectedNumIntents, null, null);
+            String id, int expectedNumIntents, String[] expectedActions) {
+        return launchShortcutAndGetIntents(launcher, client, id, expectedNumIntents, null, null,
+                expectedActions);
     }
 
     private List<Intent> launchShortcutAndGetIntents(Context launcher, Context client,
-            String id, int expectedNumIntents, Rect rect, Bundle options) {
+            String id, int expectedNumIntents, Rect rect, Bundle options,
+            String[] expectedActions) {
 
-        ShortcutLaunchedActivity.clearIntents();
+        ShortcutLaunchedActivity.setExpectedOrder(expectedActions);
 
         runWithCaller(launcher, () -> {
             getLauncherApps().startShortcut(client.getPackageName(), id, rect, options,
@@ -65,8 +64,10 @@
         return ShortcutLaunchedActivity.getIntents();
     }
 
-    private void assertShortcutStarts(Context launcher, Context client, String id) {
-        final List<Intent> launched = launchShortcutAndGetIntents(launcher, client, id, 1);
+    private void assertShortcutStarts(Context launcher, Context client, String id,
+            String[] expectedActions) {
+        final List<Intent> launched = launchShortcutAndGetIntents(launcher, client, id, 1,
+                expectedActions);
         assertTrue(launched.size() > 0);
     }
 
@@ -81,6 +82,9 @@
         });
     }
 
+    private static final String[] EXPECTED_ACTIONS_SINGLE = new String[]{Intent.ACTION_MAIN};
+    private static final String[] EXPECTED_ACTIONS_MULTI = new String[]{"a3", "a2", "a1"};
+
     /**
      * Start a single activity.
      */
@@ -100,7 +104,7 @@
         });
 
         List<Intent> launched = launchShortcutAndGetIntents(mLauncherContext1, mPackageContext1,
-                "s1", 1);
+                "s1", 1, EXPECTED_ACTIONS_SINGLE);
         assertEquals(1, launched.size());
         assertEquals(Intent.ACTION_MAIN, launched.get(0).getAction());
         assertTrue((launched.get(0).getFlags() & Intent.FLAG_ACTIVITY_NO_ANIMATION) != 0);
@@ -132,7 +136,7 @@
         });
 
         List<Intent> launched = launchShortcutAndGetIntents(mLauncherContext1, mPackageContext1,
-                "s1", 3);
+                "s1", 3, EXPECTED_ACTIONS_MULTI);
         assertEquals(3, launched.size());
 
         Intent i = launched.get(2);
@@ -164,7 +168,8 @@
         setDefaultLauncher(getInstrumentation(), mLauncherContext2);
 
         // L2 can start it.
-        assertShortcutStarts(mLauncherContext2, mPackageContext1, "s1");
+        assertShortcutStarts(mLauncherContext2, mPackageContext1, "s1",
+                EXPECTED_ACTIONS_SINGLE);
 
         // L1 no longer can start it.
         assertShortcutCantStart(mLauncherContext1, mPackageContext1, "s1",
@@ -225,7 +230,7 @@
         });
 
         // Should still be launchable.
-        assertShortcutStarts(mLauncherContext1, mPackageContext1, "s1");
+        assertShortcutStarts(mLauncherContext1, mPackageContext1, "s1", EXPECTED_ACTIONS_SINGLE);
     }
 
     public void testPinnedShortcut_differentLauncher() {
@@ -249,7 +254,7 @@
         setDefaultLauncher(getInstrumentation(), mLauncherContext2);
 
         // L2 can now launch it.
-        assertShortcutStarts(mLauncherContext2, mPackageContext1, "s1");
+        assertShortcutStarts(mLauncherContext2, mPackageContext1, "s1", EXPECTED_ACTIONS_SINGLE);
 
         // Then remove it.
         runWithCaller(mPackageContext1, () -> {
@@ -261,14 +266,14 @@
                 ActivityNotFoundException.class);
 
         // But launcher 1 can still launch it too, because it's pinned by this launcher.
-        assertShortcutStarts(mLauncherContext1, mPackageContext1, "s1");
+        assertShortcutStarts(mLauncherContext1, mPackageContext1, "s1", EXPECTED_ACTIONS_SINGLE);
     }
 
     public void testStartSingleWithOptions() {
         testStartSingle();
 
         List<Intent> launched = launchShortcutAndGetIntents(mLauncherContext1, mPackageContext1,
-                "s1", 1, new Rect(1, 1, 2, 2), new Bundle());
+                "s1", 1, new Rect(1, 1, 2, 2), new Bundle(), EXPECTED_ACTIONS_SINGLE);
 
         Intent i = launched.get(0);
         assertEquals(1, i.getSourceBounds().left);
@@ -280,7 +285,7 @@
         testStartMultiple();
 
         List<Intent> launched = launchShortcutAndGetIntents(mLauncherContext1, mPackageContext1,
-                "s1", 3, new Rect(1, 1, 2, 2), new Bundle());
+                "s1", 3, new Rect(1, 1, 2, 2), new Bundle(), EXPECTED_ACTIONS_MULTI);
 
         Intent i = launched.get(2);
         assertEquals(1, i.getSourceBounds().left);
@@ -309,7 +314,7 @@
         assertExpectException(
                 ActivityNotFoundException.class, "Shortcut could not be started", () -> {
             launchShortcutAndGetIntents(mLauncherContext1, mPackageContext1,
-                    "s1", 1);
+                    "s1", 1, new String[0]);
         });
     }
 
@@ -334,7 +339,7 @@
         assertExpectException(
                 ActivityNotFoundException.class, "Shortcut could not be started", () -> {
                     launchShortcutAndGetIntents(mLauncherContext1, mPackageContext1,
-                            "s1", 1);
+                            "s1", 1, new String[0]);
                 });
     }
 }
diff --git a/tests/tests/shortcutmanager/src/android/content/pm/cts/shortcutmanager/ShortcutManagerUsageTest.java b/tests/tests/shortcutmanager/src/android/content/pm/cts/shortcutmanager/ShortcutManagerUsageTest.java
index aa0ad82..6ca946e 100644
--- a/tests/tests/shortcutmanager/src/android/content/pm/cts/shortcutmanager/ShortcutManagerUsageTest.java
+++ b/tests/tests/shortcutmanager/src/android/content/pm/cts/shortcutmanager/ShortcutManagerUsageTest.java
@@ -101,35 +101,37 @@
             )));
         });
 
-        // Report usage.
-        final long start = System.currentTimeMillis() - USAGE_STATS_RANGE_ALLOWANCE;
-
-        runWithCaller(mPackageContext1, () -> getManager().reportShortcutUsed(id1));
-        runWithCaller(mPackageContext1, () -> getManager().reportShortcutUsed(idManifest));
-        runWithCaller(mPackageContext1, () -> getManager().reportShortcutUsed(idNonexistance));
-
-        runWithCaller(mPackageContext2, () -> getManager().reportShortcutUsed(id3));
-
-        final long end = System.currentTimeMillis() + USAGE_STATS_RANGE_ALLOWANCE;
-
-        // Check the log.
         final UsageStatsManager usm = getTestContext().getSystemService(UsageStatsManager.class);
 
-        // Note it's a bit silly, but because events are populated asynchronously,
-        // we need to wait until the last one is populated.
+        // Report usage.
+        final long start1 = System.currentTimeMillis() - USAGE_STATS_RANGE_ALLOWANCE;
+        runWithCaller(mPackageContext2, () -> getManager().reportShortcutUsed(id3));
+        final long end1 = System.currentTimeMillis() + USAGE_STATS_RANGE_ALLOWANCE;
 
-        retryUntil(() -> hasEvent(usm.queryEvents(start, end),
+        // Check the log.
+        retryUntil(() -> hasEvent(usm.queryEvents(start1, end1),
                 mPackageContext2.getPackageName(), id3), "Events weren't populated");
 
-        assertTrue(hasEvent(usm.queryEvents(start, end),
-                mPackageContext1.getPackageName(), id1));
+        // Report usage.
+        final long start2 = System.currentTimeMillis() - USAGE_STATS_RANGE_ALLOWANCE;
+        runWithCaller(mPackageContext1, () -> getManager().reportShortcutUsed(id1));
+        final long end2 = System.currentTimeMillis() + USAGE_STATS_RANGE_ALLOWANCE;
 
-        assertTrue(hasEvent(usm.queryEvents(start, end),
-                mPackageContext1.getPackageName(), idManifest));
-        assertFalse(hasEvent(usm.queryEvents(start, end),
-                mPackageContext1.getPackageName(), idNonexistance));
+        // Check the log.
+        retryUntil(() -> hasEvent(usm.queryEvents(start2, end2),
+                mPackageContext1.getPackageName(), id1), "Events weren't populated");
 
-        assertTrue(hasEvent(usm.queryEvents(start, end),
-                mPackageContext2.getPackageName(), id3));
+        // Report usage.
+        final long start3 = System.currentTimeMillis() - USAGE_STATS_RANGE_ALLOWANCE;
+        runWithCaller(mPackageContext1, () -> getManager().reportShortcutUsed(idNonexistance));
+        runWithCaller(mPackageContext1, () -> getManager().reportShortcutUsed(idManifest));
+        final long end3 = System.currentTimeMillis() + USAGE_STATS_RANGE_ALLOWANCE;
+
+        // Check the log.
+        retryUntil(() -> hasEvent(usm.queryEvents(start3, end3),
+                mPackageContext1.getPackageName(), idManifest), "Events weren't populated");
+        // Ensure that the nonexistent shortcut is not reported, even after the other one is.
+        assertFalse(hasEvent(usm.queryEvents(start3, end3),
+                    mPackageContext1.getPackageName(), idNonexistance));
     }
 }
diff --git a/tests/tests/speech/src/android/speech/tts/cts/StubTextToSpeechService.java b/tests/tests/speech/src/android/speech/tts/cts/StubTextToSpeechService.java
index 88bdc74..647d79d 100644
--- a/tests/tests/speech/src/android/speech/tts/cts/StubTextToSpeechService.java
+++ b/tests/tests/speech/src/android/speech/tts/cts/StubTextToSpeechService.java
@@ -16,6 +16,7 @@
 package android.speech.tts.cts;
 
 import android.media.AudioFormat;
+import android.os.ConditionVariable;
 import android.speech.tts.SynthesisCallback;
 import android.speech.tts.SynthesisRequest;
 import android.speech.tts.TextToSpeech;
@@ -33,8 +34,8 @@
 public class StubTextToSpeechService extends TextToSpeechService {
     private static final String LOG_TAG = "StubTextToSpeechService";
 
-    // Object that onSynthesizeText will #wait on, if set to non-null
-    public static volatile Object sSynthesizeTextWait;
+    // Object that onSynthesizeText will #block on, if set to non-null
+    public static volatile ConditionVariable sSynthesizeTextWait;
 
     private ArrayList<Locale> supportedLanguages = new ArrayList<Locale>();
     private ArrayList<Locale> supportedCountries = new ArrayList<Locale>();
@@ -79,15 +80,9 @@
             return;
         }
 
-        final Object synthesizeTextWait = sSynthesizeTextWait;
+        final ConditionVariable synthesizeTextWait = sSynthesizeTextWait;
         if (synthesizeTextWait != null) {
-            synchronized (synthesizeTextWait) {
-                try {
-                    synthesizeTextWait.wait(10000);  // 10s timeout
-                } catch (InterruptedException e) {
-                    Log.e(LOG_TAG, "onSynthesizeText wait interrupted", e);
-                }
-            }
+            synthesizeTextWait.block(10000);  // 10s timeout
         }
 
         byte[] data = { 0x01, 0x2 };
diff --git a/tests/tests/speech/src/android/speech/tts/cts/TextToSpeechServiceTest.java b/tests/tests/speech/src/android/speech/tts/cts/TextToSpeechServiceTest.java
index e205cc4..53ef86d 100644
--- a/tests/tests/speech/src/android/speech/tts/cts/TextToSpeechServiceTest.java
+++ b/tests/tests/speech/src/android/speech/tts/cts/TextToSpeechServiceTest.java
@@ -15,6 +15,7 @@
  */
 package android.speech.tts.cts;
 
+import android.os.ConditionVariable;
 import android.os.Environment;
 import android.speech.tts.TextToSpeech;
 import android.test.AndroidTestCase;
@@ -76,7 +77,7 @@
     }
 
     public void testSpeakStop() throws Exception {
-        final Object synthesizeTextWait = new Object();
+        final ConditionVariable synthesizeTextWait = new ConditionVariable();
         StubTextToSpeechService.sSynthesizeTextWait = synthesizeTextWait;
 
         getTts().stop();
@@ -89,9 +90,7 @@
         getTts().stop();
 
         // Wake up the Stubs #onSynthesizeSpeech (one that will be stopped in-progress)
-        synchronized (synthesizeTextWait) {
-          synthesizeTextWait.notify();
-        }
+        synthesizeTextWait.open();
 
         for (int i = 0; i < iterations; i++) {
             assertTrue("speak() stop callback timeout", mTts.waitForStop(
diff --git a/tests/tests/speech/src/android/speech/tts/cts/TextToSpeechTest.java b/tests/tests/speech/src/android/speech/tts/cts/TextToSpeechTest.java
index 43b0fe3..c117745 100644
--- a/tests/tests/speech/src/android/speech/tts/cts/TextToSpeechTest.java
+++ b/tests/tests/speech/src/android/speech/tts/cts/TextToSpeechTest.java
@@ -144,6 +144,9 @@
     }
 
     public void testSpeakStop() throws Exception {
+        if (mTts == null) {
+            return;
+        }
         getTts().stop();
         final int iterations = 20;
         for (int i = 0; i < iterations; i++) {
diff --git a/tests/tests/systemintents/Android.mk b/tests/tests/systemintents/Android.mk
new file mode 100644
index 0000000..1af6702
--- /dev/null
+++ b/tests/tests/systemintents/Android.mk
@@ -0,0 +1,34 @@
+# Copyright (C) 2016 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+LOCAL_PATH:= $(call my-dir)
+
+include $(CLEAR_VARS)
+
+LOCAL_MODULE_TAGS := optional
+
+LOCAL_MODULE_PATH := $(TARGET_OUT_DATA_APPS)
+
+# Tag this module as a cts test artifact
+LOCAL_COMPATIBILITY_SUITE := cts
+
+LOCAL_SRC_FILES := $(call all-java-files-under, src)
+
+LOCAL_PACKAGE_NAME := CtsSystemIntentTestCases
+
+LOCAL_STATIC_JAVA_LIBRARIES := ctstestrunner
+
+LOCAL_SDK_VERSION := test_current
+
+include $(BUILD_CTS_PACKAGE)
diff --git a/tests/tests/systemintents/AndroidManifest.xml b/tests/tests/systemintents/AndroidManifest.xml
new file mode 100644
index 0000000..da0cbac
--- /dev/null
+++ b/tests/tests/systemintents/AndroidManifest.xml
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="utf-8"?>
+
+<!--
+  ~ Copyright (C) 2016 The Android Open Source Project
+  ~
+  ~ Licensed under the Apache License, Version 2.0 (the "License");
+  ~ you may not use this file except in compliance with the License.
+  ~ You may obtain a copy of the License at
+  ~
+  ~      http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing, software
+  ~ distributed under the License is distributed on an "AS IS" BASIS,
+  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  ~ See the License for the specific language governing permissions and
+  ~ limitations under the License
+  -->
+
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+          package="android.systemintents.cts">
+
+    <application>
+        <uses-library android:name="android.test.runner" />
+    </application>
+
+    <instrumentation android:name="android.support.test.runner.AndroidJUnitRunner"
+                     android:targetPackage="android.systemintents.cts"
+                     android:label="System intent tests"/>
+</manifest>
\ No newline at end of file
diff --git a/tests/tests/systemintents/AndroidTest.xml b/tests/tests/systemintents/AndroidTest.xml
new file mode 100644
index 0000000..eceb909
--- /dev/null
+++ b/tests/tests/systemintents/AndroidTest.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  ~ Copyright (C) 2016 The Android Open Source Project
+  ~
+  ~ Licensed under the Apache License, Version 2.0 (the "License");
+  ~ you may not use this file except in compliance with the License.
+  ~ You may obtain a copy of the License at
+  ~
+  ~      http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing, software
+  ~ distributed under the License is distributed on an "AS IS" BASIS,
+  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  ~ See the License for the specific language governing permissions and
+  ~ limitations under the License
+  -->
+<configuration description="Config for CTS system intent test cases">
+    <target_preparer class="com.android.compatibility.common.tradefed.targetprep.ApkInstaller">
+        <option name="cleanup-apks" value="true" />
+        <option name="test-file-name" value="CtsSystemIntentTestCases.apk" />
+    </target_preparer>
+    <test class="com.android.tradefed.testtype.AndroidJUnitTest" >
+        <option name="package" value="android.systemintents.cts" />
+    </test>
+</configuration>
\ No newline at end of file
diff --git a/tests/tests/systemintents/src/android/systemintents/cts/TestSystemIntents.java b/tests/tests/systemintents/src/android/systemintents/cts/TestSystemIntents.java
new file mode 100644
index 0000000..c572629
--- /dev/null
+++ b/tests/tests/systemintents/src/android/systemintents/cts/TestSystemIntents.java
@@ -0,0 +1,102 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.systemintents.cts;
+
+import android.content.Intent;
+import android.content.pm.PackageManager;
+import android.content.pm.ResolveInfo;
+import android.content.res.Configuration;
+import android.net.Uri;
+import android.provider.Settings;
+import android.support.test.filters.MediumTest;
+import android.test.AndroidTestCase;
+import android.util.Log;
+
+import org.junit.Rule;
+import org.junit.Test;
+
+@MediumTest
+public class TestSystemIntents extends AndroidTestCase {
+    /*
+     * List of activity intents defined by the system.  Activities to handle each of these
+     * intents must all exist.
+     *
+     * They are Intents here rather than simply action strings so that the test can
+     * easily accommodate data URIs or similar for correct resolution.
+     *
+     * The flags associated with each intent indicate kinds of device on which the given
+     * UI intent is *not* applicable.
+     */
+
+    private static final int EXCLUDE_TV = 1 << 0;
+    private static final int EXCLUDE_WATCH = 1 << 1;
+    private static final int EXCLUDE_NON_TELEPHONY = 1 << 2;
+
+    class IntentEntry {
+        public int flags;
+        public Intent intent;
+
+        public IntentEntry(int f, Intent i) {
+            flags = f;
+            intent = i;
+        }
+    }
+
+    @Rule
+    private final IntentEntry[] mTestIntents = {
+            /* Settings-namespace intent actions */
+            new IntentEntry(0, new Intent(Settings.ACTION_SETTINGS)),
+            new IntentEntry(0, new Intent(Settings.ACTION_WEBVIEW_SETTINGS)),
+            new IntentEntry(0, new Intent(Settings.ACTION_APPLICATION_DEVELOPMENT_SETTINGS)),
+            new IntentEntry(0, new Intent(Settings.ACTION_IGNORE_BATTERY_OPTIMIZATION_SETTINGS)),
+            new IntentEntry(0, new Intent(Settings.ACTION_REQUEST_IGNORE_BATTERY_OPTIMIZATIONS)
+                    .setData(Uri.parse("package:android.systemintents.cts"))),
+            new IntentEntry(0, new Intent(Settings.ACTION_IGNORE_BACKGROUND_DATA_RESTRICTIONS_SETTINGS)
+                    .setData(Uri.parse("package:android.systemintents.cts"))),
+            new IntentEntry(0, new Intent(Settings.ACTION_HOME_SETTINGS)),
+            new IntentEntry(EXCLUDE_NON_TELEPHONY,
+                    new Intent(Settings.ACTION_APN_SETTINGS)),
+            new IntentEntry(EXCLUDE_TV|EXCLUDE_WATCH,
+                    new Intent(Settings.ACTION_NOTIFICATION_POLICY_ACCESS_SETTINGS))
+    };
+
+    @Test
+    public void testSystemIntents() {
+        final PackageManager pm = getContext().getPackageManager();
+        int productFlags = 0;
+
+        if (pm.hasSystemFeature(PackageManager.FEATURE_LEANBACK)) {
+            productFlags |= EXCLUDE_TV;
+        }
+
+        if (!pm.hasSystemFeature(PackageManager.FEATURE_TELEPHONY)) {
+            productFlags |= EXCLUDE_NON_TELEPHONY;
+        }
+
+        final Configuration config = getContext().getResources().getConfiguration();
+        if ((config.uiMode & Configuration.UI_MODE_TYPE_WATCH) != 0) {
+            productFlags |= EXCLUDE_WATCH;
+        }
+
+        for (IntentEntry e : mTestIntents) {
+            if ((productFlags & e.flags) == 0) {
+                final ResolveInfo ri = pm.resolveActivity(e.intent, PackageManager.MATCH_DEFAULT_ONLY);
+                assertTrue("API intent " + e.intent + " not implemented by any activity", ri != null);
+            }
+        }
+    }
+}
\ No newline at end of file
diff --git a/tests/tests/telecom/src/android/telecom/cts/CallDetailsTest.java b/tests/tests/telecom/src/android/telecom/cts/CallDetailsTest.java
index ff84655..d167249 100644
--- a/tests/tests/telecom/src/android/telecom/cts/CallDetailsTest.java
+++ b/tests/tests/telecom/src/android/telecom/cts/CallDetailsTest.java
@@ -445,6 +445,10 @@
      * {@link android.telecom.Call.Callback#onDetailsChanged(Call, Call.Details)}.
      */
     public void testConnectionRemoveExtras() {
+        if (!mShouldTestTelecom) {
+            return;
+        }
+
         testConnectionPutExtras();
 
         mConnection.removeExtras(Arrays.asList(TEST_EXTRA_KEY));
@@ -458,6 +462,10 @@
      * {@link android.telecom.Call.Callback#onDetailsChanged(Call, Call.Details)}.
      */
     public void testConnectionRemoveExtras2() {
+        if (!mShouldTestTelecom) {
+            return;
+        }
+
         testConnectionPutExtras();
 
         mConnection.removeExtras(TEST_EXTRA_KEY);
diff --git a/tests/tests/telecom/src/android/telecom/cts/MockConference.java b/tests/tests/telecom/src/android/telecom/cts/MockConference.java
index d84610d..302f91f 100644
--- a/tests/tests/telecom/src/android/telecom/cts/MockConference.java
+++ b/tests/tests/telecom/src/android/telecom/cts/MockConference.java
@@ -143,6 +143,10 @@
 
     public void setRemoteConference(RemoteConference remoteConference) {
         mRemoteConference = remoteConference;
+        Bundle bundle = remoteConference.getExtras();
+        if (bundle != null) {
+            this.putExtras(bundle);
+        }
     }
 
     public RemoteConference getRemoteConference() {
@@ -155,6 +159,7 @@
 
     @Override
     public void onExtrasChanged(Bundle extras) {
+        setExtras(extras);
         mOnExtrasChanged.invoke(extras);
     }
 }
diff --git a/tests/tests/telecom/src/android/telecom/cts/RemoteConferenceTest.java b/tests/tests/telecom/src/android/telecom/cts/RemoteConferenceTest.java
index 3246b9c..57654f40 100644
--- a/tests/tests/telecom/src/android/telecom/cts/RemoteConferenceTest.java
+++ b/tests/tests/telecom/src/android/telecom/cts/RemoteConferenceTest.java
@@ -455,7 +455,8 @@
         mRemoteConference.setExtras(extras);
         callbackInvoker.waitForCount(1, WAIT_FOR_STATE_CHANGE_TIMEOUT_MS);
         assertEquals(mRemoteConferenceObject, callbackInvoker.getArgs(0)[0]);
-        assertTrue(areBundlesEqual(extras, (Bundle) callbackInvoker.getArgs(0)[1]));
+        assertTrue(((Bundle) callbackInvoker.getArgs(0)[1]).containsKey(
+                TelecomManager.EXTRA_CALL_DISCONNECT_MESSAGE));
         mRemoteConferenceObject.unregisterCallback(callback);
     }
 
@@ -469,8 +470,9 @@
             remoteConnections.add(((MockConnection)c).getRemoteConnection());
         }
         assertEquals(remoteConnections, remoteConferenceObject.getConnections());
-        assertEquals(remoteConference.getDisconnectCause(), remoteConferenceObject.getDisconnectCause());
-        assertEquals(remoteConference.getExtras(), remoteConferenceObject.getExtras());
+        assertEquals(remoteConference.getDisconnectCause(),
+                remoteConferenceObject.getDisconnectCause());
+        assertTrue(areBundlesEqual(remoteConferenceObject.getExtras(), conference.getExtras()));
     }
 
     private void addRemoteConnectionOutgoingCalls() {
@@ -572,7 +574,7 @@
             setupConnectionServices(managerConnectionService, remoteConnectionService,
                     FLAG_REGISTER | FLAG_ENABLE);
         } catch(Exception e) {
-            fail("Error in setting up the connection services");
+            fail("Error in setting up the connection services: " + e.toString());
         }
 
         placeAndVerifyCall();
diff --git a/tests/tests/telephony/src/android/telephony/cts/SmsMessageTest.java b/tests/tests/telephony/src/android/telephony/cts/SmsMessageTest.java
index 2406ad8..e247775 100644
--- a/tests/tests/telephony/src/android/telephony/cts/SmsMessageTest.java
+++ b/tests/tests/telephony/src/android/telephony/cts/SmsMessageTest.java
@@ -114,7 +114,7 @@
 
         // Test create from null Pdu
         sms = SmsMessage.createFromPdu(null, SmsMessage.FORMAT_3GPP);
-        assertNotNull(sms);
+        assertNull(sms);
 
         // Test create from long Pdu
         pdu = "07912160130310F2040B915121927786F300036060924180008A0DA"
diff --git a/tests/tests/text/src/android/text/method/cts/TouchTest.java b/tests/tests/text/src/android/text/method/cts/TouchTest.java
index 233539c..d9b8aa9 100644
--- a/tests/tests/text/src/android/text/method/cts/TouchTest.java
+++ b/tests/tests/text/src/android/text/method/cts/TouchTest.java
@@ -27,6 +27,7 @@
 import android.util.DisplayMetrics;
 import android.util.TypedValue;
 import android.view.MotionEvent;
+import android.view.ViewGroup;
 import android.widget.TextView;
 
 public class TouchTest extends ActivityInstrumentationTestCase2<CtsActivity> {
@@ -58,7 +59,11 @@
 
         runTestOnUiThread(new Runnable() {
             public void run() {
-                mActivity.setContentView(tv);
+                final float pixelPerSp =
+                    mActivity.getResources().getDisplayMetrics().scaledDensity;
+                // Explicitly set the width so that |LONG_TEXT| causes horizontal scroll.
+                mActivity.setContentView(tv, new ViewGroup.LayoutParams(
+                    (int)(100 * pixelPerSp), ViewGroup.LayoutParams.MATCH_PARENT));
                 tv.setSingleLine(true);
                 tv.setLines(2);
             }
diff --git a/tests/tests/toast/Android.mk b/tests/tests/toast/Android.mk
new file mode 100644
index 0000000..d9f15eb
--- /dev/null
+++ b/tests/tests/toast/Android.mk
@@ -0,0 +1,33 @@
+#
+# Copyright (C) 2016 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+LOCAL_PATH:= $(call my-dir)
+
+include $(CLEAR_VARS)
+
+LOCAL_MODULE_TAGS := tests
+
+LOCAL_MODULE_PATH := $(TARGET_OUT_DATA_APPS)
+
+LOCAL_COMPATIBILITY_SUITE := cts
+
+LOCAL_STATIC_JAVA_LIBRARIES := ctstestrunner android-support-test
+
+LOCAL_SRC_FILES := $(call all-java-files-under, src)
+
+LOCAL_PACKAGE_NAME := CtsToastTestCases
+
+include $(BUILD_CTS_PACKAGE)
+
diff --git a/tests/tests/toast/AndroidManifest.xml b/tests/tests/toast/AndroidManifest.xml
new file mode 100644
index 0000000..1fa71c4
--- /dev/null
+++ b/tests/tests/toast/AndroidManifest.xml
@@ -0,0 +1,33 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2016 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+      package="android.widget.toast.cts">
+
+    <uses-sdk android:minSdkVersion="25" android:targetSdkVersion="26" />
+
+    <application>
+    </application>
+
+    <instrumentation android:name="android.support.test.runner.AndroidJUnitRunner"
+        android:targetPackage="android.widget.toast.cts"
+        android:label="CTS tests for toast windows">
+        <meta-data android:name="listener"
+            android:value="com.android.cts.runner.CtsTestRunListener" />
+    </instrumentation>
+
+</manifest>
+
diff --git a/tests/tests/toast/AndroidTest.xml b/tests/tests/toast/AndroidTest.xml
new file mode 100644
index 0000000..d0a5eed
--- /dev/null
+++ b/tests/tests/toast/AndroidTest.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2016 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+<configuration description="Config for Toast test cases">
+    <target_preparer class="com.android.compatibility.common.tradefed.targetprep.ApkInstaller">
+        <option name="cleanup-apks" value="true" />
+        <option name="test-file-name" value="CtsToastTestCases.apk" />
+    </target_preparer>
+    <test class="com.android.tradefed.testtype.AndroidJUnitTest" >
+        <option name="package" value="android.widget.toast.cts" />
+    </test>
+</configuration>
diff --git a/tests/tests/toast/src/android/widget/toast/cts/BaseToastTest.java b/tests/tests/toast/src/android/widget/toast/cts/BaseToastTest.java
new file mode 100644
index 0000000..fd75309
--- /dev/null
+++ b/tests/tests/toast/src/android/widget/toast/cts/BaseToastTest.java
@@ -0,0 +1,101 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.widget.toast.cts;
+
+import android.app.Instrumentation;
+import android.app.UiAutomation;
+import android.content.Context;
+import android.graphics.PixelFormat;
+import android.os.SystemClock;
+import android.support.test.InstrumentationRegistry;
+import android.view.WindowManager;
+import android.widget.TextView;
+import android.widget.Toast;
+import org.junit.Before;
+
+/**
+ * Base class for toast tests.
+ */
+public abstract class BaseToastTest {
+    protected static final long TOAST_TIMEOUT_MILLIS = 5000; // 5 sec
+    protected static final long EVENT_TIMEOUT_MILLIS = 5000; // 5 sec
+
+    protected Context mContext;
+    protected Instrumentation mInstrumentation;
+    protected UiAutomation mUiAutomation;
+
+    @Before
+    public void setUp() {
+        mContext = InstrumentationRegistry.getContext();
+        mInstrumentation = InstrumentationRegistry.getInstrumentation();
+        mUiAutomation = mInstrumentation.getUiAutomation();
+        waitForToastTimeout();
+    }
+
+    protected void waitForToastTimeout() {
+        SystemClock.sleep(TOAST_TIMEOUT_MILLIS);
+    }
+
+    protected void showToastsViaToastApis(int count) throws Exception {
+        Exception[] exceptions = new Exception[1];
+        mInstrumentation.runOnMainSync(
+                () -> {
+                    try {
+                        for (int i = 0; i < count; i++) {
+                            Toast.makeText(mContext, getClass().getName(),
+                                    Toast.LENGTH_LONG).show();
+                        }
+                    } catch (Exception e) {
+                        exceptions[0] = e;
+                    }
+                });
+        if (exceptions[0] != null) {
+            throw exceptions[0];
+        }
+    }
+
+    protected void showToastsViaAddingWindow(int count, boolean focusable) throws Exception {
+        Exception[] exceptions = new Exception[1];
+        mInstrumentation.runOnMainSync(() -> {
+            try {
+                for (int i = 0; i < count; i++) {
+                    WindowManager.LayoutParams params = new WindowManager.LayoutParams();
+                    params.height = WindowManager.LayoutParams.WRAP_CONTENT;
+                    params.width = WindowManager.LayoutParams.WRAP_CONTENT;
+                    params.format = PixelFormat.TRANSLUCENT;
+                    params.type = WindowManager.LayoutParams.TYPE_TOAST;
+                    params.flags = WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON;
+                    if (!focusable) {
+                        params.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE;
+                    }
+
+                    TextView textView = new TextView(mContext);
+                    textView.setText(BaseToastTest.class.getName());
+
+                    WindowManager windowManager = mContext
+                            .getSystemService(WindowManager.class);
+                    windowManager.addView(textView, params);
+                }
+            } catch (Exception e) {
+                exceptions[0] = e;
+            }
+        });
+        if (exceptions[0] != null) {
+            throw exceptions[0];
+        }
+    }
+}
diff --git a/tests/tests/toast/src/android/widget/toast/cts/LegacyToastTest.java b/tests/tests/toast/src/android/widget/toast/cts/LegacyToastTest.java
new file mode 100644
index 0000000..4ac88b3
--- /dev/null
+++ b/tests/tests/toast/src/android/widget/toast/cts/LegacyToastTest.java
@@ -0,0 +1,59 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.widget.toast.cts;
+
+import android.support.test.runner.AndroidJUnit4;
+import android.view.WindowManager;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import static org.junit.Assert.fail;
+
+/**
+ * Test whether toasts are properly shown. For apps targeting API 25+
+ * like this app the only way to add toast windows is via the dedicated
+ * toast APIs.
+ */
+@RunWith(AndroidJUnit4.class)
+public class LegacyToastTest extends BaseToastTest {
+    @Test
+    public void testAddSingleToastViaTestApisWhenUidFocused() throws Exception {
+        // Normal toast windows cannot be obtained vie the accessibility APIs because
+        // they are not touchable. In this case not crashing is good enough.
+        showToastsViaToastApis(1);
+    }
+
+    @Test
+    public void testAddTwoToastViaTestApisWhenUidFocused() throws Exception {
+        // Normal toast windows cannot be obtained vie the accessibility APIs because
+        // they are not touchable. In this case not crashing is good enough.
+        showToastsViaToastApis(2);
+
+        // Wait for the first one to expire
+        waitForToastTimeout();
+    }
+
+    @Test
+    public void testAddSingleToastViaAddingWindowApisWhenUidFocused() throws Exception {
+        try {
+            showToastsViaAddingWindow(1, false);
+            fail("Shouldn't be able to add toast windows directly");
+        } catch (WindowManager.BadTokenException e) {
+            /* expected */
+        }
+    }
+}
diff --git a/tests/tests/toastlegacy/Android.mk b/tests/tests/toastlegacy/Android.mk
new file mode 100644
index 0000000..ac5825d
--- /dev/null
+++ b/tests/tests/toastlegacy/Android.mk
@@ -0,0 +1,34 @@
+#
+# Copyright (C) 2016 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+LOCAL_PATH:= $(call my-dir)
+
+include $(CLEAR_VARS)
+
+LOCAL_MODULE_TAGS := tests
+
+LOCAL_MODULE_PATH := $(TARGET_OUT_DATA_APPS)
+
+LOCAL_COMPATIBILITY_SUITE := cts
+
+LOCAL_STATIC_JAVA_LIBRARIES := ctstestrunner android-support-test
+
+LOCAL_SRC_FILES := $(call all-java-files-under, src) \
+    ../toast/src/android/widget/toast/cts/BaseToastTest.java
+
+LOCAL_PACKAGE_NAME := CtsToastLegacyTestCases
+
+include $(BUILD_CTS_PACKAGE)
+
diff --git a/tests/tests/toastlegacy/AndroidManifest.xml b/tests/tests/toastlegacy/AndroidManifest.xml
new file mode 100644
index 0000000..8529b5c
--- /dev/null
+++ b/tests/tests/toastlegacy/AndroidManifest.xml
@@ -0,0 +1,35 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2016 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+      package="android.widget.toast.legacy.cts">
+
+    <uses-sdk android:minSdkVersion="25" android:targetSdkVersion="25" />
+
+    <application>
+        <activity android:name="android.widget.toast.cts.legacy.ToastActivity">
+        </activity>
+    </application>
+
+    <instrumentation android:name="android.support.test.runner.AndroidJUnitRunner"
+        android:targetPackage="android.widget.toast.legacy.cts"
+        android:label="CTS tests for legacy toast windows">
+        <meta-data android:name="listener"
+            android:value="com.android.cts.runner.CtsTestRunListener" />
+    </instrumentation>
+
+</manifest>
+
diff --git a/tests/tests/toastlegacy/AndroidTest.xml b/tests/tests/toastlegacy/AndroidTest.xml
new file mode 100644
index 0000000..a208077
--- /dev/null
+++ b/tests/tests/toastlegacy/AndroidTest.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2016 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+<configuration description="Config for Toast legacy test cases">
+    <target_preparer class="com.android.compatibility.common.tradefed.targetprep.ApkInstaller">
+        <option name="cleanup-apks" value="true" />
+        <option name="test-file-name" value="CtsToastLegacyTestCases.apk" />
+    </target_preparer>
+    <test class="com.android.tradefed.testtype.AndroidJUnitTest" >
+        <option name="package" value="android.widget.toast.legacy.cts" />
+    </test>
+</configuration>
diff --git a/tests/tests/toastlegacy/src/android/widget/toast/cts/legacy/ToastActivity.java b/tests/tests/toastlegacy/src/android/widget/toast/cts/legacy/ToastActivity.java
new file mode 100644
index 0000000..745385e
--- /dev/null
+++ b/tests/tests/toastlegacy/src/android/widget/toast/cts/legacy/ToastActivity.java
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.widget.toast.cts.legacy;
+
+import android.app.Activity;
+import android.graphics.Color;
+import android.os.Bundle;
+import android.view.View;
+import android.view.ViewGroup;
+
+/**
+ * Activity that shows toasts on demand.
+ */
+public class ToastActivity extends Activity {
+
+    @Override
+    public void onCreate(Bundle bundle) {
+        super.onCreate(bundle);
+        View view = new View(this);
+        view.setBackgroundColor(Color.BLUE);
+        view.setLayoutParams(new ViewGroup.LayoutParams(
+                ViewGroup.LayoutParams.MATCH_PARENT,
+                ViewGroup.LayoutParams.MATCH_PARENT));
+        setContentView(view);
+    }
+}
diff --git a/tests/tests/toastlegacy/src/android/widget/toast/cts/legacy/ToastTest.java b/tests/tests/toastlegacy/src/android/widget/toast/cts/legacy/ToastTest.java
new file mode 100644
index 0000000..207e6ea
--- /dev/null
+++ b/tests/tests/toastlegacy/src/android/widget/toast/cts/legacy/ToastTest.java
@@ -0,0 +1,144 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.widget.toast.cts.legacy;
+
+import android.support.test.rule.ActivityTestRule;
+import android.support.test.runner.AndroidJUnit4;
+import android.view.WindowManager;
+import android.view.accessibility.AccessibilityEvent;
+import android.widget.toast.cts.BaseToastTest;
+import org.junit.Assert;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+/**
+ * Test whether toasts are properly shown. For apps targeting SDK
+ * 25 and below a toast window can be added via the window APIs
+ * but it will be removed after a timeout if the UID that added
+ * the window is not focused. Also only a single toast window
+ * is allowed at a time.
+ */
+@RunWith(AndroidJUnit4.class)
+public class ToastTest extends BaseToastTest {
+    @Rule
+    public final ActivityTestRule<ToastActivity> mActivityRule =
+            new ActivityTestRule<>(ToastActivity.class);
+
+    @Test
+    public void testAddSingleNotFocusableToastViaAddingWindowApisWhenUidFocused() throws Exception {
+        // Show a toast on top of the focused activity
+        showToastsViaAddingWindow(1, false);
+
+        // Wait for the toast to timeout
+        waitForToastTimeout();
+
+        // Finish the activity so the UID loses focus
+        finishActivity(false);
+
+        // Wait for the toast to timeout
+        waitForToastTimeout();
+
+        // Show another toast
+        showToastsViaAddingWindow(1, false);
+    }
+
+    @Test
+    public void testAddSingleFocusableToastViaAddingWindowApisWhenUidFocused() throws Exception {
+        // Show a toast on top of our activity
+        showToastsViaAddingWindow(1, true);
+
+        // Wait for the toast to timeout
+        waitForToastTimeout();
+
+        // Show a toast on top of our activity
+        showToastsViaAddingWindow(1, true);
+    }
+
+    @Test
+    public void testAddSingleToastViaAddingWindowApisWhenUidNotFocused() throws Exception {
+        // Finish the activity so the UID loses focus
+        finishActivity(false);
+
+        // Show a toast
+        showToastsViaAddingWindow(1, true);
+
+        // Wait for the toast to timeout
+        waitForToastTimeout();
+
+        // Show a toast on top of our activity
+        showToastsViaAddingWindow(1, true);
+    }
+
+    @Test
+    public void testAddTwoToastsViaToastApisWhenUidFocused() throws Exception {
+        // Finish the activity so the UID loses focus
+        finishActivity(false);
+
+        // Normal toast windows cannot be obtained vie the accessibility APIs because
+        // they are not touchable. In this case not crashing is good enough.
+        showToastsViaToastApis(2);
+
+        // Wait for the first one to expire
+        waitForToastTimeout();
+    }
+
+    @Test
+    public void testAddTwoToastsViaToastApisWhenUidNotFocused() throws Exception {
+        // Normal toast windows cannot be obtained vie the accessibility APIs because
+        // they are not touchable. In this case not crashing is good enough.
+        showToastsViaToastApis(2);
+
+        // Wait for the first one to expire
+        waitForToastTimeout();
+    }
+
+    @Test
+    public void testAddTwoToastsViaAddingWindowApisWhenUidFocusedQuickly() throws Exception {
+        try {
+            showToastsViaAddingWindow(2, false);
+            Assert.fail("Only one custom toast window at a time should be allowed");
+        } catch (WindowManager.BadTokenException e) {
+            /* expected */
+        } catch (Exception ex) {
+            Assert.fail("Unexpected exception when adding second toast window" + ex);
+        }
+    }
+
+    @Test
+    public void testAddTwoToastsViaAddingWindowApisWhenUidFocusedSlowly() throws Exception {
+        // Add one window
+        showToastsViaAddingWindow(1, true);
+
+        // Wait for the toast to timeout
+        waitForToastTimeout();
+
+        // Add another window
+        showToastsViaAddingWindow(1, true);
+    }
+
+    private void finishActivity(boolean waitForEvent) throws Exception {
+        if (waitForEvent) {
+            mUiAutomation.executeAndWaitForEvent(
+                    () -> mActivityRule.getActivity().finish(),
+                    (event) -> event.getEventType() == AccessibilityEvent.TYPE_WINDOWS_CHANGED
+                    , EVENT_TIMEOUT_MILLIS);
+        } else {
+            mActivityRule.getActivity().finish();
+        }
+    }
+}
diff --git a/tests/tests/transition/src/android/transition/cts/BaseTransitionTest.java b/tests/tests/transition/src/android/transition/cts/BaseTransitionTest.java
index 944ff91..a3a8cad 100644
--- a/tests/tests/transition/src/android/transition/cts/BaseTransitionTest.java
+++ b/tests/tests/transition/src/android/transition/cts/BaseTransitionTest.java
@@ -27,7 +27,9 @@
 import android.view.Choreographer.FrameCallback;
 import android.view.View;
 import android.view.ViewGroup;
+import android.view.ViewTreeObserver;
 import android.widget.FrameLayout;
+import junit.framework.Assert;
 
 import java.util.ArrayList;
 import java.util.concurrent.CountDownLatch;
@@ -139,13 +141,31 @@
     }
 
     protected void enterScene(final Scene scene) throws Throwable {
-        runTestOnUiThread(new Runnable() {
-            @Override
-            public void run() {
-                scene.enter();
-            }
+        final CountDownLatch latch = new CountDownLatch(1);
+
+        runTestOnUiThread(() -> {
+            final ViewTreeObserver.OnGlobalLayoutListener listener =
+                    new ViewTreeObserver.OnGlobalLayoutListener() {
+                @Override
+                public void onGlobalLayout() {
+                    mActivity.getWindow().getDecorView().
+                            getViewTreeObserver().removeOnGlobalLayoutListener(this);
+                    latch.countDown();
+                }
+            };
+
+            mActivity.getWindow().getDecorView().
+                    getViewTreeObserver().addOnGlobalLayoutListener(listener);
+
+            scene.enter();
         });
-        getInstrumentation().waitForIdleSync();
+
+        try {
+            Assert.assertTrue("Expected layout pass within 5 seconds",
+                    latch.await(5, TimeUnit.SECONDS));
+        } catch (InterruptedException e) {
+            throw new RuntimeException(e);
+        }
     }
 
     protected void exitScene(final Scene scene) throws Throwable {
diff --git a/tests/tests/uirendering/src/android/uirendering/cts/testinfrastructure/DrawActivity.java b/tests/tests/uirendering/src/android/uirendering/cts/testinfrastructure/DrawActivity.java
index 60c67d4..1be34f9 100644
--- a/tests/tests/uirendering/src/android/uirendering/cts/testinfrastructure/DrawActivity.java
+++ b/tests/tests/uirendering/src/android/uirendering/cts/testinfrastructure/DrawActivity.java
@@ -163,7 +163,8 @@
                 mView.postInvalidate();
             } else {
                 synchronized (mLock) {
-                    mLock.set(mViewWrapper.getLeft(), mViewWrapper.getTop());
+                    final int[] locationOnScreen = mViewWrapper.getLocationOnScreen();
+                    mLock.set(locationOnScreen[0], locationOnScreen[1]);
                     mLock.notify();
                 }
                 mView.getViewTreeObserver().removeOnPreDrawListener(this);
diff --git a/tests/tests/view/AndroidManifest.xml b/tests/tests/view/AndroidManifest.xml
index ba1f3d2..e0d8371 100644
--- a/tests/tests/view/AndroidManifest.xml
+++ b/tests/tests/view/AndroidManifest.xml
@@ -19,6 +19,8 @@
     package="android.view.cts">
 
     <uses-permission android:name="android.permission.DISABLE_KEYGUARD" />
+    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
+
     <application android:label="Android TestCase"
                 android:icon="@drawable/size_48x48"
                 android:maxRecents="1"
@@ -239,8 +241,18 @@
             </intent-filter>
         </activity>
 
+        <activity android:name="android.view.cts.DragDropActivity"
+                  android:label="DragDropActivity">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+                <category android:name="android.intent.category.FRAMEWORK_INSTRUMENTATION_TEST" />
+            </intent-filter>
+        </activity>
+
         <activity android:name="android.view.cts.surfacevalidator.CapturedActivity"
-                  android:theme="@style/WhiteBackgroundTheme">
+            android:configChanges="orientation|screenSize"
+            android:screenOrientation="locked"
+            android:theme="@style/WhiteBackgroundTheme">
             <intent-filter>
                 <action android:name="android.intent.action.MAIN" />
                 <category android:name="android.intent.category.LAUNCHER" />
diff --git a/tests/tests/view/res/layout/drag_drop_layout.xml b/tests/tests/view/res/layout/drag_drop_layout.xml
new file mode 100644
index 0000000..3800d99
--- /dev/null
+++ b/tests/tests/view/res/layout/drag_drop_layout.xml
@@ -0,0 +1,50 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ -->
+
+<LinearLayout
+        android:id="@+id/drag_drop_activity_main"
+        xmlns:android="http://schemas.android.com/apk/res/android"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:orientation="vertical">
+    <FrameLayout
+            android:id="@+id/container"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:layout_margin="64px"
+            android:background="#BBBBBB">
+        <FrameLayout
+                android:id="@+id/subcontainer"
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:layout_margin="64px"
+                android:background="#666666">
+            <View
+                    android:id="@+id/inner"
+                    android:layout_width="64px"
+                    android:layout_height="64px"
+                    android:layout_margin="64px"
+                    android:background="#00FF00" />
+        </FrameLayout>
+    </FrameLayout>
+    <View
+            android:id="@+id/draggable"
+            android:layout_width="64px"
+            android:layout_height="64px"
+            android:layout_margin="64px"
+            android:background="#0000FF" />
+</LinearLayout>
diff --git a/tests/tests/view/src/android/view/animation/cts/AnimatorInflaterTest.java b/tests/tests/view/src/android/view/animation/cts/AnimatorInflaterTest.java
index 3851e94..e8cd62c 100644
--- a/tests/tests/view/src/android/view/animation/cts/AnimatorInflaterTest.java
+++ b/tests/tests/view/src/android/view/animation/cts/AnimatorInflaterTest.java
@@ -128,6 +128,7 @@
         WindowManager mWindowManager = (WindowManager) getActivity()
                 .getSystemService(Context.WINDOW_SERVICE);
         Display display = mWindowManager.getDefaultDisplay();
+        int orientation = getActivity().getResources().getConfiguration().orientation;
 
         Instrumentation.ActivityMonitor monitor = new Instrumentation.ActivityMonitor(
                 getActivity().getClass().getName(), null, false);
@@ -160,6 +161,10 @@
             Log.e(TAG, "New activity orientation does not match. Canceling test");
             return false;
         }
+        if (getActivity().getResources().getConfiguration().orientation == orientation) {
+            Log.e(TAG, "Screen orientation didn't change, test is canceled");
+            return false;
+        }
         return true;
     }
 
diff --git a/tests/tests/view/src/android/view/cts/DragDropActivity.java b/tests/tests/view/src/android/view/cts/DragDropActivity.java
new file mode 100644
index 0000000..b4324e3
--- /dev/null
+++ b/tests/tests/view/src/android/view/cts/DragDropActivity.java
@@ -0,0 +1,31 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.view.cts;
+
+import android.view.cts.R;
+
+import android.app.Activity;
+import android.os.Bundle;
+
+public class DragDropActivity extends Activity {
+
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        setContentView(R.layout.drag_drop_layout);
+    }
+}
\ No newline at end of file
diff --git a/tests/tests/view/src/android/view/cts/DragDropTest.java b/tests/tests/view/src/android/view/cts/DragDropTest.java
new file mode 100644
index 0000000..968dc7b
--- /dev/null
+++ b/tests/tests/view/src/android/view/cts/DragDropTest.java
@@ -0,0 +1,592 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.view.cts;
+
+import com.android.internal.util.ArrayUtils;
+
+import android.app.Instrumentation;
+import android.app.UiAutomation;
+import android.content.pm.PackageManager;
+import android.os.SystemClock;
+import android.support.test.InstrumentationRegistry;
+import android.support.test.rule.ActivityTestRule;
+import android.support.test.runner.AndroidJUnit4;
+import android.view.DragEvent;
+import android.view.InputDevice;
+import android.view.MotionEvent;
+import android.view.View;
+import android.view.ViewGroup;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import java.lang.InterruptedException;
+import java.lang.StringBuilder;
+import java.lang.Thread;
+import java.util.ArrayList;
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.TimeUnit;
+import java.util.Objects;
+
+import static junit.framework.TestCase.*;
+
+@RunWith(AndroidJUnit4.class)
+public class DragDropTest {
+    static final String TAG = "DragDropTest";
+
+    final Instrumentation mInstrumentation = InstrumentationRegistry.getInstrumentation();
+    final UiAutomation mAutomation = mInstrumentation.getUiAutomation();
+
+    @Rule
+    public ActivityTestRule<DragDropActivity> mActivityRule =
+            new ActivityTestRule<>(DragDropActivity.class);
+
+    private DragDropActivity mActivity;
+
+    private CountDownLatch mEndReceived;
+
+    static boolean equal(DragEvent ev1, DragEvent ev2) {
+        return ev1.getAction() == ev2.getAction() &&
+                ev1.getX() == ev2.getX() &&
+                ev1.getY() == ev2.getY() &&
+                Objects.equals(ev1.getClipData(), ev2.getClipData()) &&
+                Objects.equals(ev1.getClipDescription(), ev2.getClipDescription()) &&
+                Objects.equals(ev1.getDragAndDropPermissions(), ev2.getDragAndDropPermissions()) &&
+                Objects.equals(ev1.getLocalState(), ev2.getLocalState()) &&
+                ev1.getResult() == ev2.getResult();
+    }
+
+    class LogEntry {
+        public View v;
+        public DragEvent ev;
+
+        public LogEntry(View v, DragEvent ev) {
+            this.v = v;
+            this.ev = DragEvent.obtain(ev);
+        }
+
+        public boolean eq(LogEntry other) {
+            return v == other.v && equal(ev, other.ev);
+        }
+    }
+
+    // Actual and expected sequences of events.
+    // While the test is running, logs should be accessed only from the main thread.
+    final private ArrayList<LogEntry> mActual = new ArrayList<LogEntry> ();
+    final private ArrayList<LogEntry> mExpected = new ArrayList<LogEntry> ();
+
+    static private DragEvent obtainDragEvent(int action, int x, int y, boolean result) {
+        return DragEvent.obtain(action, x, y, null, null, null, null, result);
+    }
+
+    private void logEvent(View v, DragEvent ev) {
+        if (ev.getAction() == DragEvent.ACTION_DRAG_ENDED) {
+            mEndReceived.countDown();
+        }
+        mActual.add(new LogEntry(v, ev));
+    }
+
+    // Add expected event for a view, with zero coordinates.
+    private void expectEvent5(int action, int viewId) {
+        View v = mActivity.findViewById(viewId);
+        mExpected.add(new LogEntry(v, obtainDragEvent(action, 0, 0, false)));
+    }
+
+    // Add expected event for a view.
+    private void expectEndEvent(int viewId, int x, int y, boolean result) {
+        View v = mActivity.findViewById(viewId);
+        mExpected.add(new LogEntry(v, obtainDragEvent(DragEvent.ACTION_DRAG_ENDED, x, y, result)));
+    }
+
+    // Add expected successful-end event for a view.
+    private void expectEndEventSuccess(int viewId) {
+        expectEndEvent(viewId, 0, 0, true);
+    }
+
+    // Add expected failed-end event for a view, with the release coordinates shifted by 6 relative
+    // to the left-upper corner of a view with id releaseViewId.
+    private void expectEndEventFailure6(int viewId, int releaseViewId) {
+        View v = mActivity.findViewById(viewId);
+        View release = mActivity.findViewById(releaseViewId);
+        int [] releaseLoc = release.getLocationOnScreen();
+        mExpected.add(new LogEntry(v, obtainDragEvent(DragEvent.ACTION_DRAG_ENDED,
+                releaseLoc[0] + 6, releaseLoc[1] + 6, false)));
+    }
+
+    // Add expected event for a view, with coordinates over view locationViewId, with the specified
+    // offset from the location view's upper-left corner.
+    private void expectEventWithOffset(int action, int viewId, int locationViewId, int offset) {
+        View v = mActivity.findViewById(viewId);
+        View locationView = mActivity.findViewById(locationViewId);
+        int [] viewLocation = v.getLocationOnScreen();
+        int [] locationViewLocation = locationView.getLocationOnScreen();
+        mExpected.add(new LogEntry(v, obtainDragEvent(action,
+                locationViewLocation[0] - viewLocation[0] + offset,
+                locationViewLocation[1] - viewLocation[1] + offset, false)));
+    }
+
+    private void expectEvent5(int action, int viewId, int locationViewId) {
+        expectEventWithOffset(action, viewId, locationViewId, 5);
+    }
+
+    // See comment for injectMouse6 on why we need both *5 and *6 methods.
+    private void expectEvent6(int action, int viewId, int locationViewId) {
+        expectEventWithOffset(action, viewId, locationViewId, 6);
+    }
+
+    // Inject mouse event over a given view, with specified offset from its left-upper corner.
+    private void injectMouseWithOffset(int viewId, int action, int offset) {
+        runOnMain(() -> {
+            View v = mActivity.findViewById(viewId);
+            int [] destLoc = v.getLocationOnScreen();
+            long downTime = SystemClock.uptimeMillis();
+            MotionEvent event = MotionEvent.obtain(downTime, downTime, action,
+                    destLoc[0] + offset, destLoc[1] + offset, 1);
+            event.setSource(InputDevice.SOURCE_TOUCHSCREEN);
+            mAutomation.injectInputEvent(event, false);
+        });
+
+        // Wait till the mouse event generates drag events. Also, some waiting needed because the
+        // system seems to collapse too frequent mouse events.
+        try {
+            Thread.sleep(100);
+        } catch (Exception e) {
+            fail("Exception while wait: " + e);
+        }
+    }
+
+    // Inject mouse event over a given view, with offset 5 from its left-upper corner.
+    private void injectMouse5(int viewId, int action) {
+        injectMouseWithOffset(viewId, action, 5);
+    }
+
+    // Inject mouse event over a given view, with offset 6 from its left-upper corner.
+    // We need both injectMouse5 and injectMouse6 if we want to inject 2 events in a row in the same
+    // view, and want them to produce distinct drag events or simply drag events with different
+    // coordinates.
+    private void injectMouse6(int viewId, int action) {
+        injectMouseWithOffset(viewId, action, 6);
+    }
+
+    private String logToString(ArrayList<LogEntry> log) {
+        StringBuilder sb = new StringBuilder();
+        for (int i = 0; i < log.size(); ++i) {
+            LogEntry e = log.get(i);
+            sb.append("#").append(i + 1).append(": ").append(e.ev).append(" @ ").
+                    append(e.v.toString()).append('\n');
+        }
+        return sb.toString();
+    }
+
+    private void failWithLogs(String message) {
+        fail(message + ":\nExpected event sequence:\n" + logToString(mExpected) +
+                "\nActual event sequence:\n" + logToString(mActual));
+    }
+
+    private void verifyEventLog() {
+        try {
+            assertTrue("Timeout while waiting for END event",
+                    mEndReceived.await(1, TimeUnit.SECONDS));
+        } catch (InterruptedException e) {
+            fail("Got InterruptedException while waiting for END event");
+        }
+
+        // Verify the log.
+        runOnMain(() -> {
+            if (mExpected.size() != mActual.size()) {
+                failWithLogs("Actual log has different size than expected");
+            }
+
+            for (int i = 0; i < mActual.size(); ++i) {
+                if (!mActual.get(i).eq(mExpected.get(i))) {
+                    failWithLogs("Actual event #" + (i + 1) + " is different from expected");
+                }
+            }
+        });
+    }
+
+    private boolean init() {
+        // Only run for non-watch devices
+        if (mActivity.getPackageManager().hasSystemFeature(PackageManager.FEATURE_WATCH)) {
+            return false;
+        }
+        return true;
+    }
+
+    @Before
+    public void setUp() {
+        mActivity = mActivityRule.getActivity();
+        mEndReceived = new CountDownLatch(1);
+    }
+
+    @After
+    public void tearDown() throws Exception {
+        mActual.clear();
+        mExpected.clear();
+    }
+
+    // Sets handlers on all views in a tree, which log the event and return false.
+    private void setRejectingHandlersOnTree(View v) {
+        v.setOnDragListener((_v, ev) -> {
+            logEvent(_v, ev);
+            return false;
+        });
+
+        if (v instanceof ViewGroup) {
+            ViewGroup group = (ViewGroup) v;
+            for (int i = 0; i < group.getChildCount(); ++i) {
+                setRejectingHandlersOnTree(group.getChildAt(i));
+            }
+        }
+    }
+
+    private void runOnMain(Runnable runner) {
+        mInstrumentation.runOnMainSync(runner);
+    }
+
+    private void startDrag() {
+        // Mouse down. Required for the drag to start.
+        injectMouse5(R.id.draggable, MotionEvent.ACTION_DOWN);
+
+        runOnMain(() -> {
+            // Start drag.
+            View v = mActivity.findViewById(R.id.draggable);
+            assertTrue("Couldn't start drag",
+                    v.startDragAndDrop(null, new View.DragShadowBuilder(v), null, 0));
+        });
+    }
+
+    /**
+     * Tests that no drag-drop events are sent to views that aren't supposed to receive them.
+     */
+    @Test
+    public void testNoExtraEvents() throws Exception {
+        if (!init()) {
+            return;
+        }
+
+        runOnMain(() -> {
+            // Tell all views in layout to return false to all events, and log them.
+            setRejectingHandlersOnTree(mActivity.findViewById(R.id.drag_drop_activity_main));
+
+            // Override handlers for the inner view and its parent to return true.
+            mActivity.findViewById(R.id.inner).setOnDragListener((v, ev) -> {
+                logEvent(v, ev);
+                return true;
+            });
+            mActivity.findViewById(R.id.subcontainer).setOnDragListener((v, ev) -> {
+                logEvent(v, ev);
+                return true;
+            });
+        });
+
+        startDrag();
+
+        // Move mouse to the outmost view. This shouldn't generate any events since it returned
+        // false to STARTED.
+        injectMouse5(R.id.container, MotionEvent.ACTION_MOVE);
+        // Release mouse over the inner view. This produces DROP there.
+        injectMouse5(R.id.inner, MotionEvent.ACTION_UP);
+
+        expectEvent5(DragEvent.ACTION_DRAG_STARTED, R.id.inner, R.id.draggable);
+        expectEvent5(DragEvent.ACTION_DRAG_STARTED, R.id.subcontainer, R.id.draggable);
+        expectEvent5(DragEvent.ACTION_DRAG_STARTED, R.id.container, R.id.draggable);
+        expectEvent5(DragEvent.ACTION_DRAG_STARTED, R.id.draggable, R.id.draggable);
+        expectEvent5(DragEvent.ACTION_DRAG_STARTED, R.id.drag_drop_activity_main, R.id.draggable);
+
+        expectEvent5(DragEvent.ACTION_DRAG_ENTERED, R.id.inner);
+        expectEvent5(DragEvent.ACTION_DROP, R.id.inner, R.id.inner);
+
+        expectEndEventSuccess(R.id.inner);
+        expectEndEventSuccess(R.id.subcontainer);
+
+        verifyEventLog();
+    }
+
+    /**
+     * Tests events over a non-accepting view with an accepting child get delivered to that view's
+     * parent.
+     */
+    @Test
+    public void testBlackHole() throws Exception {
+        if (!init()) {
+            return;
+        }
+
+        runOnMain(() -> {
+            // Accepting child.
+            mActivity.findViewById(R.id.inner).setOnDragListener((v, ev) -> {
+                logEvent(v, ev);
+                return true;
+            });
+            // Non-accepting parent of that child.
+            mActivity.findViewById(R.id.subcontainer).setOnDragListener((v, ev) -> {
+                logEvent(v, ev);
+                return false;
+            });
+            // Accepting parent of the previous view.
+            mActivity.findViewById(R.id.container).setOnDragListener((v, ev) -> {
+                logEvent(v, ev);
+                return true;
+            });
+        });
+
+        startDrag();
+
+        // Move mouse to the non-accepting view.
+        injectMouse5(R.id.subcontainer, MotionEvent.ACTION_MOVE);
+        // Release mouse over the non-accepting view, with different coordinates.
+        injectMouse6(R.id.subcontainer, MotionEvent.ACTION_UP);
+
+        expectEvent5(DragEvent.ACTION_DRAG_STARTED, R.id.inner, R.id.draggable);
+        expectEvent5(DragEvent.ACTION_DRAG_STARTED, R.id.subcontainer, R.id.draggable);
+        expectEvent5(DragEvent.ACTION_DRAG_STARTED, R.id.container, R.id.draggable);
+
+        expectEvent5(DragEvent.ACTION_DRAG_ENTERED, R.id.container);
+        expectEvent5(DragEvent.ACTION_DRAG_LOCATION, R.id.container, R.id.subcontainer);
+        expectEvent6(DragEvent.ACTION_DROP, R.id.container, R.id.subcontainer);
+
+        expectEndEventSuccess(R.id.inner);
+        expectEndEventSuccess(R.id.container);
+
+        verifyEventLog();
+    }
+
+    /**
+     * Tests generation of ENTER/EXIT events.
+     */
+    @Test
+    public void testEnterExit() throws Exception {
+        if (!init()) {
+            return;
+        }
+
+        runOnMain(() -> {
+            // The setup is same as for testBlackHole.
+
+            // Accepting child.
+            mActivity.findViewById(R.id.inner).setOnDragListener((v, ev) -> {
+                logEvent(v, ev);
+                return true;
+            });
+            // Non-accepting parent of that child.
+            mActivity.findViewById(R.id.subcontainer).setOnDragListener((v, ev) -> {
+                logEvent(v, ev);
+                return false;
+            });
+            // Accepting parent of the previous view.
+            mActivity.findViewById(R.id.container).setOnDragListener((v, ev) -> {
+                logEvent(v, ev);
+                return true;
+            });
+
+        });
+
+        startDrag();
+
+        // Move mouse to the non-accepting view, then to the inner one, then back to the
+        // non-accepting view, then release over the inner.
+        injectMouse5(R.id.subcontainer, MotionEvent.ACTION_MOVE);
+        injectMouse5(R.id.inner, MotionEvent.ACTION_MOVE);
+        injectMouse5(R.id.subcontainer, MotionEvent.ACTION_MOVE);
+        injectMouse5(R.id.inner, MotionEvent.ACTION_UP);
+
+        expectEvent5(DragEvent.ACTION_DRAG_STARTED, R.id.inner, R.id.draggable);
+        expectEvent5(DragEvent.ACTION_DRAG_STARTED, R.id.subcontainer, R.id.draggable);
+        expectEvent5(DragEvent.ACTION_DRAG_STARTED, R.id.container, R.id.draggable);
+
+        expectEvent5(DragEvent.ACTION_DRAG_ENTERED, R.id.container);
+        expectEvent5(DragEvent.ACTION_DRAG_LOCATION, R.id.container, R.id.subcontainer);
+        expectEvent5(DragEvent.ACTION_DRAG_EXITED, R.id.container);
+
+        expectEvent5(DragEvent.ACTION_DRAG_ENTERED, R.id.inner);
+        expectEvent5(DragEvent.ACTION_DRAG_LOCATION, R.id.inner, R.id.inner);
+        expectEvent5(DragEvent.ACTION_DRAG_EXITED, R.id.inner);
+
+        expectEvent5(DragEvent.ACTION_DRAG_ENTERED, R.id.container);
+        expectEvent5(DragEvent.ACTION_DRAG_LOCATION, R.id.container, R.id.subcontainer);
+        expectEvent5(DragEvent.ACTION_DRAG_EXITED, R.id.container);
+
+        expectEvent5(DragEvent.ACTION_DRAG_ENTERED, R.id.inner);
+        expectEvent5(DragEvent.ACTION_DROP, R.id.inner, R.id.inner);
+
+        expectEndEventSuccess(R.id.inner);
+        expectEndEventSuccess(R.id.container);
+
+        verifyEventLog();
+    }
+    /**
+     * Tests events over a non-accepting view that has no accepting ancestors.
+     */
+    @Test
+    public void testOverNowhere() throws Exception {
+        if (!init()) {
+            return;
+        }
+
+        runOnMain(() -> {
+            // Accepting child.
+            mActivity.findViewById(R.id.inner).setOnDragListener((v, ev) -> {
+                logEvent(v, ev);
+                return true;
+            });
+            // Non-accepting parent of that child.
+            mActivity.findViewById(R.id.subcontainer).setOnDragListener((v, ev) -> {
+                logEvent(v, ev);
+                return false;
+            });
+        });
+
+        startDrag();
+
+        // Move mouse to the non-accepting view, then to accepting view, and back, and drop there.
+        injectMouse5(R.id.subcontainer, MotionEvent.ACTION_MOVE);
+        injectMouse5(R.id.inner, MotionEvent.ACTION_MOVE);
+        injectMouse5(R.id.subcontainer, MotionEvent.ACTION_MOVE);
+        injectMouse6(R.id.subcontainer, MotionEvent.ACTION_UP);
+
+        expectEvent5(DragEvent.ACTION_DRAG_STARTED, R.id.inner, R.id.draggable);
+        expectEvent5(DragEvent.ACTION_DRAG_STARTED, R.id.subcontainer, R.id.draggable);
+
+        expectEvent5(DragEvent.ACTION_DRAG_ENTERED, R.id.inner);
+        expectEvent5(DragEvent.ACTION_DRAG_LOCATION, R.id.inner, R.id.inner);
+        expectEvent5(DragEvent.ACTION_DRAG_EXITED, R.id.inner);
+
+        expectEndEventFailure6(R.id.inner, R.id.subcontainer);
+
+        verifyEventLog();
+    }
+
+    /**
+     * Tests that events are properly delivered to a view that is in the middle of the accepting
+     * hierarchy.
+     */
+    @Test
+    public void testAcceptingGroupInTheMiddle() throws Exception {
+        if (!init()) {
+            return;
+        }
+
+        runOnMain(() -> {
+            // Set accepting handlers to the inner view and its 2 ancestors.
+            mActivity.findViewById(R.id.inner).setOnDragListener((v, ev) -> {
+                logEvent(v, ev);
+                return true;
+            });
+            mActivity.findViewById(R.id.subcontainer).setOnDragListener((v, ev) -> {
+                logEvent(v, ev);
+                return true;
+            });
+            mActivity.findViewById(R.id.container).setOnDragListener((v, ev) -> {
+                logEvent(v, ev);
+                return true;
+            });
+        });
+
+        startDrag();
+
+        // Move mouse to the outmost container, then move to the subcontainer and drop there.
+        injectMouse5(R.id.container, MotionEvent.ACTION_MOVE);
+        injectMouse5(R.id.subcontainer, MotionEvent.ACTION_MOVE);
+        injectMouse6(R.id.subcontainer, MotionEvent.ACTION_UP);
+
+        expectEvent5(DragEvent.ACTION_DRAG_STARTED, R.id.inner, R.id.draggable);
+        expectEvent5(DragEvent.ACTION_DRAG_STARTED, R.id.subcontainer, R.id.draggable);
+        expectEvent5(DragEvent.ACTION_DRAG_STARTED, R.id.container, R.id.draggable);
+
+        expectEvent5(DragEvent.ACTION_DRAG_ENTERED, R.id.container);
+        expectEvent5(DragEvent.ACTION_DRAG_LOCATION, R.id.container, R.id.container);
+        expectEvent5(DragEvent.ACTION_DRAG_EXITED, R.id.container);
+
+        expectEvent5(DragEvent.ACTION_DRAG_ENTERED, R.id.subcontainer);
+        expectEvent5(DragEvent.ACTION_DRAG_LOCATION, R.id.subcontainer, R.id.subcontainer);
+        expectEvent6(DragEvent.ACTION_DROP, R.id.subcontainer, R.id.subcontainer);
+
+        expectEndEventSuccess(R.id.inner);
+        expectEndEventSuccess(R.id.subcontainer);
+        expectEndEventSuccess(R.id.container);
+
+        verifyEventLog();
+    }
+
+    /**
+     * Tests that state_drag_hovered and state_drag_can_accept are set correctly.
+     */
+    @Test
+    public void testDrawableState() throws Exception {
+        if (!init()) {
+            return;
+        }
+
+        runOnMain(() -> {
+            // Set accepting handler for the inner view.
+            mActivity.findViewById(R.id.inner).setOnDragListener((v, ev) -> {
+                logEvent(v, ev);
+                return true;
+            });
+            assertFalse(ArrayUtils.contains(
+                    mActivity.findViewById(R.id.inner).getDrawableState(),
+                    android.R.attr.state_drag_can_accept));
+        });
+
+        startDrag();
+
+        runOnMain(() -> {
+            assertFalse(ArrayUtils.contains(
+                    mActivity.findViewById(R.id.inner).getDrawableState(),
+                    android.R.attr.state_drag_hovered));
+            assertTrue(ArrayUtils.contains(
+                    mActivity.findViewById(R.id.inner).getDrawableState(),
+                    android.R.attr.state_drag_can_accept));
+        });
+
+        // Move mouse into the view.
+        injectMouse5(R.id.inner, MotionEvent.ACTION_MOVE);
+        runOnMain(() -> {
+            assertTrue(ArrayUtils.contains(
+                    mActivity.findViewById(R.id.inner).getDrawableState(),
+                    android.R.attr.state_drag_hovered));
+        });
+
+        // Move out.
+        injectMouse5(R.id.subcontainer, MotionEvent.ACTION_MOVE);
+        runOnMain(() -> {
+            assertFalse(ArrayUtils.contains(
+                    mActivity.findViewById(R.id.inner).getDrawableState(),
+                    android.R.attr.state_drag_hovered));
+        });
+
+        // Move in.
+        injectMouse5(R.id.inner, MotionEvent.ACTION_MOVE);
+        runOnMain(() -> {
+            assertTrue(ArrayUtils.contains(
+                    mActivity.findViewById(R.id.inner).getDrawableState(),
+                    android.R.attr.state_drag_hovered));
+        });
+
+        // Release there.
+        injectMouse5(R.id.inner, MotionEvent.ACTION_UP);
+        runOnMain(() -> {
+            assertFalse(ArrayUtils.contains(
+                    mActivity.findViewById(R.id.inner).getDrawableState(),
+                    android.R.attr.state_drag_hovered));
+        });
+    }
+}
\ No newline at end of file
diff --git a/tests/tests/view/src/android/view/cts/PixelCopyTests.java b/tests/tests/view/src/android/view/cts/PixelCopyTests.java
index 3fa3634..dfbf2bf 100644
--- a/tests/tests/view/src/android/view/cts/PixelCopyTests.java
+++ b/tests/tests/view/src/android/view/cts/PixelCopyTests.java
@@ -23,9 +23,12 @@
 import android.graphics.SurfaceTexture;
 import android.opengl.GLSurfaceView;
 import android.opengl.GLSurfaceView.Renderer;
+import android.os.Debug;
+import android.os.Debug.MemoryInfo;
 import android.os.Handler;
 import android.os.HandlerThread;
 import android.support.test.InstrumentationRegistry;
+import android.support.test.filters.LargeTest;
 import android.support.test.filters.MediumTest;
 import android.support.test.rule.ActivityTestRule;
 import android.util.Log;
@@ -169,6 +172,96 @@
             GLSurfaceViewCtsActivity.resetRenderMode();
         }
     }
+    private void runGcAndFinalizersSync() {
+         final CountDownLatch fence = new CountDownLatch(1);
+         new Object() {
+             @Override
+             protected void finalize() throws Throwable {
+                 try {
+                     fence.countDown();
+                 } finally {
+                     super.finalize();
+                 }
+             }
+         };
+         try {
+             do {
+                 Runtime.getRuntime().gc();
+                 Runtime.getRuntime().runFinalization();
+             } while (!fence.await(100, TimeUnit.MILLISECONDS));
+         } catch (InterruptedException ex) {
+             throw new RuntimeException(ex);
+         }
+         Runtime.getRuntime().gc();
+     }
+
+    private void assertNotLeaking(int iteration, MemoryInfo start, MemoryInfo end) {
+        Debug.getMemoryInfo(end);
+         if (end.getTotalPss() - start.getTotalPss() > 2000 /* kB */) {
+            runGcAndFinalizersSync();
+            Debug.getMemoryInfo(end);
+            if (end.getTotalPss() - start.getTotalPss() > 2000 /* kB */) {
+                 // Guarded by if so we don't continually generate garbage for the
+                // assertion string.
+                assertEquals("Memory leaked, iteration=" + iteration,
+                        start.getTotalPss(), end.getTotalPss(),
+                        2000 /* kb */);
+            }
+        }
+    }
+
+    @Test
+    @LargeTest
+    public void testNotLeaking() {
+        try {
+            CountDownLatch swapFence = new CountDownLatch(2);
+            GLSurfaceViewCtsActivity.setGlVersion(2);
+            GLSurfaceViewCtsActivity.setRenderMode(GLSurfaceView.RENDERMODE_WHEN_DIRTY);
+            GLSurfaceViewCtsActivity.setFixedSize(100, 100);
+            GLSurfaceViewCtsActivity.setRenderer(new QuadColorGLRenderer(
+                    Color.RED, Color.GREEN, Color.BLUE, Color.BLACK, swapFence));
+
+            GLSurfaceViewCtsActivity activity =
+                    mGLSurfaceViewActivityRule.launchActivity(null);
+
+            while (!swapFence.await(5, TimeUnit.MILLISECONDS)) {
+                activity.getView().requestRender();
+            }
+
+            // Test a fullsize copy
+            Bitmap bitmap = Bitmap.createBitmap(100, 100, Config.ARGB_8888);
+            SynchronousPixelCopy copyHelper = new SynchronousPixelCopy();
+
+            MemoryInfo meminfoStart = new MemoryInfo();
+            MemoryInfo meminfoEnd = new MemoryInfo();
+
+            for (int i = 0; i < 1000; i++) {
+                if (i == 2) {
+                    // Not really the "start" but by having done a couple
+                    // we've fully initialized any state that may be required,
+                    // so memory usage should be stable now
+                    runGcAndFinalizersSync();
+                    Debug.getMemoryInfo(meminfoStart);
+                }
+                if (i % 100 == 5) {
+                    assertNotLeaking(i, meminfoStart, meminfoEnd);
+                }
+                int result = copyHelper.request(activity.getView(), bitmap);
+                assertEquals("Copy request failed", PixelCopy.SUCCESS, result);
+                // Make sure nothing messed with the bitmap
+                assertEquals(100, bitmap.getWidth());
+                assertEquals(100, bitmap.getHeight());
+                assertEquals(Config.ARGB_8888, bitmap.getConfig());
+                assertBitmapQuadColor(bitmap,
+                        Color.RED, Color.GREEN, Color.BLUE, Color.BLACK);
+            }
+
+            assertNotLeaking(1000, meminfoStart, meminfoEnd);
+
+        } catch (InterruptedException e) {
+            fail("Interrupted, error=" + e.getMessage());
+        }
+    }
 
     @Test
     public void testVideoProducer() throws InterruptedException {
diff --git a/tests/tests/view/src/android/view/cts/SurfaceViewSyncTests.java b/tests/tests/view/src/android/view/cts/SurfaceViewSyncTests.java
index 876c178..6f1c655 100644
--- a/tests/tests/view/src/android/view/cts/SurfaceViewSyncTests.java
+++ b/tests/tests/view/src/android/view/cts/SurfaceViewSyncTests.java
@@ -19,19 +19,18 @@
 import android.animation.PropertyValuesHolder;
 import android.animation.ValueAnimator;
 import android.annotation.SuppressLint;
+import android.graphics.Bitmap;
 import android.graphics.Canvas;
 import android.graphics.Color;
 import android.graphics.Paint;
 import android.media.MediaPlayer;
-import android.support.test.InstrumentationRegistry;
+import android.os.Environment;
 import android.support.test.rule.ActivityTestRule;
 import android.support.test.runner.AndroidJUnit4;
-import android.support.test.uiautomator.UiDevice;
-import android.support.test.uiautomator.UiObject;
 import android.support.test.uiautomator.UiObjectNotFoundException;
-import android.support.test.uiautomator.UiSelector;
 import android.test.suitebuilder.annotation.LargeTest;
 import android.util.Log;
+import android.util.SparseArray;
 import android.view.Gravity;
 import android.view.SurfaceHolder;
 import android.view.SurfaceView;
@@ -44,11 +43,18 @@
 import android.view.cts.surfacevalidator.ViewFactory;
 import android.widget.FrameLayout;
 
-import org.junit.Before;
+import libcore.io.IoUtils;
+import org.junit.After;
 import org.junit.Rule;
 import org.junit.Test;
+import org.junit.rules.TestName;
 import org.junit.runner.RunWith;
 
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.util.concurrent.TimeUnit;
+
 import static org.junit.Assert.*;
 
 @RunWith(AndroidJUnit4.class)
@@ -56,23 +62,20 @@
 @SuppressLint("RtlHardcoded")
 public class SurfaceViewSyncTests {
     private static final String TAG = "SurfaceViewSyncTests";
-    private static final int PERMISSION_DIALOG_WAIT_MS = 500;
-
-    @Before
-    public void setUp() throws UiObjectNotFoundException {
-        // The permission dialog will be auto-opened by the activity - find it and accept
-        UiDevice uiDevice = UiDevice.getInstance(InstrumentationRegistry.getInstrumentation());
-        UiSelector acceptButtonSelector = new UiSelector().resourceId("android:id/button1");
-        UiObject acceptButton = uiDevice.findObject(acceptButtonSelector);
-        if (acceptButton.waitForExists(PERMISSION_DIALOG_WAIT_MS)) {
-            assertTrue(acceptButton.click());
-        }
-    }
 
     private CapturedActivity getActivity() {
         return (CapturedActivity) mActivityRule.getActivity();
     }
 
+    /**
+     * Want to be especially sure we don't leave up the permission dialog, so try and dismiss
+     * after test.
+     */
+    @After
+    public void setUp() throws UiObjectNotFoundException {
+        getActivity().dismissPermissionDialog();
+    }
+
     private MediaPlayer getMediaPlayer() {
         return getActivity().getMediaPlayer();
     }
@@ -80,6 +83,9 @@
     @Rule
     public ActivityTestRule mActivityRule = new ActivityTestRule<>(CapturedActivity.class);
 
+    @Rule
+    public TestName mName = new TestName();
+
     static ValueAnimator makeInfinite(ValueAnimator a) {
         a.setRepeatMode(ObjectAnimator.REVERSE);
         a.setRepeatCount(ObjectAnimator.INFINITE);
@@ -165,13 +171,76 @@
     };
 
     ///////////////////////////////////////////////////////////////////////////
+    // Bad frame capture
+    ///////////////////////////////////////////////////////////////////////////
+
+    private void saveFailureCaptures(SparseArray<Bitmap> failFrames) {
+        if (failFrames.size() == 0) return;
+
+        String directoryName = Environment.getExternalStorageDirectory()
+                + "/" + getClass().getSimpleName()
+                + "/" + mName.getMethodName();
+        File testDirectory = new File(directoryName);
+        if (testDirectory.exists()) {
+            String[] children = testDirectory.list();
+            if (children == null) {
+                return;
+            }
+            for (String file : children) {
+                new File(testDirectory, file).delete();
+            }
+        } else {
+            testDirectory.mkdirs();
+        }
+
+        for (int i = 0; i < failFrames.size(); i++) {
+            int frameNr = failFrames.keyAt(i);
+            Bitmap bitmap = failFrames.valueAt(i);
+
+            String bitmapName =  "frame_" + frameNr + ".png";
+            Log.d(TAG, "Saving file : " + bitmapName + " in directory : " + directoryName);
+
+            File file = new File(directoryName, bitmapName);
+            FileOutputStream fileStream = null;
+            try {
+                fileStream = new FileOutputStream(file);
+                bitmap.compress(Bitmap.CompressFormat.PNG, 85, fileStream);
+                fileStream.flush();
+            } catch (IOException e) {
+                e.printStackTrace();
+            } finally {
+                IoUtils.closeQuietly(fileStream);
+            }
+        }
+    }
+
+
+    ///////////////////////////////////////////////////////////////////////////
     // Tests
     ///////////////////////////////////////////////////////////////////////////
 
+    public void verifyTest(AnimationTestCase testCase) throws Throwable {
+        CapturedActivity.TestResult result = getActivity().runTest(testCase);
+        saveFailureCaptures(result.failures);
+
+        float failRatio = 1.0f * result.failFrames / (result.failFrames + result.passFrames);
+        assertTrue("Error: " + failRatio + " fail ratio - extremely high, is activity obstructed?",
+                failRatio < 0.95f);
+        assertTrue("Error: " + result.failFrames
+                + " incorrect frames observed - incorrect positioning",
+                result.failFrames == 0);
+        float framesPerSecond = 1.0f * result.passFrames
+                / TimeUnit.MILLISECONDS.toSeconds(CapturedActivity.CAPTURE_DURATION_MS);
+        assertTrue("Error, only " + result.passFrames
+                + " frames observed, virtual display only capturing at "
+                + framesPerSecond + " frames per second",
+                result.passFrames > 100);
+    }
+
     /** Draws a moving 10x10 black rectangle, validates 100 pixels of black are seen each frame */
     @Test
-    public void testSmallRect() {
-        CapturedActivity.TestResult result = getActivity().runTest(new AnimationTestCase(
+    public void testSmallRect() throws Throwable {
+        verifyTest(new AnimationTestCase(
                 context -> new View(context) {
                     // draw a single pixel
                     final Paint sBlackPaint = new Paint();
@@ -190,9 +259,8 @@
                 },
                 new FrameLayout.LayoutParams(100, 100, Gravity.LEFT | Gravity.TOP),
                 view -> makeInfinite(ObjectAnimator.ofInt(view, "offset", 10, 30)),
-                (blackishPixelCount, width, height) -> blackishPixelCount == 100));
-        assertTrue(result.passFrames > 100);
-        assertTrue(result.failFrames == 0);
+                (blackishPixelCount, width, height) ->
+                        blackishPixelCount >= 90 && blackishPixelCount <= 110));
     }
 
     /**
@@ -200,53 +268,45 @@
      * approximate to avoid rounding brittleness.
      */
     @Test
-    public void testEmptySurfaceView() {
-        CapturedActivity.TestResult result = getActivity().runTest(new AnimationTestCase(
+    public void testEmptySurfaceView() throws Throwable {
+        verifyTest(new AnimationTestCase(
                 sEmptySurfaceViewFactory,
                 new FrameLayout.LayoutParams(100, 100, Gravity.LEFT | Gravity.TOP),
                 sTranslateAnimationFactory,
                 (blackishPixelCount, width, height) ->
                         blackishPixelCount > 9000 && blackishPixelCount < 11000));
-        assertTrue(result.passFrames > 100);
-        assertTrue(result.failFrames == 0);
     }
 
     @Test
-    public void testSurfaceViewSmallScale() {
-        CapturedActivity.TestResult result = getActivity().runTest(new AnimationTestCase(
+    public void testSurfaceViewSmallScale() throws Throwable {
+        verifyTest(new AnimationTestCase(
                 sGreenSurfaceViewFactory,
                 new FrameLayout.LayoutParams(320, 240, Gravity.LEFT | Gravity.TOP),
                 sSmallScaleAnimationFactory,
                 (blackishPixelCount, width, height) -> blackishPixelCount == 0));
-        assertTrue(result.passFrames > 100);
-        assertTrue(result.failFrames == 0);
     }
 
     @Test
-    public void testSurfaceViewBigScale() {
-        CapturedActivity.TestResult result = getActivity().runTest(new AnimationTestCase(
+    public void testSurfaceViewBigScale() throws Throwable {
+        verifyTest(new AnimationTestCase(
                 sGreenSurfaceViewFactory,
                 new FrameLayout.LayoutParams(640, 480, Gravity.LEFT | Gravity.TOP),
                 sBigScaleAnimationFactory,
                 (blackishPixelCount, width, height) -> blackishPixelCount == 0));
-        assertTrue(result.passFrames > 100);
-        assertTrue(result.failFrames == 0);
     }
 
     @Test
-    public void testVideoSurfaceViewTranslate() {
-        CapturedActivity.TestResult result = getActivity().runTest(new AnimationTestCase(
+    public void testVideoSurfaceViewTranslate() throws Throwable {
+        verifyTest(new AnimationTestCase(
                 sVideoViewFactory,
                 new FrameLayout.LayoutParams(640, 480, Gravity.LEFT | Gravity.TOP),
                 sTranslateAnimationFactory,
                 (blackishPixelCount, width, height) -> blackishPixelCount == 0));
-        assertTrue(result.passFrames > 100);
-        assertTrue(result.failFrames == 0);
     }
 
     @Test
-    public void testVideoSurfaceViewRotated() {
-        CapturedActivity.TestResult result = getActivity().runTest(new AnimationTestCase(
+    public void testVideoSurfaceViewRotated() throws Throwable {
+        verifyTest(new AnimationTestCase(
                 sVideoViewFactory,
                 new FrameLayout.LayoutParams(100, 100, Gravity.LEFT | Gravity.TOP),
                 view -> makeInfinite(ObjectAnimator.ofPropertyValuesHolder(view,
@@ -254,13 +314,11 @@
                         PropertyValuesHolder.ofFloat(View.TRANSLATION_Y, 10f, 30f),
                         PropertyValuesHolder.ofFloat(View.ROTATION, 45f, 45f))),
                 (blackishPixelCount, width, height) -> blackishPixelCount == 0));
-        assertTrue(result.passFrames > 100);
-        assertTrue(result.failFrames == 0);
     }
 
     @Test
-    public void testVideoSurfaceViewEdgeCoverage() {
-        CapturedActivity.TestResult result = getActivity().runTest(new AnimationTestCase(
+    public void testVideoSurfaceViewEdgeCoverage() throws Throwable {
+        verifyTest(new AnimationTestCase(
                 sVideoViewFactory,
                 new FrameLayout.LayoutParams(640, 480, Gravity.CENTER),
                 view -> {
@@ -274,13 +332,11 @@
                             PropertyValuesHolder.ofFloat(View.TRANSLATION_Y, 0, -y, 0, y, 0)));
                 },
                 (blackishPixelCount, width, height) -> blackishPixelCount == 0));
-        assertTrue(result.passFrames > 100);
-        assertTrue(result.failFrames == 0);
     }
 
     @Test
-    public void testVideoSurfaceViewCornerCoverage() {
-        CapturedActivity.TestResult result = getActivity().runTest(new AnimationTestCase(
+    public void testVideoSurfaceViewCornerCoverage() throws Throwable {
+        verifyTest(new AnimationTestCase(
                 sVideoViewFactory,
                 new FrameLayout.LayoutParams(640, 480, Gravity.CENTER),
                 view -> {
@@ -294,7 +350,5 @@
                             PropertyValuesHolder.ofFloat(View.TRANSLATION_Y, -y, -y, y, y, -y)));
                 },
                 (blackishPixelCount, width, height) -> blackishPixelCount == 0));
-        assertTrue(result.passFrames > 100);
-        assertTrue(result.failFrames == 0);
     }
 }
diff --git a/tests/tests/view/src/android/view/cts/ViewTest.java b/tests/tests/view/src/android/view/cts/ViewTest.java
index 19e267d..3006ddf 100644
--- a/tests/tests/view/src/android/view/cts/ViewTest.java
+++ b/tests/tests/view/src/android/view/cts/ViewTest.java
@@ -37,6 +37,7 @@
 import android.graphics.drawable.ColorDrawable;
 import android.graphics.drawable.Drawable;
 import android.graphics.drawable.StateListDrawable;
+import android.hardware.display.DisplayManager;
 import android.os.Bundle;
 import android.os.Parcelable;
 import android.os.SystemClock;
@@ -76,7 +77,6 @@
 import android.view.ViewGroup;
 import android.view.ViewParent;
 import android.view.ViewTreeObserver;
-import android.view.WindowManager;
 import android.view.accessibility.AccessibilityEvent;
 import android.view.animation.AlphaAnimation;
 import android.view.animation.Animation;
@@ -3374,8 +3374,9 @@
         Rect outRect = new Rect();
         View view = new View(mActivity);
         // mAttachInfo is null
-        WindowManager wm = (WindowManager)mActivity.getSystemService(Context.WINDOW_SERVICE);
-        Display d = wm.getDefaultDisplay();
+        DisplayManager dm = (DisplayManager) mActivity.getApplicationContext().getSystemService(
+                Context.DISPLAY_SERVICE);
+        Display d = dm.getDisplay(Display.DEFAULT_DISPLAY);
         view.getWindowVisibleDisplayFrame(outRect);
         assertEquals(0, outRect.left);
         assertEquals(0, outRect.top);
diff --git a/tests/tests/view/src/android/view/cts/surfacevalidator/CapturedActivity.java b/tests/tests/view/src/android/view/cts/surfacevalidator/CapturedActivity.java
index 6a23e02..272c70e 100644
--- a/tests/tests/view/src/android/view/cts/surfacevalidator/CapturedActivity.java
+++ b/tests/tests/view/src/android/view/cts/surfacevalidator/CapturedActivity.java
@@ -19,6 +19,7 @@
 import android.content.Context;
 import android.content.Intent;
 import android.content.pm.PackageManager;
+import android.graphics.Bitmap;
 import android.graphics.Point;
 import android.hardware.display.DisplayManager;
 import android.hardware.display.VirtualDisplay;
@@ -28,22 +29,35 @@
 import android.os.Bundle;
 import android.os.Handler;
 import android.os.Looper;
+import android.support.test.InstrumentationRegistry;
+import android.support.test.uiautomator.UiDevice;
+import android.support.test.uiautomator.UiObject;
+import android.support.test.uiautomator.UiObjectNotFoundException;
+import android.support.test.uiautomator.UiSelector;
 import android.util.DisplayMetrics;
 import android.util.Log;
+import android.util.SparseArray;
 import android.view.Display;
+import android.view.PointerIcon;
 import android.view.View;
 import android.widget.FrameLayout;
 
 import android.view.cts.R;
 
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.TimeUnit;
+import static org.junit.Assert.*;
+
+
 public class CapturedActivity extends Activity {
     public static class TestResult {
         public int passFrames;
         public int failFrames;
+        public final SparseArray<Bitmap> failures = new SparseArray<>();
     }
 
     private static final String TAG = "CapturedActivity";
-    private static final long TIME_OUT_MS = 10000;
+    private static final long TIME_OUT_MS = 25000;
     private static final int PERMISSION_CODE = 1;
     private MediaProjectionManager mProjectionManager;
     private MediaProjection mMediaProjection;
@@ -52,30 +66,54 @@
     private SurfacePixelValidator mSurfacePixelValidator;
     private final Object mLock = new Object();
 
-    private static final long START_CAPTURE_DELAY_MS = 1000;
-    private static final long END_CAPTURE_DELAY_MS = START_CAPTURE_DELAY_MS + 4000;
-    private static final long END_DELAY_MS = END_CAPTURE_DELAY_MS + 500;
+    public static final long CAPTURE_DURATION_MS = 10000;
+    private static final int PERMISSION_DIALOG_WAIT_MS = 1000;
+    private static final int RETRY_COUNT = 2;
+
+    private static final long START_CAPTURE_DELAY_MS = 4000;
+    private static final long END_CAPTURE_DELAY_MS = START_CAPTURE_DELAY_MS + CAPTURE_DURATION_MS;
+    private static final long END_DELAY_MS = END_CAPTURE_DELAY_MS + 1000;
 
     private MediaPlayer mMediaPlayer;
 
     private final Handler mHandler = new Handler(Looper.getMainLooper());
     private volatile boolean mOnWatch;
+    private CountDownLatch mCountDownLatch;
 
     @Override
     public void onCreate(Bundle savedInstanceState) {
         super.onCreate(savedInstanceState);
+        mOnWatch = getPackageManager().hasSystemFeature(PackageManager.FEATURE_WATCH);
+        if (mOnWatch) {
+            // Don't try and set up test/capture infrastructure - they're not supported
+            return;
+        }
+
         getWindow().getDecorView().setSystemUiVisibility(
                 View.SYSTEM_UI_FLAG_HIDE_NAVIGATION | View.SYSTEM_UI_FLAG_FULLSCREEN);
+        // Set the NULL pointer icon so that it won't obstruct the captured image.
+        getWindow().getDecorView().setPointerIcon(
+                PointerIcon.getSystemIcon(this, PointerIcon.TYPE_NULL));
 
         mProjectionManager =
                 (MediaProjectionManager) getSystemService(Context.MEDIA_PROJECTION_SERVICE);
 
+        mCountDownLatch = new CountDownLatch(1);
         startActivityForResult(mProjectionManager.createScreenCaptureIntent(), PERMISSION_CODE);
 
         mMediaPlayer = MediaPlayer.create(this, R.raw.colors_video);
         mMediaPlayer.setLooping(true);
+    }
 
-        mOnWatch = getPackageManager().hasSystemFeature(PackageManager.FEATURE_WATCH);
+    public void dismissPermissionDialog() throws UiObjectNotFoundException {
+        // The permission dialog will be auto-opened by the activity - find it and accept
+        UiDevice uiDevice = UiDevice.getInstance(InstrumentationRegistry.getInstrumentation());
+        UiSelector acceptButtonSelector = new UiSelector().resourceId("android:id/button1");
+        UiObject acceptButton = uiDevice.findObject(acceptButtonSelector);
+            if (acceptButton.waitForExists(PERMISSION_DIALOG_WAIT_MS)) {
+            boolean success = acceptButton.click();
+            Log.d(TAG, "found permission dialog, click attempt success = " + success);
+        }
     }
 
     /**
@@ -97,17 +135,23 @@
 
     @Override
     public void onActivityResult(int requestCode, int resultCode, Intent data) {
+        if (mOnWatch) return;
+        getWindow().getDecorView().setSystemUiVisibility(
+                View.SYSTEM_UI_FLAG_HIDE_NAVIGATION | View.SYSTEM_UI_FLAG_FULLSCREEN);
+
         if (requestCode != PERMISSION_CODE) {
             throw new IllegalStateException("Unknown request code: " + requestCode);
         }
         if (resultCode != RESULT_OK) {
             throw new IllegalStateException("User denied screen sharing permission");
         }
+        Log.d(TAG, "onActivityResult");
         mMediaProjection = mProjectionManager.getMediaProjection(resultCode, data);
         mMediaProjection.registerCallback(new MediaProjectionCallback(), null);
+        mCountDownLatch.countDown();
     }
 
-    public TestResult runTest(AnimationTestCase animationTestCase) {
+    public TestResult runTest(AnimationTestCase animationTestCase) throws Throwable {
         TestResult testResult = new TestResult();
         if (mOnWatch) {
             /**
@@ -122,6 +166,18 @@
             return testResult;
         }
 
+        int count = 0;
+        // Sometimes system decides to rotate the permission activity to another orientation
+        // right after showing it. This results in: uiautomation thinks that accept button appears,
+        // we successfully click it in terms of uiautomation, but nothing happens,
+        // because permission activity is already recreated.
+        // Thus, we try to click that button multiple times.
+        do {
+            assertTrue("Can't get the permission", count <= RETRY_COUNT);
+            dismissPermissionDialog();
+            count++;
+        } while (!mCountDownLatch.await(TIME_OUT_MS, TimeUnit.MILLISECONDS));
+
         mHandler.post(() -> {
             Log.d(TAG, "Setting up test case");
 
@@ -143,6 +199,7 @@
             display.getRealSize(size);
             display.getMetrics(metrics);
 
+
             mSurfacePixelValidator = new SurfacePixelValidator(CapturedActivity.this,
                     size, animationTestCase.getChecker());
             Log.d("MediaProjection", "Size is " + size.toString());
@@ -172,11 +229,7 @@
         }, END_DELAY_MS);
 
         synchronized (mLock) {
-            try {
-                mLock.wait(TIME_OUT_MS);
-            } catch (InterruptedException e) {
-                e.printStackTrace();
-            }
+            mLock.wait(TIME_OUT_MS);
         }
         Log.d(TAG, "Test finished, passFrames " + testResult.passFrames
                 + ", failFrames " + testResult.failFrames);
@@ -193,4 +246,4 @@
             }
         }
     }
-}
\ No newline at end of file
+}
diff --git a/tests/tests/view/src/android/view/cts/surfacevalidator/PixelCounter.rs b/tests/tests/view/src/android/view/cts/surfacevalidator/PixelCounter.rs
index 55bc251..f58b9cb 100644
--- a/tests/tests/view/src/android/view/cts/surfacevalidator/PixelCounter.rs
+++ b/tests/tests/view/src/android/view/cts/surfacevalidator/PixelCounter.rs
@@ -15,22 +15,18 @@
  */
 #pragma version(1)
 #pragma rs java_package_name(android.view.cts.surfacevalidator)
+#pragma rs reduce(countBlackishPixels) accumulator(countBlackishPixelsAccum) combiner(countBlackishPixelsCombiner)
 
-int WIDTH;
 uchar THRESHOLD;
 
-rs_allocation image;
-
-void countBlackishPixels(const int32_t *v_in, int *v_out){
-    int y = v_in[0];
-    v_out[0] = 0;
-
-    for(int i = 0 ; i < WIDTH; i++){
-        uchar4 pixel = rsGetElementAt_uchar4(image, i, y);
-        if (pixel.r < THRESHOLD
-                && pixel.g < THRESHOLD
-                && pixel.b < THRESHOLD) {
-            v_out[0]++;
-        }
+static void countBlackishPixelsAccum(int *accum, uchar4 pixel){
+    if (pixel.r < THRESHOLD
+            && pixel.g < THRESHOLD
+            && pixel.b < THRESHOLD) {
+        *accum += 1;
     }
 }
+
+static void countBlackishPixelsCombiner(int *accum, const int *other){
+    *accum += *other;
+}
diff --git a/tests/tests/view/src/android/view/cts/surfacevalidator/SurfacePixelValidator.java b/tests/tests/view/src/android/view/cts/surfacevalidator/SurfacePixelValidator.java
index c9bff1d..5a30b77 100644
--- a/tests/tests/view/src/android/view/cts/surfacevalidator/SurfacePixelValidator.java
+++ b/tests/tests/view/src/android/view/cts/surfacevalidator/SurfacePixelValidator.java
@@ -16,6 +16,7 @@
 package android.view.cts.surfacevalidator;
 
 import android.content.Context;
+import android.graphics.Bitmap;
 import android.graphics.Point;
 import android.os.Handler;
 import android.os.HandlerThread;
@@ -25,11 +26,13 @@
 import android.renderscript.RenderScript;
 import android.renderscript.Type;
 import android.util.Log;
+import android.util.SparseArray;
 import android.view.Surface;
 import android.view.cts.surfacevalidator.PixelChecker;
 
 import java.lang.reflect.InvocationTargetException;
 import java.lang.reflect.Method;
+import java.util.ArrayList;
 
 public class SurfacePixelValidator {
     private static final String TAG = "SurfacePixelValidator";
@@ -43,6 +46,8 @@
     // If no channel is greater than this value, pixel will be considered 'blackish'.
     private static final short PIXEL_CHANNEL_THRESHOLD = 4;
 
+    private static final int MAX_CAPTURED_FAILURES = 5;
+
     private final int mWidth;
     private final int mHeight;
 
@@ -54,14 +59,13 @@
     private final RenderScript mRS;
 
     private final Allocation mInPixelsAllocation;
-    private final Allocation mInRowsAllocation;
-    private final Allocation mOutRowsAllocation;
     private final ScriptC_PixelCounter mScript;
 
 
     private final Object mResultLock = new Object();
     private int mResultSuccessFrames;
     private int mResultFailureFrames;
+    private SparseArray<Bitmap> mFirstFailures = new SparseArray<>(MAX_CAPTURED_FAILURES);
 
     private Runnable mConsumeRunnable = new Runnable() {
         int numSkipped = 0;
@@ -69,15 +73,10 @@
         public void run() {
             Trace.beginSection("consume buffer");
             mInPixelsAllocation.ioReceive();
-            mScript.set_image(mInPixelsAllocation);
             Trace.endSection();
 
-            Trace.beginSection("compare");
-            mScript.forEach_countBlackishPixels(mInRowsAllocation, mOutRowsAllocation);
-            Trace.endSection();
-
-            Trace.beginSection("sum");
-            int blackishPixelCount = sum1DIntAllocation(mOutRowsAllocation, mHeight);
+            Trace.beginSection("compare and sum");
+            int blackishPixelCount = mScript.reduce_countBlackishPixels(mInPixelsAllocation).get();
             Trace.endSection();
 
             boolean success = mPixelChecker.checkPixels(blackishPixelCount, mWidth, mHeight);
@@ -85,7 +84,6 @@
                 if (numSkipped < NUM_FIRST_FRAMES_SKIPPED) {
                     numSkipped++;
                 } else {
-
                     if (success) {
                         mResultSuccessFrames++;
                     } else {
@@ -93,6 +91,15 @@
                         int totalFramesSeen = mResultSuccessFrames + mResultFailureFrames;
                         Log.d(TAG, "Failure (pixel count = " + blackishPixelCount
                                 + ") occurred on frame " + totalFramesSeen);
+
+                        if (mFirstFailures.size() < MAX_CAPTURED_FAILURES) {
+                            Log.d(TAG, "Capturing bitmap #" + mFirstFailures.size());
+                            // error, worth looking at...
+                            Bitmap capture = Bitmap.createBitmap(mWidth, mHeight,
+                                    Bitmap.Config.ARGB_8888);
+                            mInPixelsAllocation.copyTo(capture);
+                            mFirstFailures.put(totalFramesSeen, capture);
+                        }
                     }
                 }
             }
@@ -113,9 +120,6 @@
         mScript = new ScriptC_PixelCounter(mRS);
 
         mInPixelsAllocation = createBufferQueueAllocation();
-        mInRowsAllocation = createInputRowIndexAllocation();
-        mOutRowsAllocation = createOutputRowAllocation();
-        mScript.set_WIDTH(mWidth);
         mScript.set_THRESHOLD(PIXEL_CHANNEL_THRESHOLD);
 
         mInPixelsAllocation.setOnBufferAvailableListener(
@@ -126,41 +130,10 @@
         return mInPixelsAllocation.getSurface();
     }
 
-    static private int sum1DIntAllocation(Allocation array, int length) {
-        //Get the values returned from the function
-        int[] returnValue = new int[length];
-        array.copyTo(returnValue);
-        int sum = 0;
-        //If any row had any different pixels, then it fails
-        for (int i = 0; i < length; i++) {
-            sum += returnValue[i];
-        }
-        return sum;
-    }
-
-    /**
-     * Creates an allocation where the values in it are the indices of each row
-     */
-    private Allocation createInputRowIndexAllocation() {
-        //Create an array with the index of each row
-        int[] inputIndices = new int[mHeight];
-        for (int i = 0; i < mHeight; i++) {
-            inputIndices[i] = i;
-        }
-        //Create the allocation from that given array
-        Allocation inputAllocation = Allocation.createSized(mRS, Element.I32(mRS),
-                inputIndices.length, Allocation.USAGE_SCRIPT);
-        inputAllocation.copyFrom(inputIndices);
-        return inputAllocation;
-    }
-
-    private Allocation createOutputRowAllocation() {
-        return Allocation.createSized(mRS, Element.I32(mRS), mHeight, Allocation.USAGE_SCRIPT);
-    }
-
     private Allocation createBufferQueueAllocation() {
         return Allocation.createAllocations(mRS, Type.createXY(mRS,
-                Element.U8_4(mRS), mWidth, mHeight),
+                Element.RGBA_8888(mRS)
+                /*Element.U32(mRS)*/, mWidth, mHeight),
                 Allocation.USAGE_SCRIPT | Allocation.USAGE_IO_INPUT,
                 1)[0];
     }
@@ -177,6 +150,10 @@
             // Caller should only call this
             testResult.failFrames = mResultFailureFrames;
             testResult.passFrames = mResultSuccessFrames;
+
+            for (int i = 0; i < mFirstFailures.size(); i++) {
+                testResult.failures.put(mFirstFailures.keyAt(i), mFirstFailures.valueAt(i));
+            }
         }
         mWorkerThread.quitSafely();
     }
diff --git a/tests/tests/webkit/src/android/webkit/cts/ServiceWorkerClientTest.java b/tests/tests/webkit/src/android/webkit/cts/ServiceWorkerClientTest.java
index a77d648..e09e0d6 100644
--- a/tests/tests/webkit/src/android/webkit/cts/ServiceWorkerClientTest.java
+++ b/tests/tests/webkit/src/android/webkit/cts/ServiceWorkerClientTest.java
@@ -16,6 +16,7 @@
 
 package android.webkit.cts;
 
+import android.cts.util.NullWebViewUtils;
 import android.cts.util.PollingCheck;
 import android.test.ActivityInstrumentationTestCase2;
 
@@ -136,6 +137,10 @@
 
     // Test correct invocation of shouldInterceptRequest for Service Workers.
     public void testServiceWorkerClientInterceptCallback() throws Exception {
+        if (!NullWebViewUtils.isWebViewAvailable()) {
+            return;
+        }
+
         final InterceptServiceWorkerClient mInterceptServiceWorkerClient =
                 new InterceptServiceWorkerClient();
         ServiceWorkerController swController = ServiceWorkerController.getInstance();
diff --git a/tests/tests/webkit/src/android/webkit/cts/WebViewStartupTest.java b/tests/tests/webkit/src/android/webkit/cts/WebViewStartupTest.java
index a4ebaca..3b67d84 100644
--- a/tests/tests/webkit/src/android/webkit/cts/WebViewStartupTest.java
+++ b/tests/tests/webkit/src/android/webkit/cts/WebViewStartupTest.java
@@ -20,7 +20,6 @@
 import android.content.Context;
 import android.cts.util.NullWebViewUtils;
 import android.cts.util.PollingCheck;
-import android.os.StrictMode;
 import android.test.ActivityInstrumentationTestCase2;
 import android.test.UiThreadTest;
 import android.util.Log;
@@ -89,21 +88,4 @@
         assertTrue(m.matches());
         assertEquals("42", m.group(1)); // value got incremented
     }
-
-    @UiThreadTest
-    public void testStrictModeNotViolatedOnStartup() throws Throwable {
-        StrictMode.ThreadPolicy oldPolicy = StrictMode.getThreadPolicy();
-        StrictMode.ThreadPolicy testPolicy = new StrictMode.ThreadPolicy.Builder()
-            .detectDiskReads()
-            .penaltyLog()
-            .penaltyDeath()
-            .build();
-        StrictMode.setThreadPolicy(testPolicy);
-        try {
-            mActivity.createAndAttachWebView();
-        } finally {
-            StrictMode.setThreadPolicy(oldPolicy);
-        }
-    }
-
 }
diff --git a/tests/tests/widget/AndroidManifest.xml b/tests/tests/widget/AndroidManifest.xml
index 224966d..5d41337 100644
--- a/tests/tests/widget/AndroidManifest.xml
+++ b/tests/tests/widget/AndroidManifest.xml
@@ -222,7 +222,8 @@
         </activity>
 
         <activity android:name="android.widget.cts.PopupWindowCtsActivity"
-            android:label="PopupWindowCtsActivity">
+            android:label="PopupWindowCtsActivity"
+            android:theme="@style/Theme.PopupWindowCtsActivity">
             <intent-filter>
                 <action android:name="android.intent.action.MAIN" />
                 <category android:name="android.intent.category.FRAMEWORK_INSTRUMENTATION_TEST" />
@@ -380,6 +381,14 @@
             </intent-filter>
         </activity>
 
+        <activity android:name="android.widget.cts.TimePickerDialogCtsActivity"
+                  android:label="TimePickerDialogCtsActivity">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+                <category android:name="android.intent.category.FRAMEWORK_INSTRUMENTATION_TEST" />
+            </intent-filter>
+        </activity>
+
         <activity android:name="android.widget.cts.CalendarViewCtsActivity"
                   android:label="CalendarViewCtsActivity">
             <intent-filter>
diff --git a/tests/tests/widget/res/values-w320dp-h426dp/integers.xml b/tests/tests/widget/res/values-w320dp-h426dp/integers.xml
new file mode 100644
index 0000000..a9d049c
--- /dev/null
+++ b/tests/tests/widget/res/values-w320dp-h426dp/integers.xml
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2016 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+
+<resources>
+    <integer name="date_picker_mode">2</integer>
+    <integer name="time_picker_mode">2</integer>
+</resources>
diff --git a/tests/tests/widget/res/values-w426dp-h320dp/integers.xml b/tests/tests/widget/res/values-w426dp-h320dp/integers.xml
new file mode 100644
index 0000000..a9d049c
--- /dev/null
+++ b/tests/tests/widget/res/values-w426dp-h320dp/integers.xml
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2016 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+
+<resources>
+    <integer name="date_picker_mode">2</integer>
+    <integer name="time_picker_mode">2</integer>
+</resources>
diff --git a/tests/tests/widget/res/values/integers.xml b/tests/tests/widget/res/values/integers.xml
new file mode 100644
index 0000000..b2c1e65
--- /dev/null
+++ b/tests/tests/widget/res/values/integers.xml
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2016 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+
+<resources>
+    <integer name="date_picker_mode">1</integer>
+    <integer name="time_picker_mode">1</integer>
+</resources>
diff --git a/tests/tests/widget/res/values/styles.xml b/tests/tests/widget/res/values/styles.xml
index 345b450..d2e8e48 100644
--- a/tests/tests/widget/res/values/styles.xml
+++ b/tests/tests/widget/res/values/styles.xml
@@ -193,6 +193,11 @@
         <item name="android:windowSwipeToDismiss">false</item>
     </style>
 
+    <style name="Theme_Holo_With_Material_Pickers" parent="@android:style/Theme.Holo">
+        <item name="android:timePickerStyle">@android:style/Widget.Material.TimePicker</item>
+        <item name="android:datePickerStyle">@android:style/Widget.Material.DatePicker</item>
+    </style>
+
     <style name="PopupEmptyStyle" />
 
     <style name="TabWidgetCustomStyle" parent="android:Widget.TabWidget">
@@ -202,4 +207,9 @@
     </style>
 
     <style name="ToolbarPopupTheme_Test" parent="@android:style/ThemeOverlay.Material.Light" />
+
+    <style name="Theme.PopupWindowCtsActivity" parent="@android:style/Theme.Holo">
+        <!-- Force swipe-to-dismiss to false. -->
+        <item name="android:windowSwipeToDismiss">false</item>
+    </style>
 </resources>
diff --git a/tests/tests/widget/src/android/widget/cts/AbsListViewTest.java b/tests/tests/widget/src/android/widget/cts/AbsListViewTest.java
index 267e566..9faf906 100644
--- a/tests/tests/widget/src/android/widget/cts/AbsListViewTest.java
+++ b/tests/tests/widget/src/android/widget/cts/AbsListViewTest.java
@@ -33,6 +33,7 @@
 import android.graphics.drawable.Drawable;
 import android.test.ActivityInstrumentationTestCase2;
 import android.test.TouchUtils;
+import android.test.UiThreadTest;
 import android.text.Editable;
 import android.text.SpannableStringBuilder;
 import android.util.AttributeSet;
@@ -113,14 +114,37 @@
          */
     }
 
-    public void testAccessFastScrollEnabled() {
+    @UiThreadTest
+    public void testAccessFastScrollEnabled_UiThread() {
+        mListView.setFastScrollAlwaysVisible(false);
         mListView.setFastScrollEnabled(false);
         assertFalse(mListView.isFastScrollEnabled());
 
+        mListView.setFastScrollAlwaysVisible(true);
         mListView.setFastScrollEnabled(true);
         assertTrue(mListView.isFastScrollEnabled());
     }
 
+    public void testAccessFastScrollEnabled() {
+        mListView.setFastScrollAlwaysVisible(false);
+        mListView.setFastScrollEnabled(false);
+        new PollingCheck() {
+            @Override
+            protected boolean check() {
+                return !mListView.isFastScrollEnabled();
+            }
+        }.run();
+
+        mListView.setFastScrollAlwaysVisible(true);
+        mListView.setFastScrollEnabled(true);
+        new PollingCheck() {
+            @Override
+            protected boolean check() {
+                return mListView.isFastScrollEnabled();
+            }
+        }.run();
+    }
+
     public void testAccessSmoothScrollbarEnabled() {
         mListView.setSmoothScrollbarEnabled(false);
         assertFalse(mListView.isSmoothScrollbarEnabled());
diff --git a/tests/tests/widget/src/android/widget/cts/DatePickerDialogTest.java b/tests/tests/widget/src/android/widget/cts/DatePickerDialogTest.java
index 1477f73..74d0ff5 100644
--- a/tests/tests/widget/src/android/widget/cts/DatePickerDialogTest.java
+++ b/tests/tests/widget/src/android/widget/cts/DatePickerDialogTest.java
@@ -22,6 +22,7 @@
 import android.content.Context;
 import android.test.ActivityInstrumentationTestCase2;
 import android.test.UiThreadTest;
+import android.widget.DatePicker;
 
 /**
  * Test {@link DatePickerDialog}.
@@ -48,7 +49,16 @@
 
         new DatePickerDialog(mActivity, AlertDialog.THEME_TRADITIONAL, null, 1970, 1, 1);
 
-        new DatePickerDialog(mActivity, AlertDialog.THEME_HOLO_DARK, null, 1970, 1, 1);
+        // Ensure the picker is shown using the Holo-style layout.
+        DatePickerDialog holoDialog = new DatePickerDialog(mActivity, AlertDialog.THEME_HOLO_DARK,
+                null, 1970, 1, 1);
+        assertEquals(DatePicker.MODE_SPINNER, holoDialog.getDatePicker().getMode());
+
+        // Ensure the picker is shown using the Material-style layout where available.
+        DatePickerDialog holoCalendarDialog = new DatePickerDialog(mActivity,
+                R.style.Theme_Holo_With_Material_Pickers, null, 1970, 1, 1);
+        final int expectedMode = mActivity.getResources().getInteger(R.integer.date_picker_mode);
+        assertEquals(expectedMode, holoCalendarDialog.getDatePicker().getMode());
 
         new DatePickerDialog(mActivity,
                 android.R.style.Theme_Material_Dialog_Alert, null, 1970, 1, 1);
diff --git a/tests/tests/widget/src/android/widget/cts/ListPopupWindowTest.java b/tests/tests/widget/src/android/widget/cts/ListPopupWindowTest.java
index b882c0c..73e2aeb 100644
--- a/tests/tests/widget/src/android/widget/cts/ListPopupWindowTest.java
+++ b/tests/tests/widget/src/android/widget/cts/ListPopupWindowTest.java
@@ -219,6 +219,14 @@
                 Gravity.getAbsoluteGravity(gravity, upperAnchor.getLayoutDirection());
         if (absoluteGravity == Gravity.RIGHT) {
             expectedListViewOnScreenX -= (listView.getWidth() - upperAnchor.getWidth());
+        } else {
+            // On narrow screens, it's possible for the popup to reach the edge
+            // of the screen.
+            int rightmostX =
+                    getDisplay().getWidth() - mPopupWindow.getWidth() + listViewInWindowXY[0];
+            if (expectedListViewOnScreenX > rightmostX) {
+                expectedListViewOnScreenX = rightmostX;
+            }
         }
         int expectedListViewOnScreenY = anchorXY[1] + listViewInWindowXY[1]
                 + upperAnchor.getHeight() + verticalOffset;
diff --git a/tests/tests/widget/src/android/widget/cts/ListViewTest.java b/tests/tests/widget/src/android/widget/cts/ListViewTest.java
index 41fb14b..800073d 100644
--- a/tests/tests/widget/src/android/widget/cts/ListViewTest.java
+++ b/tests/tests/widget/src/android/widget/cts/ListViewTest.java
@@ -305,6 +305,10 @@
     public void testAccessHeaderView() {
         final TextView headerView1 = (TextView) mActivity.findViewById(R.id.headerview1);
         final TextView headerView2 = (TextView) mActivity.findViewById(R.id.headerview2);
+        mInstrumentation.runOnMainSync(() ->
+                ((ViewGroup) headerView1.getParent()).removeView(headerView1));
+        mInstrumentation.runOnMainSync(() ->
+                ((ViewGroup) headerView2.getParent()).removeView(headerView2));
 
         mInstrumentation.runOnMainSync(() -> mListView.setHeaderDividersEnabled(true));
         assertEquals(0, mListView.getHeaderViewsCount());
@@ -509,6 +513,7 @@
     public void testFindViewTraversal() {
         MyListView listView = new MyListView(mActivity, mAttributeSet);
         TextView headerView = (TextView) mActivity.findViewById(R.id.headerview1);
+        ((ViewGroup) headerView.getParent()).removeView(headerView);
 
         assertNull(listView.findViewTraversal(R.id.headerview1));
 
@@ -521,6 +526,7 @@
     public void testFindViewWithTagTraversal() {
         MyListView listView = new MyListView(mActivity, mAttributeSet);
         TextView headerView = (TextView) mActivity.findViewById(R.id.headerview1);
+        ((ViewGroup) headerView.getParent()).removeView(headerView);
 
         assertNull(listView.findViewWithTagTraversal("header"));
 
diff --git a/tests/tests/widget/src/android/widget/cts/TimePickerDialogCtsActivity.java b/tests/tests/widget/src/android/widget/cts/TimePickerDialogCtsActivity.java
new file mode 100644
index 0000000..f5c544b
--- /dev/null
+++ b/tests/tests/widget/src/android/widget/cts/TimePickerDialogCtsActivity.java
@@ -0,0 +1,33 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.widget.cts;
+
+import android.app.Activity;
+import android.os.Bundle;
+
+/**
+ * A minimal application for TimePickerDialog test.
+ */
+public class TimePickerDialogCtsActivity extends Activity {
+    /**
+     * Called with the activity is first created.
+     */
+    @Override
+    public void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+    }
+}
diff --git a/tests/tests/widget/src/android/widget/cts/TimePickerDialogTest.java b/tests/tests/widget/src/android/widget/cts/TimePickerDialogTest.java
new file mode 100644
index 0000000..73ddc04
--- /dev/null
+++ b/tests/tests/widget/src/android/widget/cts/TimePickerDialogTest.java
@@ -0,0 +1,72 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.widget.cts;
+
+import android.app.Activity;
+import android.app.AlertDialog;
+import android.app.DatePickerDialog;
+import android.app.TimePickerDialog;
+import android.test.ActivityInstrumentationTestCase2;
+import android.test.UiThreadTest;
+import android.widget.TimePicker;
+
+/**
+ * Test {@link TimePickerDialog}.
+ */
+public class TimePickerDialogTest extends
+        ActivityInstrumentationTestCase2<TimePickerDialogCtsActivity> {
+
+    private Activity mActivity;
+
+    public TimePickerDialogTest() {
+        super(TimePickerDialogCtsActivity.class);
+    }
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+        mActivity = getActivity();
+    }
+
+    @UiThreadTest
+    public void testConstructor() {
+        new TimePickerDialog(mActivity, null, 7, 0, true);
+
+        new TimePickerDialog(mActivity, AlertDialog.THEME_TRADITIONAL, null, 7, 0, true);
+
+        // Ensure the picker is shown using the Holo-style layout.
+        TimePickerDialog holoDialog = new TimePickerDialog(mActivity, AlertDialog.THEME_HOLO_DARK,
+                null, 7, 0, true);
+        assertEquals(TimePicker.MODE_SPINNER, holoDialog.getTimePicker().getMode());
+
+        // Ensure the picker is shown using the Material-style layout where available.
+        TimePickerDialog holoClockDialog = new TimePickerDialog(mActivity,
+                R.style.Theme_Holo_With_Material_Pickers, null, 7, 0, true);
+        final int expectedMode = mActivity.getResources().getInteger(R.integer.time_picker_mode);
+        assertEquals(expectedMode, holoClockDialog.getTimePicker().getMode());
+
+        new TimePickerDialog(mActivity,
+                android.R.style.Theme_Material_Dialog_Alert, null, 7, 0, true);
+
+        try {
+            new TimePickerDialog(null, null, 7, 0, true);
+            fail("should throw NullPointerException");
+        } catch (Exception e) {
+        }
+    }
+
+}
diff --git a/tests/vr/src/android/vr/cts/VrDisplayTest.java b/tests/vr/src/android/vr/cts/VrDisplayTest.java
index 9dfdf96..b26f4ed 100644
--- a/tests/vr/src/android/vr/cts/VrDisplayTest.java
+++ b/tests/vr/src/android/vr/cts/VrDisplayTest.java
@@ -52,18 +52,20 @@
      */
     public void testRefreshRateIsAtLeast60Hz() throws Throwable {
         final int NUM_FRAMES = 200;
-        mActivity = getGlEsActivity(NUM_FRAMES, 3);
+        // Add an extra frame to allow the activity to start up.
+        mActivity = getGlEsActivity(NUM_FRAMES + 1, 3);
         if (!mActivity.supportsVrHighPerformance())
             return;
 
-        long startNanos = System.nanoTime();
+        // Skip the first frame to allow for startup time.
+        mActivity.waitForFrameDrawn();
 
         // Render a few hundred frames.
-        int error;
+        long startNanos = System.nanoTime();
         while (!mActivity.waitForFrameDrawn());
-        error = mActivity.glGetError();
-        assertEquals(GLES32.GL_NO_ERROR, error);
         long endNanos = System.nanoTime();
+        int error = mActivity.glGetError();
+        assertEquals(GLES32.GL_NO_ERROR, error);
 
         double fps = NUM_FRAMES / (double)(endNanos - startNanos) * 1e9;
         assertTrue(fps >= 59.);
diff --git a/tools/cts-api-coverage/src/Android.mk b/tools/cts-api-coverage/src/Android.mk
index d1fe4ed..8c038dc 100644
--- a/tools/cts-api-coverage/src/Android.mk
+++ b/tools/cts-api-coverage/src/Android.mk
@@ -23,6 +23,10 @@
 LOCAL_JAVA_RESOURCE_DIRS := res 
 LOCAL_JAR_MANIFEST := MANIFEST.mf
 
+LOCAL_STATIC_JAVA_LIBRARIES := \
+  compatibility-host-util \
+  dexlib2
+
 LOCAL_MODULE := cts-api-coverage
 LOCAL_MODULE_TAGS := optional
 
diff --git a/tools/cts-api-coverage/src/MANIFEST.mf b/tools/cts-api-coverage/src/MANIFEST.mf
index b6aa831..63d6674 100644
--- a/tools/cts-api-coverage/src/MANIFEST.mf
+++ b/tools/cts-api-coverage/src/MANIFEST.mf
@@ -1,2 +1,3 @@
 Manifest-Version: 1.0
 Main-Class: com.android.cts.apicoverage.CtsApiCoverage
+Class-Path: tradefed-prebuilt.jar
diff --git a/tools/cts-api-coverage/src/com/android/cts/apicoverage/CddCoverage.java b/tools/cts-api-coverage/src/com/android/cts/apicoverage/CddCoverage.java
new file mode 100644
index 0000000..3d1a07d
--- /dev/null
+++ b/tools/cts-api-coverage/src/com/android/cts/apicoverage/CddCoverage.java
@@ -0,0 +1,112 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.cts.apicoverage;
+
+import java.lang.String;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.List;
+import java.util.Set;
+
+/** Representation of the entire CDD. */
+class CddCoverage {
+
+    private final Map<String, CddRequirement> requirements = new HashMap<>();
+
+    public void addCddRequirement(CddRequirement cddRequirement) {
+        requirements.put(cddRequirement.getRequirementId(), cddRequirement);
+    }
+
+    public Collection<CddRequirement> getCddRequirements() {
+        return Collections.unmodifiableCollection(requirements.values());
+    }
+
+    public void addCoverage(String cddRequirementId, TestMethod testMethod) {
+        if (!requirements.containsKey(cddRequirementId)) {
+            requirements.put(cddRequirementId, new CddRequirement(cddRequirementId));
+        }
+
+        requirements.get(cddRequirementId).addTestMethod(testMethod);
+    }
+
+    static class CddRequirement {
+        private final String mRequirementId;
+        private final List<TestMethod> mtestMethods;
+
+        CddRequirement(String requirementId) {
+            this.mRequirementId = requirementId;
+            this.mtestMethods = new ArrayList<>();
+        }
+
+        @Override
+        public boolean equals(Object other) {
+            if (other == null) {
+                return false;
+            } else if (!(other instanceof CddRequirement)) {
+                return false;
+            } else {
+                return mRequirementId.equals(((CddRequirement)other).mRequirementId);
+            }
+        }
+
+        @Override
+        public int hashCode() {
+            return mRequirementId.hashCode();
+        }
+
+        @Override
+        public String toString() {
+            return String.format("Requirement %s %s", mRequirementId, mtestMethods);
+        }
+
+        public String getRequirementId() { return mRequirementId; }
+
+        public void addTestMethod(TestMethod testMethod) {
+            mtestMethods.add(testMethod);
+        }
+
+        public Collection<TestMethod> getTestMethods() {
+            return Collections.unmodifiableCollection(mtestMethods);
+        }
+    }
+
+    static class TestMethod {
+        private final String mTestModule;
+        private final String mTestClass;
+        private final String mTestMethod;
+
+        TestMethod(String testModule, String testClass, String testMethod) {
+            this.mTestModule = testModule;
+            this.mTestClass = testClass;
+            this.mTestMethod = testMethod;
+        }
+
+        public String getTestModule() { return mTestModule; }
+
+        public String getTestClass() { return mTestClass; }
+
+        public String getTestMethod() { return mTestMethod; }
+
+        @Override
+        public String toString() {
+            return String.format("%s %s#%s", mTestModule, mTestClass, mTestMethod);
+        }
+    }
+}
diff --git a/tools/cts-api-coverage/src/com/android/cts/apicoverage/CtsApiCoverage.java b/tools/cts-api-coverage/src/com/android/cts/apicoverage/CtsApiCoverage.java
index 6b69a57..2b57c76 100644
--- a/tools/cts-api-coverage/src/com/android/cts/apicoverage/CtsApiCoverage.java
+++ b/tools/cts-api-coverage/src/com/android/cts/apicoverage/CtsApiCoverage.java
@@ -16,6 +16,19 @@
 
 package com.android.cts.apicoverage;
 
+import com.android.compatibility.common.util.CddTest;
+
+import org.jf.dexlib2.DexFileFactory;
+import org.jf.dexlib2.DexFileFactory.DexFileNotFound;
+import org.jf.dexlib2.DexFileFactory.MultipleDexFilesException;
+import org.jf.dexlib2.Opcodes;
+import org.jf.dexlib2.iface.Annotation;
+import org.jf.dexlib2.iface.AnnotationElement;
+import org.jf.dexlib2.iface.ClassDef;
+import org.jf.dexlib2.iface.DexFile;
+import org.jf.dexlib2.iface.Method;
+import org.jf.dexlib2.iface.value.StringEncodedValue;
+
 import org.xml.sax.InputSource;
 import org.xml.sax.SAXException;
 import org.xml.sax.XMLReader;
@@ -29,7 +42,9 @@
 import java.io.OutputStream;
 import java.util.Arrays;
 import java.util.ArrayList;
+import java.util.Collection;
 import java.util.List;
+import java.util.Set;
 
 import javax.xml.transform.TransformerException;
 
@@ -52,6 +67,10 @@
 
     private static final int FORMAT_HTML = 2;
 
+    private static final String CDD_REQUIREMENT_ANNOTATION = "Lcom/android/compatibility/common/util/CddTest;";
+
+    private static final String CDD_REQUIREMENT_ELEMENT_NAME = "requirement";
+
     private static void printUsage() {
         System.out.println("Usage: cts-api-coverage [OPTION]... [APK]...");
         System.out.println();
@@ -70,6 +89,7 @@
         System.out.println("  -a PATH                path to the API XML file");
         System.out.println("  -p PACKAGENAMEPREFIX   report coverage only for package that start with");
         System.out.println("  -t TITLE               report title");
+        System.out.println("  -a API                 the Android API Level");
         System.out.println();
         System.exit(1);
     }
@@ -82,6 +102,7 @@
         String apiXmlPath = "";
         PackageFilter packageFilter = new PackageFilter();
         String reportTitle = "CTS API Coverage";
+        int apiLevel = Integer.MAX_VALUE;
 
         for (int i = 0; i < args.length; i++) {
             if (args[i].startsWith("-")) {
@@ -106,6 +127,8 @@
                     packageFilter.addPrefixToFilter(getExpectedArg(args, ++i));
                 } else if ("-t".equals(args[i])) {
                     reportTitle = getExpectedArg(args, ++i);
+                } else if ("-a".equals(args[i])) {
+                    apiLevel = Integer.parseInt(getExpectedArg(args, ++i));
                 } else {
                     printUsage();
                 }
@@ -131,12 +154,16 @@
          */
 
         ApiCoverage apiCoverage = getEmptyApiCoverage(apiXmlPath);
+        CddCoverage cddCoverage = getEmptyCddCoverage();
         // Add superclass information into api coverage.
         apiCoverage.resolveSuperClasses();
         for (File testApk : testApks) {
             addApiCoverage(apiCoverage, testApk, dexDeps);
+            addCddCoverage(cddCoverage, testApk, apiLevel);
         }
-        outputCoverageReport(apiCoverage, testApks, outputFile, format, packageFilter, reportTitle);
+
+        outputCoverageReport(apiCoverage, cddCoverage, testApks, outputFile,
+            format, packageFilter, reportTitle);
     }
 
     /** Get the argument or print out the usage and exit. */
@@ -202,8 +229,106 @@
         }
     }
 
-    private static void outputCoverageReport(ApiCoverage apiCoverage, List<File> testApks,
-            File outputFile, int format, PackageFilter packageFilter, String reportTitle)
+    private static void addCddCoverage(CddCoverage cddCoverage, File testSource, int api)
+            throws IOException {
+
+        if (testSource.getName().endsWith(".apk")) {
+            addCddApkCoverage(cddCoverage, testSource, api);
+        } else if (testSource.getName().endsWith(".jar")) {
+            addCddJarCoverage(cddCoverage, testSource);
+        } else {
+            System.err.println("Unsupported file type for CDD coverage: " + testSource.getPath());
+        }
+    }
+
+    private static void addCddJarCoverage(CddCoverage cddCoverage, File testSource)
+            throws IOException {
+
+        Collection<Class<?>> classes = JarTestFinder.getClasses(testSource);
+        for (Class<?> c : classes) {
+            for (java.lang.reflect.Method m : c.getMethods()) {
+                if (m.isAnnotationPresent(CddTest.class)) {
+                    CddTest cddTest = m.getAnnotation(CddTest.class);
+                    CddCoverage.TestMethod testMethod =
+                            new CddCoverage.TestMethod(
+                                    testSource.getName(), c.getName(), m.getName());
+                    cddCoverage.addCoverage(cddTest.requirement(), testMethod);
+                }
+            }
+        }
+    }
+
+    private static void addCddApkCoverage(
+        CddCoverage cddCoverage, File testSource, int api)
+            throws IOException {
+
+        DexFile dexFile = null;
+        try {
+            dexFile = DexFileFactory.loadDexFile(
+                testSource, null /*dexEntry*/, Opcodes.forApi(api));
+        } catch (IOException | DexFileFactory.DexFileNotFound e) {
+            System.err.println("Unable to load dex file: " + testSource.getPath());
+            return;
+        }
+
+        String moduleName = testSource.getName();
+        for (ClassDef classDef : dexFile.getClasses()) {
+            String className = classDef.getType();
+            handleAnnotations(
+                cddCoverage, moduleName, className, null /*methodName*/,
+                classDef.getAnnotations());
+
+            for (Method method : classDef.getMethods()) {
+                String methodName = method.getName();
+                handleAnnotations(
+                    cddCoverage, moduleName, className, methodName, method.getAnnotations());
+            }
+        }
+    }
+
+    private static void handleAnnotations(
+            CddCoverage cddCoverage, String moduleName, String className,
+                    String methodName, Set<? extends Annotation> annotations) {
+        for (Annotation annotation : annotations) {
+            if (annotation.getType().equals(CDD_REQUIREMENT_ANNOTATION)) {
+                for (AnnotationElement annotationElement : annotation.getElements()) {
+                    if (annotationElement.getName().equals(CDD_REQUIREMENT_ELEMENT_NAME)) {
+                        String cddRequirement =
+                                ((StringEncodedValue) annotationElement.getValue()).getValue();
+                        CddCoverage.TestMethod testMethod =
+                                new CddCoverage.TestMethod(
+                                        moduleName, dexToJavaName(className), methodName);
+                        cddCoverage.addCoverage(cddRequirement, testMethod);
+                    }
+                }
+            }
+        }
+    }
+
+    /**
+     * Given a string like Landroid/app/cts/DownloadManagerTest;
+     * return android.app.cts.DownloadManagerTest.
+     */
+    private static String dexToJavaName(String dexName) {
+        if (!dexName.startsWith("L") || !dexName.endsWith(";")) {
+            return dexName;
+        }
+        dexName = dexName.replace('/', '.');
+        if (dexName.length() > 2) {
+            dexName = dexName.substring(1, dexName.length() - 1);
+        }
+        return dexName;
+    }
+
+    private static CddCoverage getEmptyCddCoverage() {
+        CddCoverage cddCoverage = new CddCoverage();
+        // TODO(nicksauer): Read in the valid list of requirements
+        return cddCoverage;
+    }
+
+    private static void outputCoverageReport(ApiCoverage apiCoverage, CddCoverage cddCoverage,
+            List<File> testApks, File outputFile, int format, PackageFilter packageFilter,
+            String reportTitle)
                 throws IOException, TransformerException, InterruptedException {
 
         OutputStream out = outputFile != null
@@ -213,15 +338,17 @@
         try {
             switch (format) {
                 case FORMAT_TXT:
-                    TextReport.printTextReport(apiCoverage, packageFilter, out);
+                    TextReport.printTextReport(apiCoverage, cddCoverage, packageFilter, out);
                     break;
 
                 case FORMAT_XML:
-                    XmlReport.printXmlReport(testApks, apiCoverage, packageFilter, reportTitle, out);
+                    XmlReport.printXmlReport(testApks, apiCoverage, cddCoverage,
+                        packageFilter, reportTitle, out);
                     break;
 
                 case FORMAT_HTML:
-                    HtmlReport.printHtmlReport(testApks, apiCoverage, packageFilter, reportTitle, out);
+                    HtmlReport.printHtmlReport(testApks, apiCoverage, cddCoverage,
+                        packageFilter, reportTitle, out);
                     break;
             }
         } finally {
diff --git a/tools/cts-api-coverage/src/com/android/cts/apicoverage/HtmlReport.java b/tools/cts-api-coverage/src/com/android/cts/apicoverage/HtmlReport.java
index 0e6b54a..f53a884 100644
--- a/tools/cts-api-coverage/src/com/android/cts/apicoverage/HtmlReport.java
+++ b/tools/cts-api-coverage/src/com/android/cts/apicoverage/HtmlReport.java
@@ -37,7 +37,8 @@
 class HtmlReport {
 
     public static void printHtmlReport(final List<File> testApks, final ApiCoverage apiCoverage,
-            final PackageFilter packageFilter, final String reportTitle, final OutputStream out)
+            final CddCoverage cddCoverage, final PackageFilter packageFilter,
+            final String reportTitle, final OutputStream out)
                 throws IOException, TransformerException {
         final PipedOutputStream xmlOut = new PipedOutputStream();
         final PipedInputStream xmlIn = new PipedInputStream(xmlOut);
@@ -45,7 +46,8 @@
         Thread t = new Thread(new Runnable() {
             @Override
             public void run() {
-                XmlReport.printXmlReport(testApks, apiCoverage, packageFilter, reportTitle, xmlOut);
+                XmlReport.printXmlReport(
+                    testApks, apiCoverage, cddCoverage, packageFilter, reportTitle, xmlOut);
 
                 // Close the output stream to avoid "Write dead end" errors.
                 try {
diff --git a/tools/cts-api-coverage/src/com/android/cts/apicoverage/JarTestFinder.java b/tools/cts-api-coverage/src/com/android/cts/apicoverage/JarTestFinder.java
new file mode 100644
index 0000000..2aa3e72
--- /dev/null
+++ b/tools/cts-api-coverage/src/com/android/cts/apicoverage/JarTestFinder.java
@@ -0,0 +1,87 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.cts.apicoverage;
+
+import java.io.File;
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.lang.reflect.Modifier;
+import java.net.URL;
+import java.net.URLClassLoader;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Enumeration;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+import java.util.jar.JarEntry;
+import java.util.jar.JarFile;
+
+/** Representation of the entire CDD. */
+class JarTestFinder {
+
+    public static Collection<Class<?>> getClasses(File jarTestFile)
+            throws IllegalArgumentException  {
+        List<Class<?>> classes = new ArrayList<>();
+
+        try (JarFile jarFile = new JarFile(jarTestFile)) {
+            Enumeration<JarEntry> e = jarFile.entries();
+
+            URL[] urls = {
+                new URL(String.format("jar:file:%s!/", jarTestFile.getAbsolutePath()))
+            };
+            URLClassLoader cl = URLClassLoader.newInstance(urls, JarTestFinder.class.getClassLoader());
+
+            while (e.hasMoreElements()) {
+                JarEntry je = e.nextElement();
+                if (je.isDirectory() || !je.getName().endsWith(".class")
+                        || je.getName().contains("$")) {
+                    continue;
+                }
+                String className = getClassName(je.getName());
+                if (!className.endsWith("Test")) {
+                    continue;
+                }
+                try {
+                    Class<?> cls = cl.loadClass(className);
+                    int modifiers = cls.getModifiers();
+                    if (!Modifier.isStatic(modifiers)
+                            && !Modifier.isPrivate(modifiers)
+                            && !Modifier.isProtected(modifiers)
+                            && !Modifier.isInterface(modifiers)
+                            && !Modifier.isAbstract(modifiers)) {
+
+                        classes.add(cls);
+                    }
+                } catch (ClassNotFoundException | Error x) {
+                    System.err.println(
+                            String.format("Cannot find test class %s from %s",
+                                    className, jarTestFile.getName()));
+                    x.printStackTrace();
+                }
+            }
+        } catch (IOException e) {
+            e.printStackTrace();
+        }
+        return classes;
+    }
+
+    private static String getClassName(String name) {
+        // -6 because of .class
+        return name.substring(0, name.length() - 6).replace('/', '.');
+    }
+}
diff --git a/tools/cts-api-coverage/src/com/android/cts/apicoverage/TextReport.java b/tools/cts-api-coverage/src/com/android/cts/apicoverage/TextReport.java
index 3adc020..978a652 100644
--- a/tools/cts-api-coverage/src/com/android/cts/apicoverage/TextReport.java
+++ b/tools/cts-api-coverage/src/com/android/cts/apicoverage/TextReport.java
@@ -27,8 +27,8 @@
  */
 class TextReport {
 
-    public static void printTextReport(ApiCoverage api, PackageFilter packageFilter,
-            OutputStream outputStream) {
+    public static void printTextReport(ApiCoverage api, CddCoverage CddCoverage,
+            PackageFilter packageFilter, OutputStream outputStream) {
         PrintStream out = new PrintStream(outputStream);
 
         CoverageComparator comparator = new CoverageComparator();
diff --git a/tools/cts-api-coverage/src/com/android/cts/apicoverage/XmlReport.java b/tools/cts-api-coverage/src/com/android/cts/apicoverage/XmlReport.java
index 2ba16cf..e6ac3af 100644
--- a/tools/cts-api-coverage/src/com/android/cts/apicoverage/XmlReport.java
+++ b/tools/cts-api-coverage/src/com/android/cts/apicoverage/XmlReport.java
@@ -33,7 +33,8 @@
 class XmlReport {
 
     public static void printXmlReport(List<File> testApks, ApiCoverage apiCoverage,
-            PackageFilter packageFilter, String reportTitle, OutputStream outputStream) {
+            CddCoverage cddCoverage, PackageFilter packageFilter, String reportTitle,
+            OutputStream outputStream) {
         PrintStream out = new PrintStream(outputStream);
         out.println("<?xml version=\"1.0\" encoding=\"UTF-8\"?>");
         out.println("<?xml-stylesheet type=\"text/xsl\"  href=\"api-coverage.xsl\"?>");
@@ -137,6 +138,20 @@
         }
 
         out.println("</api>");
+        out.println("<cdd>");
+        for (CddCoverage.CddRequirement requirement : cddCoverage.getCddRequirements()) {
+            out.println("<requirement id=\"" + requirement.getRequirementId() + "\">");
+            for (CddCoverage.TestMethod method : requirement.getTestMethods()) {
+                out.print("<test module=\"" + method.getTestModule()
+                        + "\" class=\"" + method.getTestClass() + "\" ");
+                if (method.getTestMethod() != null) {
+                    out.print("method=\"" + method.getTestMethod() + "\"");
+                }
+                out.println("/>" );
+            }
+            out.println("</requirement>");
+        }
+        out.println("</cdd>");
         out.println("<total numCovered=\"" + totalCoveredMethods + "\" "
                 + "numTotal=\"" + totalMethods + "\" "
                 + "coveragePercentage=\""
diff --git a/tools/cts-device-info/src/com/android/cts/deviceinfo/SampleDeviceInfo.java b/tools/cts-device-info/src/com/android/cts/deviceinfo/SampleDeviceInfo.java
index 8d3d7ada..67db187 100644
--- a/tools/cts-device-info/src/com/android/cts/deviceinfo/SampleDeviceInfo.java
+++ b/tools/cts-device-info/src/com/android/cts/deviceinfo/SampleDeviceInfo.java
@@ -33,6 +33,7 @@
         double[] doubles = {Double.MAX_VALUE, Double.MIN_VALUE};
         int[] ints = {Integer.MAX_VALUE, Integer.MIN_VALUE};
         long[] longs = {Long.MAX_VALUE, Long.MIN_VALUE};
+        float[] floats = {Float.MAX_VALUE, Float.MIN_VALUE, Float.NaN};
 
         // Group Foo
         store.startGroup("foo");
@@ -49,12 +50,16 @@
         store.addArrayResult("bar_double", doubles);
         store.addArrayResult("bar_int", ints);
         store.addArrayResult("bar_long", longs);
+        store.addArrayResult("bar_float", floats);
         store.endGroup(); // bar
 
         store.addResult("foo_double", Double.MAX_VALUE);
         store.addResult("foo_int", Integer.MAX_VALUE);
         store.addResult("foo_long", Long.MAX_VALUE);
         store.addResult("foo_string", "foo-string");
+        store.addResult("foo_float_nan", Float.NaN);
+        store.addResult("foo_float_max", Float.MAX_VALUE + 1);
+        store.addResult("foo_float_min", Float.MIN_VALUE - 1);
         store.endGroup(); // foo
     }
 }
diff --git a/tools/cts-tradefed/Android.mk b/tools/cts-tradefed/Android.mk
index bb4b934..a9bb07b 100644
--- a/tools/cts-tradefed/Android.mk
+++ b/tools/cts-tradefed/Android.mk
@@ -25,7 +25,7 @@
 LOCAL_SUITE_TARGET_ARCH := $(TARGET_ARCH)
 LOCAL_SUITE_NAME := CTS
 LOCAL_SUITE_FULLNAME := "Compatibility Test Suite"
-LOCAL_SUITE_VERSION := 7.1_r1
+LOCAL_SUITE_VERSION := 7.1_r201708s
 
 LOCAL_MODULE := cts-tradefed
 
diff --git a/tools/cts-tradefed/res/config/cts-known-failures.xml b/tools/cts-tradefed/res/config/cts-known-failures.xml
index b7fb8a8..2d4bd5c 100644
--- a/tools/cts-tradefed/res/config/cts-known-failures.xml
+++ b/tools/cts-tradefed/res/config/cts-known-failures.xml
@@ -30,6 +30,9 @@
     <!-- b/23776083 -->
     <option name="compatibility:exclude-filter" value="CtsAlarmClockTestCases" />
 
+    <!-- b/31156007 will need framework fix https://android.googlesource.com/platform/frameworks/base/+/20488d97cdc9aa7e98f6fd75c2890ba18781654a -->
+    <option name="compatibility:exclude-filter" value="CtsAppSecurityHostTestCases android.appsecurity.cts.ScopedDirectoryAccessTest#testDeniesOnceForAllClearedWhenPackageRemoved" />
+
     <!-- b/17993121 -->
     <option name="compatibility:exclude-filter" value="CtsAppWidgetTestCases android.appwidget.cts.AppWidgetTest#testAppWidgetProviderCallbacks" />
     <option name="compatibility:exclude-filter" value="CtsAppWidgetTestCases android.appwidget.cts.AppWidgetTest#testBindAppWidget" />
@@ -74,6 +77,15 @@
     <option name="compatibility:exclude-filter" value="CtsDumpsysHostTestCases android.dumpsys.cts.DumpsysHostTest#testBatterystatsOutput" />
     <option name="compatibility:exclude-filter" value="CtsDumpsysHostTestCases android.dumpsys.cts.DumpsysHostTest#testGfxinfoFramestats" />
 
+    <!-- b/31199016 will need platform fix https://android.googlesource.com/platform/frameworks/base/+/11a84b8429c2cf395b99c852d232a490ba1c9975 to pass -->
+    <option name="compatibility:exclude-filter" value="CtsGraphicsTestCases android.graphics.drawable.cts.ThemedDrawableTest#testLayerDrawable" />
+
+    <!-- b/31306911 will need platform fixes
+         https://android.googlesource.com/platform/frameworks/base/+/0a815bb94fa2aad016a10fe23633efc5682d2a7c and
+         https://android.googlesource.com/platform/frameworks/base/+/0c03664fa6acbe5c3fd11d54ab9a6792f43dda07 to pass -->
+    <option name="compatibility:exclude-filter" value="CtsGraphicsTestCases android.graphics.drawable.cts.CustomAnimationScaleListDrawableTest#testNonZeroDurationScale" />
+    <option name="compatibility:exclude-filter" value="CtsGraphicsTestCases android.graphics.drawable.cts.CustomAnimationScaleListDrawableTest#testZeroDurationScale" />
+
     <!-- b/22922206 b/27534791 -->
     <option name="compatibility:exclude-filter" value="CtsHardwareTestCases android.hardware.cts.SensorBatchingTests#testAccelerometer_50hz_batching" />
     <option name="compatibility:exclude-filter" value="CtsHardwareTestCases android.hardware.cts.SensorBatchingTests#testAccelerometer_fastest_batching" />
@@ -104,31 +116,19 @@
     <option name="compatibility:exclude-filter" value="CtsHardwareTestCases android.hardware.cts.SingleSensorTests#testMagneticFieldUncalibrated_200hz" />
     <option name="compatibility:exclude-filter" value="CtsHardwareTestCases android.hardware.cts.SingleSensorTests#testOrientation_5hz" />
 
-    <!-- b/16720689 -->
-    <option name="compatibility:exclude-filter" value="CtsJdwp org.apache.harmony.jpda.tests.jdwp.DebuggerOnDemand.OnthrowDebuggerLaunchTest#testDebuggerLaunch001" />
-    <option name="compatibility:exclude-filter" value="CtsJdwp org.apache.harmony.jpda.tests.jdwp.DebuggerOnDemand.OnthrowDebuggerLaunchTest#testDebuggerLaunch002" />
-    <option name="compatibility:exclude-filter" value="CtsJdwp org.apache.harmony.jpda.tests.jdwp.DebuggerOnDemand.OnthrowDebuggerLaunchTest#testDebuggerLaunch003" />
-    <option name="compatibility:exclude-filter" value="CtsJdwp org.apache.harmony.jpda.tests.jdwp.DebuggerOnDemand.OnthrowDebuggerLaunchTest#testDebuggerLaunch004" />
-    <option name="compatibility:exclude-filter" value="CtsJdwp org.apache.harmony.jpda.tests.jdwp.DebuggerOnDemand.OnthrowLaunchDebugger001#testDebugger002" />
-    <option name="compatibility:exclude-filter" value="CtsJdwp org.apache.harmony.jpda.tests.jdwp.DebuggerOnDemand.OnthrowLaunchDebugger002#testDebugger" />
-    <option name="compatibility:exclude-filter" value="CtsJdwp org.apache.harmony.jpda.tests.jdwp.Events.ClassUnloadTest#testClassUnloadEvent" />
-    <option name="compatibility:exclude-filter" value="CtsJdwp org.apache.harmony.jpda.tests.jdwp.Events.MonitorContendedEnteredTest#testMonitorContendedEnteredForClassMatch" />
-    <option name="compatibility:exclude-filter" value="CtsJdwp org.apache.harmony.jpda.tests.jdwp.Events.MonitorContendedEnterTest#testMonitorContendedEnterForClassMatch" />
-    <option name="compatibility:exclude-filter" value="CtsJdwp org.apache.harmony.jpda.tests.jdwp.Events.MonitorWaitedTest#testMonitorWaitedForClassExclude" />
-    <option name="compatibility:exclude-filter" value="CtsJdwp org.apache.harmony.jpda.tests.jdwp.Events.MonitorWaitedTest#testMonitorWaitedForClassMatchExact" />
-    <option name="compatibility:exclude-filter" value="CtsJdwp org.apache.harmony.jpda.tests.jdwp.Events.MonitorWaitedTest#testMonitorWaitedForClassMatchFirst" />
-    <option name="compatibility:exclude-filter" value="CtsJdwp org.apache.harmony.jpda.tests.jdwp.Events.MonitorWaitedTest#testMonitorWaitedForClassMatchSecond" />
-    <option name="compatibility:exclude-filter" value="CtsJdwp org.apache.harmony.jpda.tests.jdwp.Events.MonitorWaitedTest#testMonitorWaitedForClassOnly" />
-    <option name="compatibility:exclude-filter" value="CtsJdwp org.apache.harmony.jpda.tests.jdwp.Events.MonitorWaitTest#testMonitorWaitForClassExclude" />
-    <option name="compatibility:exclude-filter" value="CtsJdwp org.apache.harmony.jpda.tests.jdwp.Events.MonitorWaitTest#testMonitorWaitForClassMatchExact" />
-    <option name="compatibility:exclude-filter" value="CtsJdwp org.apache.harmony.jpda.tests.jdwp.Events.MonitorWaitTest#testMonitorWaitForClassMatchFirst" />
-    <option name="compatibility:exclude-filter" value="CtsJdwp org.apache.harmony.jpda.tests.jdwp.Events.MonitorWaitTest#testMonitorWaitForClassMatchSecond" />
-    <option name="compatibility:exclude-filter" value="CtsJdwp org.apache.harmony.jpda.tests.jdwp.Events.MonitorWaitTest#testMonitorWaitForClassOnly" />
-    <option name="compatibility:exclude-filter" value="CtsJdwp org.apache.harmony.jpda.tests.jdwp.ReferenceType.ClassFileVersionTest#testClassFileVersion001" />
-    <option name="compatibility:exclude-filter" value="CtsJdwp org.apache.harmony.jpda.tests.jdwp.ReferenceType.NestedTypesTest#testNestedTypes001" />
-    <option name="compatibility:exclude-filter" value="CtsJdwp org.apache.harmony.jpda.tests.jdwp.ThreadReference.StopTest#testStop001" />
-    <option name="compatibility:exclude-filter" value="CtsJdwp org.apache.harmony.jpda.tests.jdwp.VirtualMachine.HoldEventsTest#testHoldEvents001" />
-    <option name="compatibility:exclude-filter" value="CtsJdwp org.apache.harmony.jpda.tests.jdwp.VirtualMachine.ReleaseEventsTest#testReleaseEvents001" />
+    <!-- b/31153233 will need platform fix https://android.googlesource.com/platform/external/apache-harmony/+/5617ae1cb798e58748946c0fa4299f5d982c7b8b to pass -->
+    <option name="compatibility:exclude-filter" value="CtsJdwpTestCases org.apache.harmony.jpda.tests.jdwp.ClassType.NewInstanceStringTest#testNewInstanceString_ByteArrayArgConstructor" />
+    <option name="compatibility:exclude-filter" value="CtsJdwpTestCases org.apache.harmony.jpda.tests.jdwp.ClassType.NewInstanceStringTest#testNewInstanceString_ByteArrayCharsetConstructor" />
+    <option name="compatibility:exclude-filter" value="CtsJdwpTestCases org.apache.harmony.jpda.tests.jdwp.ClassType.NewInstanceStringTest#testNewInstanceString_ByteArrayIntIntCharsetConstructor" />
+    <option name="compatibility:exclude-filter" value="CtsJdwpTestCases org.apache.harmony.jpda.tests.jdwp.ClassType.NewInstanceStringTest#testNewInstanceString_ByteArrayIntIntConstructor" />
+    <option name="compatibility:exclude-filter" value="CtsJdwpTestCases org.apache.harmony.jpda.tests.jdwp.ClassType.NewInstanceStringTest#testNewInstanceString_ByteArrayIntIntStringConstructor" />
+    <option name="compatibility:exclude-filter" value="CtsJdwpTestCases org.apache.harmony.jpda.tests.jdwp.ClassType.NewInstanceStringTest#testNewInstanceString_ByteArrayStringConstructor" />
+    <option name="compatibility:exclude-filter" value="CtsJdwpTestCases org.apache.harmony.jpda.tests.jdwp.ClassType.NewInstanceStringTest#testNewInstanceString_CharArrayConstructor" />
+    <option name="compatibility:exclude-filter" value="CtsJdwpTestCases org.apache.harmony.jpda.tests.jdwp.ClassType.NewInstanceStringTest#testNewInstanceString_CharArrayIntIntConstructor" />
+    <option name="compatibility:exclude-filter" value="CtsJdwpTestCases org.apache.harmony.jpda.tests.jdwp.ClassType.NewInstanceStringTest#testNewInstanceString_IntArrayIntIntConstructor" />
+    <option name="compatibility:exclude-filter" value="CtsJdwpTestCases org.apache.harmony.jpda.tests.jdwp.ClassType.NewInstanceStringTest#testNewInstanceString_StringBufferConstructor" />
+    <option name="compatibility:exclude-filter" value="CtsJdwpTestCases org.apache.harmony.jpda.tests.jdwp.ClassType.NewInstanceStringTest#testNewInstanceString_StringBuilderConstructor" />
+    <option name="compatibility:exclude-filter" value="CtsJdwpTestCases org.apache.harmony.jpda.tests.jdwp.ClassType.NewInstanceStringTest#testNewInstanceString_StringConstructor" />
 
     <!-- b/18117279 b/21262226 b/23144425 -->
     <option name="compatibility:exclude-filter" value="CtsJobSchedulerTestCases android.jobscheduler.cts.ConnectivityConstraintTest#testConnectivityConstraintExecutes_withMobile" />
@@ -137,6 +137,24 @@
     <option name="compatibility:exclude-filter" value="CtsJobSchedulerTestCases android.jobscheduler.cts.ConnectivityConstraintTest#testUnmeteredConstraintFails_withMobile" />
     <option name="compatibility:exclude-filter" value="CtsJobSchedulerTestCases android.jobscheduler.cts.TimingConstraintsTest#testJobParameters_unexpiredDeadline" />
 
+    <!-- b/31157079 will need platform fix https://android.googlesource.com/platform/libcore/+/4149edc81ea22ef954aa443e0c70e5d3cb55341b to pass -->
+    <option name="compatibility:exclude-filter" value="CtsLibcoreTestCases libcore.java.util.TimeZoneTest#testDisplayNamesWithScript" />
+
+    <!-- b/31157557 will need platform fix https://android.googlesource.com/platform/libcore/+/7b7ce9368f104eef4cf337a8a2067e5cf345ccc0 to pass -->
+    <option name="compatibility:exclude-filter" value="CtsLibcoreTestCases libcore.java.net.SocketTest#testSocketTestAllAddresses" />
+
+    <!-- b/31305368 will need platform fix https://android.googlesource.com/platform/external/conscrypt/+/f24631e45c6bef8135cd9e82bfb30cf56fd8acb6 to pass -->
+    <option name="compatibility:exclude-filter" value="CtsLibcoreTestCases libcore.javax.crypto.MacTest#testMac_correctAlias" />
+
+    <!-- b/31151341 will need platform fix https://android.googlesource.com/platform/libcore/+/4a2b94a98213fcf628f6d4de034a109695d908cc to pass -->
+    <option name="compatibility:exclude-filter" value="CtsLibcoreTestCases libcore.net.MimeUtilsTest#test_30793548" />
+
+    <!-- b/31155940 will need platform fix https://android.googlesource.com/platform/libcore/+/08e9e364940586cb242839c8f0e303b82438f58b to pass -->
+    <option name="compatibility:exclude-filter" value="CtsLibcoreTestCases org.apache.harmony.tests.java.util.VectorTest#test_listIterator_addAndPrevious" />
+
+    <!-- b/31535558 will need platform fix https://android.googlesource.com/platform/frameworks/base/+/4e82fe51207bbd8ceaec356b4215e338ec63a31e to pass -->
+    <option name="compatibility:exclude-filter" value="CtsLocationTestCases android.location.cts.GnssStatusTest#testGnssStatusChanges" />
+
     <!-- b/25850508 -->
     <option name="compatibility:exclude-filter" value="CtsMediaStressTestCases android.mediastress.cts.preconditions.MediaPreparerTest#testCopyMediaFiles" />
     <option name="compatibility:exclude-filter" value="CtsMediaStressTestCases android.mediastress.cts.preconditions.MediaPreparerTest#testMediaFilesExistOnDeviceFalse" />
@@ -165,6 +183,9 @@
     <!-- b/18091590 -->
     <option name="compatibility:exclude-filter" value="CtsOpenGlPerfTestCases android.openglperf.cts.GlVboPerfTest#testVboWithVaryingIndexBufferNumbers" />
 
+    <!-- b/31306874 will need platform fix https://android.googlesource.com/platform/frameworks/base/+/5eb91a437c551ed0c66b38299f988f8159ada207 to pass -->
+    <option name="compatibility:exclude-filter" value="CtsOsTestCases android.os.cts.AsyncTaskTest#testCancellationWithException" />
+
     <!-- b/23192492 -->
     <option name="compatibility:exclude-filter" value="CtsPermission2TestCases android.permission2.cts.ProtectedBroadcastsTest#testSendProtectedBroadcasts" />
 
@@ -209,6 +230,9 @@
     <option name="compatibility:exclude-filter" value="CtsUsageStatsTestCases android.app.usage.cts.UsageStatsTest#testPackageUsageStatsIntervals" />
     <option name="compatibility:exclude-filter" value="CtsUsageStatsTestCases android.app.usage.cts.UsageStatsTest#testUsageEventsParceling" />
 
+    <!-- b/31469490 -->
+    <option name="compatibility:exclude-filter" value="CtsViewTestCases android.view.cts.DragDropTest" />
+
     <!-- b/23238984 -->
     <option name="compatibility:exclude-filter" value="CtsVoiceSettingsTestCases android.voicesettings.cts.ZenModeTest#testAll" />