Merge "Cover more PendingIntent whitelist scenarios." into nyc-mr1-dev
diff --git a/apps/CameraITS/pymodules/its/objects.py b/apps/CameraITS/pymodules/its/objects.py
index ac384fb..58fe4ec 100644
--- a/apps/CameraITS/pymodules/its/objects.py
+++ b/apps/CameraITS/pymodules/its/objects.py
@@ -71,7 +71,7 @@
         return float(r["numerator"]) / float(r["denominator"])
 
 def manual_capture_request(
-        sensitivity, exp_time, linear_tonemap=False, props=None):
+        sensitivity, exp_time, f_distance = 0.0, linear_tonemap=False, props=None):
     """Return a capture request with everything set to manual.
 
     Uses identity/unit color correction, and the default tonemap curve.
@@ -81,6 +81,7 @@
         sensitivity: The sensitivity value to populate the request with.
         exp_time: The exposure time, in nanoseconds, to populate the request
             with.
+        f_distance: The focus distance to populate the request with.
         linear_tonemap: [Optional] whether a linear tonemap should be used
             in this request.
         props: [Optional] the object returned from
@@ -105,6 +106,7 @@
         "android.colorCorrection.transform":
                 int_to_rational([1,0,0, 0,1,0, 0,0,1]),
         "android.colorCorrection.gains": [1,1,1,1],
+        "android.lens.focusDistance" : f_distance,
         "android.tonemap.mode": 1,
         "android.shading.mode": 1
         }
diff --git a/apps/CameraITS/tests/scene1/test_auto_vs_manual.py b/apps/CameraITS/tests/scene1/test_auto_vs_manual.py
index a9efa0b..c5f5e29 100644
--- a/apps/CameraITS/tests/scene1/test_auto_vs_manual.py
+++ b/apps/CameraITS/tests/scene1/test_auto_vs_manual.py
@@ -56,7 +56,7 @@
         print "Auto transform:", xform_a
 
         # Manual capture 1: WB
-        req = its.objects.manual_capture_request(sens, exp)
+        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)
diff --git a/apps/CameraITS/tests/scene1/test_crop_region_raw.py b/apps/CameraITS/tests/scene1/test_crop_region_raw.py
index 7973755..f2d788e 100644
--- a/apps/CameraITS/tests/scene1/test_crop_region_raw.py
+++ b/apps/CameraITS/tests/scene1/test_crop_region_raw.py
@@ -64,7 +64,7 @@
         # Use a manual request with a linear tonemap so that the YUV and RAW
         # should look the same (once converted by the its.image module).
         e, s = its.target.get_target_exposure_combos(cam)["minSensitivity"]
-        req = its.objects.manual_capture_request(s,e, True, props)
+        req = its.objects.manual_capture_request(s,e, 0.0, True, props)
         cap1_raw, cap1_yuv = cam.do_capture(req, cam.CAP_RAW_YUV)
 
         # Capture with a crop region.
diff --git a/apps/CameraITS/tests/scene1/test_dng_noise_model.py b/apps/CameraITS/tests/scene1/test_dng_noise_model.py
index 51270b6..2e3ecbb5 100644
--- a/apps/CameraITS/tests/scene1/test_dng_noise_model.py
+++ b/apps/CameraITS/tests/scene1/test_dng_noise_model.py
@@ -54,7 +54,7 @@
         # Expose for the scene with min sensitivity
         sens_min, sens_max = props['android.sensor.info.sensitivityRange']
         sens_step = (sens_max - sens_min) / NUM_STEPS
-        s_ae,e_ae,_,_,_  = cam.do_3a(get_results=True)
+        s_ae,e_ae,_,_,f_dist  = cam.do_3a(get_results=True)
         s_e_prod = s_ae * e_ae
         sensitivities = range(sens_min, sens_max, sens_step)
 
@@ -64,7 +64,7 @@
 
             # Capture a raw frame with the desired sensitivity.
             exp = int(s_e_prod / float(sens))
-            req = its.objects.manual_capture_request(sens, exp)
+            req = its.objects.manual_capture_request(sens, exp, f_dist)
             cap = cam.do_capture(req, cam.CAP_RAW)
 
             # Test each raw color channel (R, GR, GB, B):
diff --git a/apps/CameraITS/tests/scene1/test_exposure.py b/apps/CameraITS/tests/scene1/test_exposure.py
index dc4a790..6299f79 100644
--- a/apps/CameraITS/tests/scene1/test_exposure.py
+++ b/apps/CameraITS/tests/scene1/test_exposure.py
@@ -62,7 +62,8 @@
             s_test = round(s*m)
             e_test = s_e_product / s_test
             print "Testing s:", s_test, "e:", e_test
-            req = its.objects.manual_capture_request(s_test, e_test, True, props)
+            req = its.objects.manual_capture_request(
+                    s_test, e_test, 0.0, True, props)
             cap = cam.do_capture(req)
             s_res = cap["metadata"]["android.sensor.sensitivity"]
             e_res = cap["metadata"]["android.sensor.exposureTime"]
diff --git a/apps/CameraITS/tests/scene1/test_jpeg.py b/apps/CameraITS/tests/scene1/test_jpeg.py
index 7bc038d..6b14411 100644
--- a/apps/CameraITS/tests/scene1/test_jpeg.py
+++ b/apps/CameraITS/tests/scene1/test_jpeg.py
@@ -33,7 +33,7 @@
                              its.caps.per_frame_control(props))
 
         e, s = its.target.get_target_exposure_combos(cam)["midExposureTime"]
-        req = its.objects.manual_capture_request(s, e, True, props)
+        req = its.objects.manual_capture_request(s, e, 0.0, True, props)
 
         # YUV
         size = its.objects.get_available_output_sizes("yuv", props)[0]
diff --git a/apps/CameraITS/tests/scene1/test_latching.py b/apps/CameraITS/tests/scene1/test_latching.py
index a7da421..6e42c23 100644
--- a/apps/CameraITS/tests/scene1/test_latching.py
+++ b/apps/CameraITS/tests/scene1/test_latching.py
@@ -44,20 +44,20 @@
         b_means = []
 
         reqs = [
-            its.objects.manual_capture_request(s,  e,   True, props),
-            its.objects.manual_capture_request(s,  e,   True, props),
-            its.objects.manual_capture_request(s*2,e,   True, props),
-            its.objects.manual_capture_request(s*2,e,   True, props),
-            its.objects.manual_capture_request(s,  e,   True, props),
-            its.objects.manual_capture_request(s,  e,   True, props),
-            its.objects.manual_capture_request(s,  e*2, True, props),
-            its.objects.manual_capture_request(s,  e,   True, props),
-            its.objects.manual_capture_request(s*2,e,   True, props),
-            its.objects.manual_capture_request(s,  e,   True, props),
-            its.objects.manual_capture_request(s,  e*2, True, props),
-            its.objects.manual_capture_request(s,  e,   True, props),
-            its.objects.manual_capture_request(s,  e*2, True, props),
-            its.objects.manual_capture_request(s,  e*2, True, props),
+            its.objects.manual_capture_request(s,  e,   0.0, True, props),
+            its.objects.manual_capture_request(s,  e,   0.0, True, props),
+            its.objects.manual_capture_request(s*2,e,   0.0, True, props),
+            its.objects.manual_capture_request(s*2,e,   0.0, True, props),
+            its.objects.manual_capture_request(s,  e,   0.0, True, props),
+            its.objects.manual_capture_request(s,  e,   0.0, True, props),
+            its.objects.manual_capture_request(s,  e*2, 0.0, True, props),
+            its.objects.manual_capture_request(s,  e,   0.0, True, props),
+            its.objects.manual_capture_request(s*2,e,   0.0, True, props),
+            its.objects.manual_capture_request(s,  e,   0.0, True, props),
+            its.objects.manual_capture_request(s,  e*2, 0.0, True, props),
+            its.objects.manual_capture_request(s,  e,   0.0, True, props),
+            its.objects.manual_capture_request(s,  e*2, 0.0, True, props),
+            its.objects.manual_capture_request(s,  e*2, 0.0, True, props),
             ]
 
         caps = cam.do_capture(reqs, fmt)
diff --git a/apps/CameraITS/tests/scene1/test_param_color_correction.py b/apps/CameraITS/tests/scene1/test_param_color_correction.py
index 09b3707..8623426 100644
--- a/apps/CameraITS/tests/scene1/test_param_color_correction.py
+++ b/apps/CameraITS/tests/scene1/test_param_color_correction.py
@@ -42,7 +42,7 @@
 
         # Baseline request
         e, s = its.target.get_target_exposure_combos(cam)["midSensitivity"]
-        req = its.objects.manual_capture_request(s, e, True, props)
+        req = its.objects.manual_capture_request(s, e, 0.0, True, props)
         req["android.colorCorrection.mode"] = 0
 
         # Transforms:
diff --git a/apps/CameraITS/tests/scene1/test_param_exposure_time.py b/apps/CameraITS/tests/scene1/test_param_exposure_time.py
index 0c0aab1..576516c 100644
--- a/apps/CameraITS/tests/scene1/test_param_exposure_time.py
+++ b/apps/CameraITS/tests/scene1/test_param_exposure_time.py
@@ -39,7 +39,7 @@
 
         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, True, props)
+            req = its.objects.manual_capture_request(s, e * e_mult, 0.0, True, props)
             cap = cam.do_capture(req)
             img = its.image.convert_capture_to_rgb_image(cap)
             its.image.write_image(
diff --git a/apps/CameraITS/tests/scene1/test_param_flash_mode.py b/apps/CameraITS/tests/scene1/test_param_flash_mode.py
index 38f864f..5ef6fd6 100644
--- a/apps/CameraITS/tests/scene1/test_param_flash_mode.py
+++ b/apps/CameraITS/tests/scene1/test_param_flash_mode.py
@@ -39,7 +39,7 @@
         # linear tonemap.
         e, s = its.target.get_target_exposure_combos(cam)["midExposureTime"]
         e /= 4
-        req = its.objects.manual_capture_request(s, e, True, props)
+        req = its.objects.manual_capture_request(s, e, 0.0, True, props)
 
         for f in [0,1,2]:
             req["android.flash.mode"] = f
diff --git a/apps/CameraITS/tests/scene1/test_raw_burst_sensitivity.py b/apps/CameraITS/tests/scene1/test_raw_burst_sensitivity.py
index e176312..1d2a6b1 100644
--- a/apps/CameraITS/tests/scene1/test_raw_burst_sensitivity.py
+++ b/apps/CameraITS/tests/scene1/test_raw_burst_sensitivity.py
@@ -47,14 +47,14 @@
         # Digital gains might not be visible on RAW data
         sens_max = props['android.sensor.maxAnalogSensitivity']
         sens_step = (sens_max - sens_min) / NUM_STEPS
-        s_ae,e_ae,_,_,_  = cam.do_3a(get_results=True)
+        s_ae,e_ae,_,_,f_dist  = cam.do_3a(get_results=True)
         s_e_prod = s_ae * e_ae
 
         reqs = []
         settings = []
         for s in range(sens_min, sens_max, sens_step):
             e = int(s_e_prod / float(s))
-            req = its.objects.manual_capture_request(s, e)
+            req = its.objects.manual_capture_request(s, e, f_dist)
             reqs.append(req)
             settings.append((s,e))
 
diff --git a/apps/CameraITS/tests/scene1/test_raw_sensitivity.py b/apps/CameraITS/tests/scene1/test_raw_sensitivity.py
index cc0ce14..e49ee34 100644
--- a/apps/CameraITS/tests/scene1/test_raw_sensitivity.py
+++ b/apps/CameraITS/tests/scene1/test_raw_sensitivity.py
@@ -45,14 +45,14 @@
         # Digital gains might not be visible on RAW data
         sens_max = props['android.sensor.maxAnalogSensitivity']
         sens_step = (sens_max - sens_min) / NUM_STEPS
-        s_ae,e_ae,_,_,_  = cam.do_3a(get_results=True)
+        s_ae,e_ae,_,_,f_dist  = cam.do_3a(get_results=True)
         s_e_prod = s_ae * e_ae
 
         variances = []
         for s in range(sens_min, sens_max, sens_step):
 
             e = int(s_e_prod / float(s))
-            req = its.objects.manual_capture_request(s, e)
+            req = its.objects.manual_capture_request(s, e, f_dist)
 
             # Capture raw+yuv, but only look at the raw.
             cap,_ = cam.do_capture(req, cam.CAP_RAW_YUV)
diff --git a/apps/CameraITS/tests/scene1/test_tonemap_sequence.py b/apps/CameraITS/tests/scene1/test_tonemap_sequence.py
index 54d3d65..0db70b8 100644
--- a/apps/CameraITS/tests/scene1/test_tonemap_sequence.py
+++ b/apps/CameraITS/tests/scene1/test_tonemap_sequence.py
@@ -35,12 +35,12 @@
                              its.caps.manual_post_proc(props) and
                              its.caps.per_frame_control(props))
 
-        sens, exp_time, _,_,_ = cam.do_3a(do_af=False,get_results=True)
+        sens, exp_time, _,_,f_dist = cam.do_3a(do_af=True,get_results=True)
 
         means = []
 
         # Capture 3 manual shots with a linear tonemap.
-        req = its.objects.manual_capture_request(sens, exp_time, True, props)
+        req = its.objects.manual_capture_request(sens, exp_time, f_dist, True, props)
         for i in [0,1,2]:
             cap = cam.do_capture(req)
             img = its.image.convert_capture_to_rgb_image(cap)
@@ -49,7 +49,7 @@
             means.append(tile.mean(0).mean(0))
 
         # Capture 3 manual shots with the default tonemap.
-        req = its.objects.manual_capture_request(sens, exp_time, False)
+        req = its.objects.manual_capture_request(sens, exp_time, f_dist, False)
         for i in [3,4,5]:
             cap = cam.do_capture(req)
             img = its.image.convert_capture_to_rgb_image(cap)
diff --git a/apps/CameraITS/tests/scene1/test_yuv_jpeg_all.py b/apps/CameraITS/tests/scene1/test_yuv_jpeg_all.py
index 0c428fc..0d3726d 100644
--- a/apps/CameraITS/tests/scene1/test_yuv_jpeg_all.py
+++ b/apps/CameraITS/tests/scene1/test_yuv_jpeg_all.py
@@ -35,7 +35,7 @@
         # Use a manual request with a linear tonemap so that the YUV and JPEG
         # should look the same (once converted by the its.image module).
         e, s = its.target.get_target_exposure_combos(cam)["midExposureTime"]
-        req = its.objects.manual_capture_request(s, e, True, props)
+        req = its.objects.manual_capture_request(s, e, 0.0, True, props)
 
         rgbs = []
 
diff --git a/apps/CameraITS/tests/scene1/test_yuv_plus_jpeg.py b/apps/CameraITS/tests/scene1/test_yuv_plus_jpeg.py
index 78378eb..f559c2b 100644
--- a/apps/CameraITS/tests/scene1/test_yuv_plus_jpeg.py
+++ b/apps/CameraITS/tests/scene1/test_yuv_plus_jpeg.py
@@ -41,7 +41,7 @@
         # Use a manual request with a linear tonemap so that the YUV and JPEG
         # should look the same (once converted by the its.image module).
         e, s = its.target.get_target_exposure_combos(cam)["midExposureTime"]
-        req = its.objects.manual_capture_request(s, e, True, props)
+        req = its.objects.manual_capture_request(s, e, 0.0, True, props)
 
         cap_yuv, cap_jpeg = cam.do_capture(req, [fmt_yuv, fmt_jpeg])
 
diff --git a/apps/CameraITS/tests/scene1/test_yuv_plus_raw.py b/apps/CameraITS/tests/scene1/test_yuv_plus_raw.py
index bfa6a28..a5ceaba 100644
--- a/apps/CameraITS/tests/scene1/test_yuv_plus_raw.py
+++ b/apps/CameraITS/tests/scene1/test_yuv_plus_raw.py
@@ -36,7 +36,7 @@
         # Use a manual request with a linear tonemap so that the YUV and RAW
         # should look the same (once converted by the its.image module).
         e, s = its.target.get_target_exposure_combos(cam)["midExposureTime"]
-        req = its.objects.manual_capture_request(s, e, True, props)
+        req = its.objects.manual_capture_request(s, e, 0.0, True, props)
 
         max_raw_size = \
                 its.objects.get_available_output_sizes("raw", props)[0]
diff --git a/apps/CameraITS/tests/scene1/test_yuv_plus_raw10.py b/apps/CameraITS/tests/scene1/test_yuv_plus_raw10.py
index 322af10..f281089 100644
--- a/apps/CameraITS/tests/scene1/test_yuv_plus_raw10.py
+++ b/apps/CameraITS/tests/scene1/test_yuv_plus_raw10.py
@@ -36,7 +36,7 @@
         # Use a manual request with a linear tonemap so that the YUV and RAW
         # should look the same (once converted by the its.image module).
         e, s = its.target.get_target_exposure_combos(cam)["midExposureTime"]
-        req = its.objects.manual_capture_request(s, e, True, props)
+        req = its.objects.manual_capture_request(s, e, 0.0, True, props)
 
         max_raw10_size = \
                 its.objects.get_available_output_sizes("raw10", props)[0]
diff --git a/apps/CameraITS/tests/scene1/test_yuv_plus_raw12.py b/apps/CameraITS/tests/scene1/test_yuv_plus_raw12.py
index b3cca0b..5b6051a 100644
--- a/apps/CameraITS/tests/scene1/test_yuv_plus_raw12.py
+++ b/apps/CameraITS/tests/scene1/test_yuv_plus_raw12.py
@@ -36,7 +36,7 @@
         # Use a manual request with a linear tonemap so that the YUV and RAW
         # should look the same (once converted by the its.image module).
         e, s = its.target.get_target_exposure_combos(cam)["midExposureTime"]
-        req = its.objects.manual_capture_request(s, e, True, props)
+        req = its.objects.manual_capture_request(s, e, 0.0, True, props)
 
         max_raw12_size = \
                 its.objects.get_available_output_sizes("raw12", props)[0]
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 a5fc819..ec9d6e8 100644
--- a/apps/CameraITS/tests/scene4/test_aspect_ratio_and_crop.py
+++ b/apps/CameraITS/tests/scene4/test_aspect_ratio_and_crop.py
@@ -45,6 +45,8 @@
     THRES_L_CP_TEST = 0.02
     # pass/fail threshold of mini size images for crop test
     THRES_XS_CP_TEST = 0.05
+    # Crop test will allow at least THRES_MIN_PIXEL offset
+    THRES_MIN_PIXEL = 4
     PREVIEW_SIZE = (1920, 1080) # preview size
     aspect_ratio_gt = 1  # ground truth
     failed_ar = []  # streams failed the aspect ration test
@@ -84,7 +86,7 @@
         print "AWB transform", xform
         print "AF distance", focus
         req = its.objects.manual_capture_request(
-                sens, exp, True, props)
+                sens, exp, focus, True, props)
         xform_rat = its.objects.float_to_rational(xform)
         req["android.colorCorrection.gains"] = gains
         req["android.colorCorrection.transform"] = xform_rat
@@ -150,8 +152,8 @@
                 img = its.image.convert_capture_to_rgb_image(frm_iter)
                 img_name = "%s_%s_with_%s_w%d_h%d.png" \
                            % (NAME, fmt_iter, fmt_cmpr, w_iter, h_iter)
-                aspect_ratio, cc_ct, _ = measure_aspect_ratio(img, raw_avlb,
-                                                              img_name)
+                aspect_ratio, cc_ct, (cc_w, cc_h) = \
+                        measure_aspect_ratio(img, raw_avlb, img_name)
                 # check pass/fail for aspect ratio
                 # image size >= LARGE_SIZE: use THRES_L_AR_TEST
                 # image size == 0 (extreme case): THRES_XS_AR_TEST
@@ -176,14 +178,23 @@
                     # image size == 0 (extreme case): thres_xs_cp_test
                     # 0 < image size < LARGE_SIZE: scale between
                     # thres_xs_cp_test and thres_l_cp_test
+                    # Also, allow at least THRES_MIN_PIXEL off to
+                    # prevent threshold being too tight for very
+                    # small circle
                     thres_hori_cp_test = max(thres_l_cp_test,
                             thres_xs_cp_test + w_iter *
                             (thres_l_cp_test-thres_xs_cp_test)/LARGE_SIZE)
+                    min_threshold_h = THRES_MIN_PIXEL / cc_w
+                    thres_hori_cp_test = max(thres_hori_cp_test,
+                            min_threshold_h)
                     thres_range_h_cp = (cc_ct_gt["hori"]-thres_hori_cp_test,
                                         cc_ct_gt["hori"]+thres_hori_cp_test)
                     thres_vert_cp_test = max(thres_l_cp_test,
                             thres_xs_cp_test + h_iter *
                             (thres_l_cp_test-thres_xs_cp_test)/LARGE_SIZE)
+                    min_threshold_v = THRES_MIN_PIXEL / cc_h
+                    thres_vert_cp_test = max(thres_vert_cp_test,
+                            min_threshold_v)
                     thres_range_v_cp = (cc_ct_gt["vert"]-thres_vert_cp_test,
                                         cc_ct_gt["vert"]+thres_vert_cp_test)
                     if cc_ct["hori"] < thres_range_h_cp[0] \
diff --git a/common/device-side/device-info/src/com/android/compatibility/common/deviceinfo/GenericDeviceInfo.java b/common/device-side/device-info/src/com/android/compatibility/common/deviceinfo/GenericDeviceInfo.java
index b0486ef..cb4324c 100644
--- a/common/device-side/device-info/src/com/android/compatibility/common/deviceinfo/GenericDeviceInfo.java
+++ b/common/device-side/device-info/src/com/android/compatibility/common/deviceinfo/GenericDeviceInfo.java
@@ -56,6 +56,7 @@
     public static final String BUILD_VERSION_SDK_INT = "build_version_sdk_int";
     public static final String BUILD_VERSION_BASE_OS = "build_version_base_os";
     public static final String BUILD_VERSION_SECURITY_PATCH = "build_version_security_patch";
+    public static final String BUILD_REFERENCE_FINGERPRINT = "build_reference_fingerprint";
 
     private final Map<String, String> mDeviceInfo = new HashMap<>();
 
@@ -75,6 +76,8 @@
         store.addResult(BUILD_SERIAL, Build.SERIAL);
         store.addResult(BUILD_VERSION_RELEASE, Build.VERSION.RELEASE);
         store.addResult(BUILD_VERSION_SDK, Build.VERSION.SDK);
+        store.addResult(BUILD_REFERENCE_FINGERPRINT,
+                SystemProperties.get("ro.build.reference.fingerprint", ""));
 
         // Collect build fields available in API level 21
         if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
diff --git a/tools/cts-tradefed/res/config/system-status-checkers.xml b/common/host-side/tradefed/res/config/system-status-checkers.xml
similarity index 100%
rename from tools/cts-tradefed/res/config/system-status-checkers.xml
rename to common/host-side/tradefed/res/config/system-status-checkers.xml
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 1335fc6..ebdc1e6 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
@@ -485,6 +485,11 @@
     @Override
     public void testLog(String name, LogDataType type, InputStreamSource stream) {
         // This is safe to be invoked on either the master or a shard ResultReporter
+        if (isShardResultReporter()) {
+            // Shard ResultReporters forward testLog to the mMasterResultReporter
+            mMasterResultReporter.testLog(name, type, stream);
+            return;
+        }
         try {
             LogFileSaver saver = new LogFileSaver(mLogDir);
             File logFile = saver.saveAndZipLogData(name, type, stream.createInputStream());
diff --git a/common/host-side/tradefed/src/com/android/compatibility/common/tradefed/targetprep/DeviceInfoCollector.java b/common/host-side/tradefed/src/com/android/compatibility/common/tradefed/targetprep/DeviceInfoCollector.java
index b6cd48f..dd91d11 100644
--- a/common/host-side/tradefed/src/com/android/compatibility/common/tradefed/targetprep/DeviceInfoCollector.java
+++ b/common/host-side/tradefed/src/com/android/compatibility/common/tradefed/targetprep/DeviceInfoCollector.java
@@ -60,6 +60,7 @@
         BUILD_KEYS.put("cts:build_version_sdk", "ro.build.version.sdk");
         BUILD_KEYS.put("cts:build_version_base_os", "ro.build.version.base_os");
         BUILD_KEYS.put("cts:build_version_security_patch", "ro.build.version.security_patch");
+        BUILD_KEYS.put("cts:build_reference_fingerprint", "ro.build.reference.fingerprint");
     }
 
     @Option(name = CompatibilityTest.SKIP_DEVICE_INFO_OPTION,
diff --git a/hostsidetests/services/activitymanager/app/AndroidManifest.xml b/hostsidetests/services/activitymanager/app/AndroidManifest.xml
index 3523478..00c6352 100755
--- a/hostsidetests/services/activitymanager/app/AndroidManifest.xml
+++ b/hostsidetests/services/activitymanager/app/AndroidManifest.xml
@@ -159,6 +159,15 @@
             android:exported="true"
             android:launchMode="singleInstance"
         />
+        <activity android:name=".TrampolineActivity"
+                  android:exported="true"
+                  android:theme="@android:style/Theme.NoDisplay"
+        />
+        <activity-alias android:enabled="true"
+                android:exported="true"
+                android:name=".EntryPointAliasActivity"
+                android:targetActivity=".TrampolineActivity" >
+        </activity-alias>
     </application>
 </manifest>
 
diff --git a/hostsidetests/services/activitymanager/app/src/android/server/app/TrampolineActivity.java b/hostsidetests/services/activitymanager/app/src/android/server/app/TrampolineActivity.java
new file mode 100644
index 0000000..4b80482
--- /dev/null
+++ b/hostsidetests/services/activitymanager/app/src/android/server/app/TrampolineActivity.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 android.server.app;
+
+import android.os.Bundle;
+
+import static android.content.Intent.FLAG_ACTIVITY_CLEAR_TOP;
+import static android.content.Intent.FLAG_ACTIVITY_NEW_TASK;
+
+import android.content.Intent;
+
+public class TrampolineActivity extends AbstractLifecycleLogActivity {
+
+    private static final String TAG = TrampolineActivity.class.getSimpleName();
+
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        // Add a delay here to expose more easily a failure case where the real target
+        // activity is visible before it's launched, because its task is being brought
+        // to foreground. We need to verify that 'am start' is unblocked correctly.
+        try {
+            Thread.sleep(2000);
+        } catch(InterruptedException e) {}
+        Intent intent = new Intent(this, SingleTaskActivity.class);
+        intent.setFlags(FLAG_ACTIVITY_CLEAR_TOP | FLAG_ACTIVITY_NEW_TASK);
+
+        startActivity(intent);
+        finish();
+    }
+
+    @Override
+    protected String getTag() {
+        return TAG;
+    }
+}
diff --git a/hostsidetests/services/activitymanager/src/android/server/cts/ActivityManagerAmStartOptionsTests.java b/hostsidetests/services/activitymanager/src/android/server/cts/ActivityManagerAmStartOptionsTests.java
new file mode 100644
index 0000000..0083be4
--- /dev/null
+++ b/hostsidetests/services/activitymanager/src/android/server/cts/ActivityManagerAmStartOptionsTests.java
@@ -0,0 +1,228 @@
+/*
+ * 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.server.cts;
+
+import com.android.tradefed.device.DeviceNotAvailableException;
+
+import java.util.regex.Pattern;
+import java.util.regex.Matcher;
+
+public class ActivityManagerAmStartOptionsTests extends ActivityManagerTestBase {
+
+    private static final String TEST_ACTIVITY_NAME = "TestActivity";
+    private static final String ENTRYPOINT_ACTIVITY_NAME = "EntryPointAliasActivity";
+    private static final String SINGLE_TASK_ACTIVITY_NAME = "SingleTaskActivity";
+
+    public void testDashD() throws Exception {
+        final String[] waitForActivitiesVisible = new String[] {TEST_ACTIVITY_NAME};
+        AmStartLogcatVerifier verifier = new AmStartLogcatVerifier("android.server.app", TEST_ACTIVITY_NAME);
+
+        // Run at least 2 rounds to verify that -D works with an existing process.
+        // -D could fail in this case if the force stop of process is broken.
+        for (int i = 0; i < 2; i++) {
+            clearLogcat();
+            executeShellCommand(getAmStartCmd(TEST_ACTIVITY_NAME) + " -D");
+
+            // visibleOnly=false as the first window popping up will be the debugger window.
+            mAmWmState.computeState(mDevice, false, waitForActivitiesVisible);
+            verifier.verifyDashD();
+        }
+    }
+
+    public void testDashW_Direct() throws Exception {
+        testDashW(SINGLE_TASK_ACTIVITY_NAME, SINGLE_TASK_ACTIVITY_NAME);
+    }
+
+    public void testDashW_Indirect() throws Exception {
+        testDashW(ENTRYPOINT_ACTIVITY_NAME, SINGLE_TASK_ACTIVITY_NAME);
+    }
+
+    private void testDashW(final String entryActivity, final String actualActivity)
+            throws Exception {
+        AmStartLogcatVerifier verifier = new AmStartLogcatVerifier("android.server.app", actualActivity);
+
+        // Test cold start
+        startActivityAndVerifyResult(verifier, entryActivity, actualActivity, true);
+
+        // Test warm start
+        pressHomeButton();
+        startActivityAndVerifyResult(verifier, entryActivity, actualActivity, false);
+
+        // Test "hot" start (app already in front)
+        startActivityAndVerifyResult(verifier, entryActivity, actualActivity, false);
+    }
+
+    private static final Pattern sNotStartedWarningPattern = Pattern.compile(
+            "Warning: Activity not started(.*)");
+    private static final Pattern sStatusPattern = Pattern.compile(
+            "Status: (.*)");
+    private static final Pattern sActivityPattern = Pattern.compile(
+            "Activity: (.*)");
+    private static final String sStatusOk = "ok";
+
+    private void startActivityAndVerifyResult(
+            final AmStartLogcatVerifier verifier, final String entryActivity,
+            final String actualActivity, boolean shouldStart) throws Exception {
+        clearLogcat();
+
+        // Pass in different data only when cold starting. This is to make the intent
+        // different in subsequent warm/hot launches, so that the entrypoint alias
+        // activity is always started, but the actual activity is not started again
+        // because of the NEW_TASK and singleTask flags.
+        final String result = executeShellCommand(getAmStartCmd(entryActivity) + " -W"
+                + (shouldStart ? " -d about:blank" : ""));
+
+        // Verify shell command return value
+        verifyShellOutput(result, actualActivity, shouldStart);
+
+        // Verify adb logcat log
+        verifier.verifyDashW(shouldStart);
+    }
+
+    private void verifyShellOutput(
+            final String result, final String activity, boolean shouldStart) {
+        boolean warningFound = false;
+        String status = null;
+        String reportedActivity = null;
+        String componentActivityName = getActivityComponentName(activity);
+
+        for (String line : result.split("\\n")) {
+            Matcher matcher = sNotStartedWarningPattern.matcher(line);
+            if (matcher.matches()) {
+                warningFound = true;
+                continue;
+            }
+            matcher = sStatusPattern.matcher(line);
+            if (matcher.matches()) {
+                status = matcher.group(1);
+                continue;
+            }
+            matcher = sActivityPattern.matcher(line);
+            if (matcher.matches()) {
+                reportedActivity = matcher.group(1);
+                continue;
+            }
+        }
+
+        assertTrue("Status " + status + " is not ok", sStatusOk.equals(status));
+        assertTrue("Reported activity is " + reportedActivity + " not " + componentActivityName,
+                componentActivityName.equals(reportedActivity));
+
+        if (shouldStart && warningFound) {
+            fail("Should start new activity but brought something to front.");
+        } else if (!shouldStart && !warningFound){
+            fail("Should bring existing activity to front but started new activity.");
+        }
+    }
+
+    private static final Pattern sStartProcPattern =
+            Pattern.compile("(.+): Start proc (\\d+):(.*) for activity (.*)");
+    private static final Pattern sKillingPattern =
+            Pattern.compile("(.+): Killing (\\d+):(.*)");
+    private static final Pattern sWaitingForDebuggerPattern =
+            Pattern.compile("(.+): Application (.+) is waiting for the debugger (.*)");
+    private static final Pattern sDisplayTimePattern =
+            Pattern.compile("(.+): Displayed (.*): (\\+{0,1})([0-9]+)ms(.*)");
+
+    private class AmStartLogcatVerifier {
+        private String mPrevProcId;
+        private final String mPackageName;
+        private final String mActivityName;
+
+        AmStartLogcatVerifier(String packageName, String activityName) {
+            mPackageName = packageName;
+            mActivityName = activityName;
+        }
+
+        void verifyDashD() throws DeviceNotAvailableException {
+            boolean prevProcKilled = false;;
+            boolean waitingForDebugger = false;
+            String newProcId = null;
+            final String[] componentNames = new String[] {"ActivityManager", "ActivityThread"};
+
+            for (String line : getDeviceLogsForComponents(componentNames)) {
+                line = line.trim();
+
+                Matcher matcher = sStartProcPattern.matcher(line);
+                if (matcher.matches()) {
+                    final String activity = matcher.group(4);
+                    if (activity.contains(mActivityName)) {
+                        newProcId = matcher.group(2);
+                    }
+                    continue;
+                }
+
+                matcher = sKillingPattern.matcher(line);
+                if (matcher.matches()) {
+                    final String procId = matcher.group(2);
+                    if (procId.equals(mPrevProcId)) {
+                        prevProcKilled = true;
+                    }
+                    continue;
+                }
+
+                matcher = sWaitingForDebuggerPattern.matcher(line);
+                if (matcher.matches()) {
+                    final String packageName = matcher.group(2);
+                    if (packageName.equals(mPackageName)) {
+                        waitingForDebugger = true;
+                    }
+                    continue;
+                }
+            }
+
+            assertTrue("Didn't kill exisiting proc " + mPrevProcId + ".",
+                    mPrevProcId == null || prevProcKilled);
+            assertTrue("Didn't start new proc.", newProcId != null);
+            assertTrue("Didn't wait for debugger.", waitingForDebugger);
+
+            mPrevProcId = newProcId;
+        }
+
+        void verifyDashW(boolean shouldStart) throws DeviceNotAvailableException {
+            int displayCount = 0;
+            String activityName = null;
+
+            for (String line : getDeviceLogsForComponent("ActivityManager")) {
+                line = line.trim();
+
+                Matcher matcher = sDisplayTimePattern.matcher(line);
+                if (matcher.matches()) {
+                    activityName = matcher.group(2);
+                    // Ignore activitiy displays from other packages, we don't
+                    // want some random activity starts to ruin our test.
+                    if (!activityName.startsWith("android.server.app")) {
+                        continue;
+                    }
+                    if (!shouldStart) {
+                        fail("Shouldn't display anything but displayed " + activityName);
+                    }
+                    displayCount++;
+                }
+            }
+            final String expectedActivityName = getActivityComponentName(mActivityName);
+            if (shouldStart) {
+                if (displayCount != 1) {
+                    fail("Should display exactly one activity but displayed " + displayCount);
+                } else if (!expectedActivityName.equals(activityName)) {
+                    fail("Should display " + expectedActivityName +
+                            " but displayed " + activityName);
+                }
+            }
+        }
+    }
+}
diff --git a/hostsidetests/services/activitymanager/src/android/server/cts/ActivityManagerTestBase.java b/hostsidetests/services/activitymanager/src/android/server/cts/ActivityManagerTestBase.java
index 04b0653..067f873 100644
--- a/hostsidetests/services/activitymanager/src/android/server/cts/ActivityManagerTestBase.java
+++ b/hostsidetests/services/activitymanager/src/android/server/cts/ActivityManagerTestBase.java
@@ -74,6 +74,8 @@
 
     private static final String AM_MOVE_TASK = "am stack movetask ";
 
+    private static final String INPUT_KEYEVENT_HOME = "input keyevent 3";
+
     /** A reference to the device under test. */
     protected ITestDevice mDevice;
 
@@ -182,6 +184,10 @@
                 + " 0 0 " + taskWidth + " " + taskHeight);
     }
 
+    protected void pressHomeButton() throws DeviceNotAvailableException {
+        executeShellCommand(INPUT_KEYEVENT_HOME);
+    }
+
     // Utility method for debugging, not used directly here, but useful, so kept around.
     protected void printStacksAndTasks() throws DeviceNotAvailableException {
         CollectingOutputReceiver outputReceiver = new CollectingOutputReceiver();
@@ -395,10 +401,20 @@
         }
     }
 
-    private String[] getDeviceLogsForActivity(String activityName)
+    protected String[] getDeviceLogsForComponent(String componentName)
             throws DeviceNotAvailableException {
-        return mDevice.executeAdbCommand("logcat", "-v", "brief", "-d", activityName + ":I", "*:S")
-                .split("\\n");
+        return mDevice.executeAdbCommand(
+                "logcat", "-v", "brief", "-d", componentName + ":I", "*:S").split("\\n");
+    }
+
+    protected String[] getDeviceLogsForComponents(final String[] componentNames)
+            throws DeviceNotAvailableException {
+        String filters = "";
+        for (int i = 0; i < componentNames.length; i++) {
+            filters += componentNames[i] + ":I ";
+        }
+        return mDevice.executeAdbCommand(
+                "logcat", "-v", "brief", "-d", filters, "*:S").split("\\n");
     }
 
     private static final Pattern sCreatePattern = Pattern.compile("(.+): onCreate");
@@ -422,7 +438,7 @@
 
     protected ReportedSizes getLastReportedSizesForActivity(String activityName)
             throws DeviceNotAvailableException {
-        final String[] lines = getDeviceLogsForActivity(activityName);
+        final String[] lines = getDeviceLogsForComponent(activityName);
         for (int i = lines.length - 1; i >= 0; i--) {
             final String line = lines[i].trim();
             final Matcher matcher = sNewConfigPattern.matcher(line);
@@ -446,7 +462,7 @@
         int mDestroyCount;
 
         public ActivityLifecycleCounts(String activityName) throws DeviceNotAvailableException {
-            for (String line : getDeviceLogsForActivity(activityName)) {
+            for (String line : getDeviceLogsForComponent(activityName)) {
                 line = line.trim();
 
                 Matcher matcher = sCreatePattern.matcher(line);
diff --git a/hostsidetests/services/activitymanager/src/android/server/cts/WindowManagerState.java b/hostsidetests/services/activitymanager/src/android/server/cts/WindowManagerState.java
index 3f66c18..a057013 100644
--- a/hostsidetests/services/activitymanager/src/android/server/cts/WindowManagerState.java
+++ b/hostsidetests/services/activitymanager/src/android/server/cts/WindowManagerState.java
@@ -49,6 +49,8 @@
             "mCurrentFocus=Window\\{([0-9a-fA-F]+) u(\\d+) (\\S+)\\}");
     private static final Pattern sAppErrorFocusedWindowPattern = Pattern.compile(
             "mCurrentFocus=Window\\{([0-9a-fA-F]+) u(\\d+) Application Error\\: (\\S+)\\}");
+    private static final Pattern sWaitingForDebuggerFocusedWindowPattern = Pattern.compile(
+            "mCurrentFocus=Window\\{([0-9a-fA-F]+) u(\\d+) Waiting For Debugger\\: (\\S+)\\}");
 
     private static final Pattern sFocusedAppPattern =
             Pattern.compile("mFocusedApp=AppWindowToken\\{(.+) token=Token\\{(.+) "
@@ -58,7 +60,8 @@
 
     private static final Pattern[] sExtractStackExitPatterns = {
             sStackIdPattern, sWindowPattern, sStartingWindowPattern, sExitingWindowPattern,
-            sFocusedWindowPattern, sAppErrorFocusedWindowPattern, sFocusedAppPattern };
+            sFocusedWindowPattern, sAppErrorFocusedWindowPattern,
+            sWaitingForDebuggerFocusedWindowPattern, sFocusedAppPattern };
 
     // Windows in z-order with the top most at the front of the list.
     private List<String> mWindows = new ArrayList();
@@ -182,6 +185,15 @@
                 continue;
             }
 
+            matcher = sWaitingForDebuggerFocusedWindowPattern.matcher(line);
+            if (matcher.matches()) {
+                log(line);
+                final String focusedWindow = matcher.group(3);
+                log(focusedWindow);
+                mFocusedWindow = focusedWindow;
+                continue;
+            }
+
             matcher = sFocusedAppPattern.matcher(line);
             if (matcher.matches()) {
                 log(line);
diff --git a/hostsidetests/theme/src/android/theme/cts/ThemeHostTest.java b/hostsidetests/theme/src/android/theme/cts/ThemeHostTest.java
index 855f74c..519ad84 100644
--- a/hostsidetests/theme/src/android/theme/cts/ThemeHostTest.java
+++ b/hostsidetests/theme/src/android/theme/cts/ThemeHostTest.java
@@ -278,6 +278,7 @@
     }
 
     private static boolean checkHardwareTypeSkipTest(String hardwareTypeString) {
-        return hardwareTypeString.contains("android.hardware.type.watch");
+        return hardwareTypeString.contains("android.hardware.type.watch")
+                || hardwareTypeString.contains("android.hardware.type.television");
     }
 }
diff --git a/tests/app/src/android/app/cts/SystemFeaturesTest.java b/tests/app/src/android/app/cts/SystemFeaturesTest.java
index 864f1be..aca79fc 100644
--- a/tests/app/src/android/app/cts/SystemFeaturesTest.java
+++ b/tests/app/src/android/app/cts/SystemFeaturesTest.java
@@ -48,6 +48,8 @@
 import java.util.List;
 import java.util.Set;
 
+import junit.framework.AssertionFailedError;
+
 /**
  * Test for checking that the {@link PackageManager} is reporting the correct features.
  */
@@ -258,10 +260,18 @@
 
     public void testNfcFeatures() {
         if (NfcAdapter.getDefaultAdapter(mContext) != null) {
-            assertAvailable(PackageManager.FEATURE_NFC);
-            assertAvailable(PackageManager.FEATURE_NFC_HOST_CARD_EMULATION);
+            // Watches MAY support all FEATURE_NFC features when an NfcAdapter is available, but
+            // non-watches MUST support them both.
+            if (mPackageManager.hasSystemFeature(PackageManager.FEATURE_WATCH)) {
+                assertOneAvailable(PackageManager.FEATURE_NFC,
+                    PackageManager.FEATURE_NFC_HOST_CARD_EMULATION);
+            } else {
+                assertAvailable(PackageManager.FEATURE_NFC);
+                assertAvailable(PackageManager.FEATURE_NFC_HOST_CARD_EMULATION);
+            }
         } else {
             assertNotAvailable(PackageManager.FEATURE_NFC);
+            assertNotAvailable(PackageManager.FEATURE_NFC_HOST_CARD_EMULATION);
         }
     }
 
@@ -457,7 +467,11 @@
     }
 
     public void testUsbAccessory() {
-        assertAvailable(PackageManager.FEATURE_USB_ACCESSORY);
+        if (!mPackageManager.hasSystemFeature(PackageManager.FEATURE_AUTOMOTIVE) &&
+                !mPackageManager.hasSystemFeature(PackageManager.FEATURE_TELEVISION) &&
+                !mPackageManager.hasSystemFeature(PackageManager.FEATURE_WATCH)) {
+            assertAvailable(PackageManager.FEATURE_USB_ACCESSORY);
+        }
     }
 
     public void testWifiFeature() throws Exception {
@@ -494,6 +508,16 @@
                 mAvailableFeatures.contains(feature));
     }
 
+    private void assertOneAvailable(String feature1, String feature2) {
+        if ((mPackageManager.hasSystemFeature(feature1) && mAvailableFeatures.contains(feature1)) ||
+            (mPackageManager.hasSystemFeature(feature2) && mAvailableFeatures.contains(feature2))) {
+            return;
+        } else {
+            throw new AssertionFailedError("Must support at least one of " + feature1 + " or " +
+                feature2);
+        }
+    }
+
     private void assertFeature(boolean exist, String feature) {
         if (exist) {
             assertAvailable(feature);
diff --git a/tests/camera/src/android/hardware/camera2/cts/SurfaceViewPreviewTest.java b/tests/camera/src/android/hardware/camera2/cts/SurfaceViewPreviewTest.java
index a367d37..3c762cf 100644
--- a/tests/camera/src/android/hardware/camera2/cts/SurfaceViewPreviewTest.java
+++ b/tests/camera/src/android/hardware/camera2/cts/SurfaceViewPreviewTest.java
@@ -451,17 +451,18 @@
      * validated.
      */
     private void previewFpsRangeTestByCamera() throws Exception {
-        Size maxPreviewSz = mOrderedPreviewSizes.get(0);
+        Size maxPreviewSz;
         Range<Integer>[] fpsRanges = mStaticInfo.getAeAvailableTargetFpsRangesChecked();
         boolean antiBandingOffIsSupported = mStaticInfo.isAntiBandingOffModeSupported();
         Range<Integer> fpsRange;
         CaptureRequest.Builder requestBuilder =
                 mCamera.createCaptureRequest(CameraDevice.TEMPLATE_PREVIEW);
         SimpleCaptureCallback resultListener = new SimpleCaptureCallback();
-        startPreview(requestBuilder, maxPreviewSz, resultListener);
 
         for (int i = 0; i < fpsRanges.length; i += 1) {
             fpsRange = fpsRanges[i];
+            maxPreviewSz = getMaxPreviewSizeForFpsRange(fpsRange);
+            startPreview(requestBuilder, maxPreviewSz, resultListener);
 
             requestBuilder.set(CaptureRequest.CONTROL_AE_TARGET_FPS_RANGE, fpsRange);
             // Turn off auto antibanding to avoid exposure time and frame duration interference
@@ -482,9 +483,9 @@
 
             verifyPreviewTargetFpsRange(resultListener, NUM_FRAMES_VERIFIED, fpsRange,
                     maxPreviewSz);
+            stopPreview();
+            resultListener.drain();
         }
-
-        stopPreview();
     }
 
     private void verifyPreviewTargetFpsRange(SimpleCaptureCallback resultListener,
diff --git a/tests/tests/content/src/android/content/cts/AvailableIntentsTest.java b/tests/tests/content/src/android/content/cts/AvailableIntentsTest.java
index 03ab3cf..4452953 100644
--- a/tests/tests/content/src/android/content/cts/AvailableIntentsTest.java
+++ b/tests/tests/content/src/android/content/cts/AvailableIntentsTest.java
@@ -24,6 +24,7 @@
 import android.content.pm.ResolveInfo;
 import android.media.RingtoneManager;
 import android.net.Uri;
+import android.os.storage.StorageManager;
 import android.provider.AlarmClock;
 import android.provider.MediaStore;
 import android.provider.Settings;
@@ -243,7 +244,7 @@
         assertCanBeHandled(new Intent(DownloadManager.ACTION_VIEW_DOWNLOADS));
     }
 
-    public void testDeletionHelper() {
-        assertCanBeHandled(new Intent(Settings.ACTION_DELETION_HELPER_SETTINGS));
+    public void testManageStorage() {
+        assertCanBeHandled(new Intent(StorageManager.ACTION_MANAGE_STORAGE));
     }
 }
diff --git a/tests/tests/graphics/src/android/graphics/drawable/cts/AnimatedVectorDrawableTest.java b/tests/tests/graphics/src/android/graphics/drawable/cts/AnimatedVectorDrawableTest.java
index d678e1e..5dabdfd 100644
--- a/tests/tests/graphics/src/android/graphics/drawable/cts/AnimatedVectorDrawableTest.java
+++ b/tests/tests/graphics/src/android/graphics/drawable/cts/AnimatedVectorDrawableTest.java
@@ -152,21 +152,20 @@
                 imageView.setImageDrawable(d1);
                 d1.start();
                 d1.stop();
+                d1.setBounds(0, 0, IMAGE_WIDTH, IMAGE_HEIGHT);
+                mBitmap.eraseColor(0);
+                d1.draw(mCanvas);
             }
         });
+
         getInstrumentation().waitForIdleSync();
-
-        d1.setBounds(0, 0, IMAGE_WIDTH, IMAGE_HEIGHT);
-        mBitmap.eraseColor(0);
-        d1.draw(mCanvas);
-
         int endColor = mBitmap.getPixel(IMAGE_WIDTH / 2, IMAGE_HEIGHT / 2);
 
-        assertEquals("Center point's color must be green", 0xFF00FF00, endColor);
-
         if (DBG_DUMP_PNG) {
             saveVectorDrawableIntoPNG(mBitmap, resId);
         }
+
+        assertEquals("Center point's color must be green", 0xFF00FF00, endColor);
     }
 
     @SmallTest
diff --git a/tests/tests/jni/libjnitest/android_jni_cts_LinkerNamespacesTest.cpp b/tests/tests/jni/libjnitest/android_jni_cts_LinkerNamespacesTest.cpp
index 1407cc9..8a82706 100644
--- a/tests/tests/jni/libjnitest/android_jni_cts_LinkerNamespacesTest.cpp
+++ b/tests/tests/jni/libjnitest/android_jni_cts_LinkerNamespacesTest.cpp
@@ -45,10 +45,10 @@
 static const std::string kVendorLibraryPath = "/vendor/lib";
 #endif
 
-// This is not complete list - just a small subset
+// This is not the complete list - just a small subset
 // of the libraries that should reside in /system/lib
 // (in addition to kSystemPublicLibraries)
-static std::unordered_set<std::string> kSystemLibraries = {
+static std::vector<std::string> kSystemLibraries = {
     "libart.so",
     "libandroid_runtime.so",
     "libbinder.so",
@@ -61,39 +61,6 @@
     "libutils.so",
   };
 
-template <typename F>
-static bool for_each_file(const std::string& dir, F functor, std::string* error_msg) {
-  auto dir_deleter = [](DIR* handle) { closedir(handle); };
-  std::unique_ptr<DIR, decltype(dir_deleter)> dirp(opendir(dir.c_str()), dir_deleter);
-  if (dirp == nullptr) {
-    *error_msg = strerror(errno);
-    return false;
-  }
-
-  dirent* dp;
-  while ((dp = readdir(dirp.get())) != nullptr) {
-    // skip "." and ".."
-    if (strcmp(".", dp->d_name) == 0 ||
-        strcmp("..", dp->d_name) == 0) {
-      continue;
-    }
-
-    if (!functor(dp->d_name, error_msg)) {
-      return false;
-    }
-  }
-
-  return true;
-}
-
-static bool should_be_accessible(const std::string& public_library_path,
-                                 const std::unordered_set<std::string>& public_libraries,
-                                 const std::string& path) {
-  std::string name = basename(path.c_str());
-  return (public_libraries.find(name) != public_libraries.end()) &&
-         (public_library_path + "/" + name == path);
-}
-
 static bool is_directory(const std::string path) {
   struct stat sb;
   if (stat(path.c_str(), &sb) != -1) {
@@ -107,10 +74,18 @@
   return kSystemLibraryPath + "/libdl.so" == path;
 }
 
-static bool check_lib(const std::string& public_library_path,
-                      const std::unordered_set<std::string>& public_libraries,
-                      const std::string& path,
-                      std::string* error_msg) {
+static bool already_loaded(const std::string& library, const std::string& err) {
+  if (err.find("dlopen failed: library \"" + library + "\"") != 0 ||
+      err.find("is not accessible for the namespace \"classloader-namespace\"") == std::string::npos) {
+    return false;
+  }
+  return true;
+}
+
+static bool check_lib(const std::string& path,
+                      const std::string& library_path,
+                      const std::unordered_set<std::string>& libraries,
+                      std::vector<std::string>* errors) {
   if (is_libdl(path)) {
     // TODO (dimitry): we skip check for libdl.so because
     // 1. Linker will fail to check accessibility because it imposes as libdl.so (see http://b/27106625)
@@ -119,83 +94,99 @@
     return true;
   }
 
-  auto dlcloser = [](void* handle) { dlclose(handle); };
-  std::unique_ptr<void, decltype(dlcloser)> handle(dlopen(path.c_str(), RTLD_NOW), dlcloser);
-  if (should_be_accessible(public_library_path, public_libraries, path)) {
+  std::unique_ptr<void, int (*)(void*)> handle(dlopen(path.c_str(), RTLD_NOW), dlclose);
+
+  // The current restrictions on public libraries:
+  //  - It must exist only in the top level directory of "library_path".
+  //  - No library with the same name can be found in a sub directory.
+  //  - Each public library does not contain any directory components.
+
+  // Check if this library should be considered a public library.
+  std::string baselib = basename(path.c_str());
+  if (libraries.find(baselib) != libraries.end() &&
+      library_path + "/" + baselib == path) {
     if (handle.get() == nullptr) {
-      *error_msg = "The library \"" + path + "\" should be accessible but isn't: " + dlerror();
+      errors->push_back("The library \"" + path +
+                        "\" is a public library but it cannot be loaded: " + dlerror());
       return false;
     }
   } else if (handle.get() != nullptr) {
-    *error_msg = "The library \"" + path + "\" should not be accessible";
+    errors->push_back("The library \"" + path + "\" is not a public library but it loaded.");
     return false;
   } else { // (handle == nullptr && !shouldBeAccessible(path))
     // Check the error message
     std::string err = dlerror();
-
-    if (err.find("dlopen failed: library \"" + path + "\"") != 0 ||
-        err.find("is not accessible for the namespace \"classloader-namespace\"") == std::string::npos) {
-      *error_msg = "unexpected dlerror: " + err;
+    if (!already_loaded(path, err)) {
+      errors->push_back("unexpected dlerror: " + err);
       return false;
     }
   }
   return true;
 }
 
-static bool check_libs(const std::string& public_library_path,
-                       const std::unordered_set<std::string>& public_libraries,
-                       const std::unordered_set<std::string>& mandatory_files,
-                       std::string* error) {
-  std::list<std::string> dirs;
-  dirs.push_back(public_library_path);
-
+static bool check_path(const std::string& library_path,
+                       const std::unordered_set<std::string> libraries,
+                       std::vector<std::string>* errors) {
+  bool success = true;
+  std::list<std::string> dirs = { library_path };
   while (!dirs.empty()) {
-    const auto dir = dirs.front();
+    std::string dir = dirs.front();
     dirs.pop_front();
-    bool success = for_each_file(dir, [&](const char* name, std::string* error_msg) {
-      std::string path = dir + "/" + name;
-      if (is_directory(path)) {
-        dirs.push_back(path);
-        return true;
-      }
 
-      return check_lib(public_library_path, public_libraries, path, error_msg);
-    }, error);
-
-    if (!success) {
-      return false;
+    auto dir_deleter = [](DIR* handle) { closedir(handle); };
+    std::unique_ptr<DIR, decltype(dir_deleter)> dirp(opendir(dir.c_str()), dir_deleter);
+    if (dirp == nullptr) {
+      errors->push_back("Failed to open " + dir + ": " + strerror(errno));
+      success = false;
+      continue;
     }
 
-    // Check mandatory files - the grey list
-    for (const auto& name : mandatory_files) {
-      std::string path = public_library_path + "/" + name;
-      if (!check_lib(public_library_path, public_libraries, path, error)) {
-        return false;
+    dirent* dp;
+    while ((dp = readdir(dirp.get())) != nullptr) {
+      // skip "." and ".."
+      if (strcmp(".", dp->d_name) == 0 || strcmp("..", dp->d_name) == 0) {
+        continue;
+      }
+
+      std::string path = dir + "/" + dp->d_name;
+      if (is_directory(path)) {
+        dirs.push_back(path);
+      } else if (!check_lib(path, library_path, libraries, errors)) {
+        success = false;
       }
     }
   }
 
-  return true;
+  return success;
 }
 
 static bool jobject_array_to_set(JNIEnv* env,
                                  jobjectArray java_libraries_array,
                                  std::unordered_set<std::string>* libraries,
                                  std::string* error_msg) {
+  error_msg->clear();
   size_t size = env->GetArrayLength(java_libraries_array);
+  bool success = true;
   for (size_t i = 0; i<size; ++i) {
     ScopedLocalRef<jstring> java_soname(
         env, (jstring) env->GetObjectArrayElement(java_libraries_array, i));
     std::string soname(ScopedUtfChars(env, java_soname.get()).c_str());
 
+    // Verify that the name doesn't contain any directory components.
+    if (soname.rfind('/') != std::string::npos) {
+      *error_msg += "\n---Illegal value, no directories allowed: " + soname;
+      continue;
+    }
+
     // Check to see if the string ends in " 32" or " 64" to indicate the
     // library is only public for one bitness.
     size_t space_pos = soname.rfind(' ');
     if (space_pos != std::string::npos) {
       std::string type = soname.substr(space_pos + 1);
       if (type != "32" && type != "64") {
-        *error_msg = "public library line is malformed: " + soname;
-        return false;
+        *error_msg += "\n---Illegal value at end of line (only 32 or 64 allowed): " + soname;
+        success = false;
+        continue;
       }
 #if defined(__LP64__)
       if (type == "32") {
@@ -214,7 +205,7 @@
     libraries->insert(soname);
   }
 
-  return true;
+  return success;
 }
 
 extern "C" JNIEXPORT jstring JNICALL
@@ -223,21 +214,55 @@
         jclass clazz __attribute__((unused)),
         jobjectArray java_system_public_libraries,
         jobjectArray java_vendor_public_libraries) {
-  std::string error;
-
+  bool success = true;
+  std::vector<std::string> errors;
+  std::string error_msg;
   std::unordered_set<std::string> vendor_public_libraries;
-  std::unordered_set<std::string> system_public_libraries;
-  std::unordered_set<std::string> empty_set;
-  if (!jobject_array_to_set(env, java_vendor_public_libraries, &vendor_public_libraries, &error)) {
-    return env->NewStringUTF(("Vendor " + error).c_str());
-  }
-  if (!jobject_array_to_set(env, java_system_public_libraries, &system_public_libraries, &error)) {
-    return env->NewStringUTF(("System " + error).c_str());
+  if (!jobject_array_to_set(env, java_vendor_public_libraries, &vendor_public_libraries,
+                            &error_msg)) {
+    success = false;
+    errors.push_back("Errors in vendor public library file:" + error_msg);
   }
 
-  if (!check_libs(kSystemLibraryPath, system_public_libraries, kSystemLibraries, &error) ||
-      !check_libs(kVendorLibraryPath, vendor_public_libraries, empty_set, &error)) {
-    return env->NewStringUTF(error.c_str());
+  std::unordered_set<std::string> system_public_libraries;
+  if (!jobject_array_to_set(env, java_system_public_libraries, &system_public_libraries,
+                            &error_msg)) {
+    success = false;
+    errors.push_back("Errors in system public library file:" + error_msg);
+  }
+
+  // Check the system libraries.
+  if (!check_path(kSystemLibraryPath, system_public_libraries, &errors)) {
+    success = false;
+  }
+
+  // Check that the mandatory system libraries are present - the grey list
+  for (const auto& name : kSystemLibraries) {
+    std::string library = kSystemLibraryPath + "/" + name;
+    void* handle = dlopen(library.c_str(), RTLD_NOW);
+    if (handle == nullptr) {
+      std::string err = dlerror();
+      // If the library is already loaded, then dlopen failing is okay.
+      if (!already_loaded(library, err)) {
+          errors.push_back("Mandatory system library \"" + library + "\" failed to load: " + err);
+          success = false;
+      }
+    } else {
+      dlclose(handle);
+    }
+  }
+
+  // Check the vendor libraries.
+  if (!check_path(kVendorLibraryPath, vendor_public_libraries, &errors)) {
+    success = false;
+  }
+
+  if (!success) {
+    std::string error_str;
+    for (const auto& line : errors) {
+      error_str += line + '\n';
+    }
+    return env->NewStringUTF(error_str.c_str());
   }
 
   return nullptr;
diff --git a/tests/tests/media/assets/520x360h264decodertest.mp4 b/tests/tests/media/assets/520x360h264decodertest.mp4
new file mode 100644
index 0000000..362568c
--- /dev/null
+++ b/tests/tests/media/assets/520x360h264decodertest.mp4
Binary files differ
diff --git a/tests/tests/media/res/raw/h264decodertest520x360golden.png b/tests/tests/media/res/raw/h264decodertest520x360golden.png
new file mode 100644
index 0000000..fe4663d
--- /dev/null
+++ b/tests/tests/media/res/raw/h264decodertest520x360golden.png
Binary files differ
diff --git a/tests/tests/media/res/raw/h264decodertest520x360original.png b/tests/tests/media/res/raw/h264decodertest520x360original.png
new file mode 100644
index 0000000..c0fd752
--- /dev/null
+++ b/tests/tests/media/res/raw/h264decodertest520x360original.png
Binary files differ
diff --git a/tests/tests/media/src/android/media/cts/DecodeAccuracyTest.java b/tests/tests/media/src/android/media/cts/DecodeAccuracyTest.java
index 3f4dde0..0a3165b 100644
--- a/tests/tests/media/src/android/media/cts/DecodeAccuracyTest.java
+++ b/tests/tests/media/src/android/media/cts/DecodeAccuracyTest.java
@@ -19,98 +19,123 @@
 
 import android.annotation.TargetApi;
 import android.content.Context;
-import android.cts.util.MediaUtils;
 import android.graphics.Bitmap;
-import android.os.Build;
-import android.util.DisplayMetrics;
-import android.util.Log;
 import android.view.View;
-import android.view.WindowManager;
 
-@TargetApi(16)
+@TargetApi(24)
 public class DecodeAccuracyTest extends DecodeAccuracyTestBase {
 
     private static final String TAG = DecodeAccuracyTest.class.getSimpleName();
     private static final String H264_VIDEO_FILE_NAME = "480ph264decodertest.mp4";
     private static final String VP9_VIDEO_FILE_NAME = "360pvp9decodertest.webm";
+    private static final String H264_CROPPED_VIDEO_FILE_NAME = "520x360h264decodertest.mp4";
     private static final int ALLOWED_GREATEST_PIXEL_DIFFERENCE = 90;
     private static final int OFFSET = 10;
 
     /* <------------- Tests Using H264 -------------> */
     public void testH264GLViewVideoDecode() throws Exception {
-        runDecodeAccuracyTest(
+        runH264DecodeAccuracyTest(
                 new GLSurfaceViewFactory(),
                 new VideoFormat(H264_VIDEO_FILE_NAME));
     }
 
     public void testH264GLViewLargerHeightVideoDecode() throws Exception {
-        runDecodeAccuracyTest(
+        runH264DecodeAccuracyTest(
                 new GLSurfaceViewFactory(),
                 getLargerHeightVideoFormat(new VideoFormat(H264_VIDEO_FILE_NAME)));
     }
 
     public void testH264GLViewLargerWidthVideoDecode() throws Exception {
-        runDecodeAccuracyTest(
+        runH264DecodeAccuracyTest(
                 new GLSurfaceViewFactory(),
                 getLargerWidthVideoFormat(new VideoFormat(H264_VIDEO_FILE_NAME)));
     }
 
     public void testH264SurfaceViewVideoDecode() throws Exception {
-        runDecodeAccuracyTest(
+        runH264DecodeAccuracyTest(
                 new SurfaceViewFactory(),
                 new VideoFormat(H264_VIDEO_FILE_NAME));
     }
 
     public void testH264SurfaceViewLargerHeightVideoDecode() throws Exception {
-        runDecodeAccuracyTest(
+        runH264DecodeAccuracyTest(
                 new SurfaceViewFactory(),
                 getLargerHeightVideoFormat(new VideoFormat(H264_VIDEO_FILE_NAME)));
     }
 
     public void testH264SurfaceViewLargerWidthVideoDecode() throws Exception {
-        runDecodeAccuracyTest(
+        runH264DecodeAccuracyTest(
                 new SurfaceViewFactory(),
                 getLargerWidthVideoFormat(new VideoFormat(H264_VIDEO_FILE_NAME)));
     }
 
     /* <------------- Tests Using VP9 -------------> */
     public void testVP9GLViewVideoDecode() throws Exception {
-        runDecodeAccuracyTest(
+        runVP9DecodeAccuracyTest(
                 new GLSurfaceViewFactory(),
                 new VideoFormat(VP9_VIDEO_FILE_NAME));
     }
 
     public void testVP9GLViewLargerHeightVideoDecode() throws Exception {
-        runDecodeAccuracyTest(
+        runVP9DecodeAccuracyTest(
                 new GLSurfaceViewFactory(),
                 getLargerHeightVideoFormat(new VideoFormat(VP9_VIDEO_FILE_NAME)));
     }
 
     public void testVP9GLViewLargerWidthVideoDecode() throws Exception {
-        runDecodeAccuracyTest(
+        runVP9DecodeAccuracyTest(
                 new GLSurfaceViewFactory(),
                 getLargerWidthVideoFormat(new VideoFormat(VP9_VIDEO_FILE_NAME)));
     }
 
     public void testVP9SurfaceViewVideoDecode() throws Exception {
-        runDecodeAccuracyTest(
+        runVP9DecodeAccuracyTest(
                 new SurfaceViewFactory(),
                 new VideoFormat(VP9_VIDEO_FILE_NAME));
     }
 
     public void testVP9SurfaceViewLargerHeightVideoDecode() throws Exception {
-        runDecodeAccuracyTest(
+        runVP9DecodeAccuracyTest(
                 new SurfaceViewFactory(),
                 getLargerHeightVideoFormat(new VideoFormat(VP9_VIDEO_FILE_NAME)));
     }
 
     public void testVP9SurfaceViewLargerWidthVideoDecode() throws Exception {
-        runDecodeAccuracyTest(
+        runVP9DecodeAccuracyTest(
                 new SurfaceViewFactory(),
                 getLargerWidthVideoFormat(new VideoFormat(VP9_VIDEO_FILE_NAME)));
     }
 
-    private void runDecodeAccuracyTest(VideoViewFactory videoViewFactory, VideoFormat videoFormat) {
+    /* <------------- Tests H264 with cropping -------------> */
+    public void testH264GLViewCroppedVideoDecode() throws Exception {
+        runH264DecodeCroppedTest(
+                new GLSurfaceViewFactory(),
+                new VideoFormat(H264_CROPPED_VIDEO_FILE_NAME));
+    }
+
+    public void testH264SurfaceViewCroppedVideoDecode() throws Exception {
+        runH264DecodeCroppedTest(
+                new SurfaceViewFactory(),
+                new VideoFormat(H264_CROPPED_VIDEO_FILE_NAME));
+    }
+
+    private void runH264DecodeAccuracyTest(
+            VideoViewFactory videoViewFactory, VideoFormat videoFormat) {
+        runDecodeAccuracyTest(videoViewFactory, videoFormat, R.raw.h264decodertestgolden);
+    }
+
+    private void runVP9DecodeAccuracyTest(
+            VideoViewFactory videoViewFactory, VideoFormat videoFormat) {
+        runDecodeAccuracyTest(videoViewFactory, videoFormat, R.raw.vp9decodertestgolden);
+    }
+
+    private void runH264DecodeCroppedTest(
+            VideoViewFactory videoViewFactory, VideoFormat videoFormat) {
+        runDecodeAccuracyTest(videoViewFactory, videoFormat, R.raw.h264decodertest520x360golden);
+    }
+
+    private void runDecodeAccuracyTest(
+            VideoViewFactory videoViewFactory, VideoFormat videoFormat, int goldenResId) {
         checkNotNull(videoViewFactory);
         checkNotNull(videoFormat);
         View videoView = videoViewFactory.createView(getHelper().getContext());
@@ -123,7 +148,7 @@
         // so it needs to be created before start decoding.
         final VideoViewSnapshot videoViewSnapshot = videoViewFactory.getVideoViewSnapshot();
         decodeVideo(videoFormat, videoViewFactory);
-        validateResult(videoFormat, videoViewSnapshot);
+        validateResult(videoFormat, videoViewSnapshot, goldenResId);
 
         if (videoView != null) {
             getHelper().cleanUpView(videoView);
@@ -140,20 +165,16 @@
         assertTrue("Failed to decode the video.", playerResult.isSuccess());
     }
 
-    private void validateResult(VideoFormat videoFormat, VideoViewSnapshot videoViewSnapshot) {
+    private void validateResult(
+            VideoFormat videoFormat, VideoViewSnapshot videoViewSnapshot, int goldenResId) {
         final Bitmap result = getHelper().generateBitmapFromVideoViewSnapshot(videoViewSnapshot);
-        final Bitmap golden;
-        final String mime = videoFormat.getMimeType();
-        if (mime.equals(MimeTypes.VIDEO_H264)) {
-            golden = getHelper().generateBitmapFromImageResourceId(R.raw.h264decodertestgolden);
-        } else if (mime.equals(MimeTypes.VIDEO_VP9)) {
-            golden = getHelper().generateBitmapFromImageResourceId(R.raw.vp9decodertestgolden);
-        } else {
-            fail("Unsupported MIME type " + mime);
-            return;
-        }
-        final BitmapCompare.Difference difference = BitmapCompare.computeDifference(golden, result);
-        assertTrue("Greatest pixel difference is "
+        final Bitmap golden = getHelper().generateBitmapFromImageResourceId(goldenResId);
+        final BitmapCompare.Difference difference = BitmapCompare.computeMinimumDifference(
+                result, golden, videoFormat.getOriginalWidth(), videoFormat.getOriginalHeight());
+        assertTrue("With the best matched border crop ("
+                    + difference.bestMatchBorderCrop.first + ", "
+                    + difference.bestMatchBorderCrop.second + "), "
+                    + "greatest pixel difference is "
                     + difference.greatestPixelDifference
                     + (difference.greatestPixelDifferenceCoordinates != null
                     ? " at (" + difference.greatestPixelDifferenceCoordinates.first + ", "
diff --git a/tests/tests/media/src/android/media/cts/DecodeAccuracyTestBase.java b/tests/tests/media/src/android/media/cts/DecodeAccuracyTestBase.java
index 3e3c866f..47029d6b 100644
--- a/tests/tests/media/src/android/media/cts/DecodeAccuracyTestBase.java
+++ b/tests/tests/media/src/android/media/cts/DecodeAccuracyTestBase.java
@@ -617,6 +617,7 @@
 /**
  * Factory for building a {@link SurfaceView}
  */
+@TargetApi(24)
 class SurfaceViewFactory extends VideoViewFactory implements SurfaceHolder.Callback {
 
     private static final String TAG = SurfaceViewFactory.class.getSimpleName();
@@ -1294,6 +1295,8 @@
     private int height = UNSET;
     private int maxWidth = UNSET;
     private int maxHeight = UNSET;
+    private int originalWidth = UNSET;
+    private int originalHeight = UNSET;
 
     public VideoFormat(String filename, Uri uri) {
         this.filename = filename;
@@ -1331,6 +1334,9 @@
 
     public void setWidth(int width) {
         this.width = width;
+        if (this.originalWidth == UNSET) {
+            this.originalWidth = width;
+        }
     }
 
     public void setMaxWidth(int maxWidth) {
@@ -1345,8 +1351,15 @@
         return maxWidth;
     }
 
+    public int getOriginalWidth() {
+        return originalWidth;
+    }
+
     public void setHeight(int height) {
         this.height = height;
+        if (this.originalHeight == UNSET) {
+            this.originalHeight = height;
+        }
     }
 
     public void setMaxHeight(int maxHeight) {
@@ -1361,6 +1374,10 @@
         return maxHeight;
     }
 
+    public int getOriginalHeight() {
+        return originalHeight;
+    }
+
     private Uri createCacheFile(Context context) {
         try {
             File cacheFile = new File(context.getCacheDir(), filename);
@@ -1563,22 +1580,167 @@
         return (int) Math.round(Math.sqrt(result));
     }
 
+    /**
+     * Crops the border of the array representing an image by hBorderSize
+     * pixels on the left and right borders, and by vBorderSize pixels on the
+     * top and bottom borders (so the width is 2 * hBorderSize smaller and
+     * the height is 2 * vBorderSize smaller), then scales the image up to
+     * match the original size using bilinear interpolation.
+     */
+    private static Bitmap shrinkAndScaleBilinear(
+            Bitmap input, double hBorderSize, double vBorderSize) {
+
+        int width = input.getWidth();
+        int height = input.getHeight();
+
+        // Compute the proper step sizes
+        double xInc = ((double) width - 1 - hBorderSize * 2) / (double) (width - 1);
+        double yInc = ((double) height - 1 - vBorderSize * 2) / (double) (height - 1);
+
+        // Read the input bitmap into RGB arrays.
+        int[] inputPixels = new int[width * height];
+        input.getPixels(inputPixels, 0, width, 0, 0, width, height);
+        int[][] inputRgb = new int[width * height][3];
+        for (int i = 0; i < width * height; ++i) {
+            inputRgb[i][0] = Color.red(inputPixels[i]);
+            inputRgb[i][1] = Color.green(inputPixels[i]);
+            inputRgb[i][2] = Color.blue(inputPixels[i]);
+        }
+        inputPixels = null;
+
+        // Prepare the output buffer.
+        int[] outputPixels = new int[width * height];
+
+        // Start the iteration. The first y coordinate is vBorderSize.
+        double y = vBorderSize;
+        for (int yIndex = 0; yIndex < height; ++yIndex) {
+            // The first x coordinate is hBorderSize.
+            double x = hBorderSize;
+            for (int xIndex = 0; xIndex < width; ++xIndex) {
+                // Determine the square of interest.
+                int left = (int)x;    // This is floor(x).
+                int top = (int)y;     // This is floor(y).
+                int right = left + 1;
+                int bottom = top + 1;
+
+                // (u, v) is the fractional part of (x, y).
+                double u = x - (double)left;
+                double v = y - (double)top;
+
+                // Precompute necessary products to save time.
+                double p00 = (1.0 - u) * (1.0 - v);
+                double p01 = (1.0 - u) * v;
+                double p10 = u * (1.0 - v);
+                double p11 = u * v;
+
+                // Clamp the indices to prevent out-of-bound that may be caused
+                // by round-off error.
+                if (left >= width) left = width - 1;
+                if (top >= height) top = height - 1;
+                if (right >= width) right = width - 1;
+                if (bottom >= height) bottom = height - 1;
+
+                // Sample RGB values from the four corners.
+                int[] rgb00 = inputRgb[top * width + left];
+                int[] rgb01 = inputRgb[bottom * width + left];
+                int[] rgb10 = inputRgb[top * width + right];
+                int[] rgb11 = inputRgb[bottom * width + right];
+
+                // Interpolate each component of RGB separately.
+                int[] mixedColor = new int[3];
+                for (int k = 0; k < 3; ++k) {
+                    mixedColor[k] = (int)Math.round(
+                            p00 * (double) rgb00[k] + p01 * (double) rgb01[k]
+                            + p10 * (double) rgb10[k] + p11 * (double) rgb11[k]);
+                }
+                // Convert RGB to bitmap Color format and store.
+                outputPixels[yIndex * width + xIndex] = Color.rgb(
+                        mixedColor[0], mixedColor[1], mixedColor[2]);
+                x += xInc;
+            }
+            y += yInc;
+        }
+        // Assemble the output buffer into a Bitmap object.
+        return Bitmap.createBitmap(outputPixels, width, height, input.getConfig());
+    }
+
+    /**
+     * Calls computeDifference on multiple cropped-and-scaled versions of
+     * bitmap2.
+     */
+    @TargetApi(12)
+    public static Difference computeMinimumDifference(
+            Bitmap bitmap1, Bitmap bitmap2, Pair<Double, Double>[] borderCrops) {
+
+        // Compute the difference with the original image (bitmap2) first.
+        Difference minDiff = computeDifference(bitmap1, bitmap2);
+        // Then go through the list of borderCrops.
+        for (Pair<Double, Double> borderCrop : borderCrops) {
+            // Compute the difference between bitmap1 and a transformed
+            // version of bitmap2.
+            Bitmap bitmap2s = shrinkAndScaleBilinear(bitmap2, borderCrop.first, borderCrop.second);
+            Difference d = computeDifference(bitmap1, bitmap2s);
+            // Keep the minimum difference.
+            if (d.greatestPixelDifference < minDiff.greatestPixelDifference) {
+                minDiff = d;
+                minDiff.bestMatchBorderCrop = borderCrop;
+            }
+        }
+        return minDiff;
+    }
+
+    /**
+     * Calls computeMinimumDifference on a default list of borderCrop.
+     */
+    @TargetApi(12)
+    public static Difference computeMinimumDifference(
+            Bitmap bitmap1, Bitmap bitmap2, int trueWidth, int trueHeight) {
+
+        double hBorder = (double) bitmap1.getWidth() / (double) trueWidth;
+        double vBorder = (double) bitmap1.getHeight() / (double) trueHeight;
+        double hBorderH = 0.5 * hBorder; // Half-texel horizontal border
+        double vBorderH = 0.5 * vBorder; // Half-texel vertical border
+        return computeMinimumDifference(
+                bitmap1,
+                bitmap2,
+                new Pair[] {
+                    Pair.create(hBorderH, 0.0),
+                    Pair.create(hBorderH, vBorderH),
+                    Pair.create(0.0, vBorderH),
+                    Pair.create(hBorder, 0.0),
+                    Pair.create(hBorder, vBorder),
+                    Pair.create(0.0, vBorder)
+                });
+        // This default list of borderCrop comes from the behavior of
+        // GLConsumer.computeTransformMatrix().
+    }
+
     /* Describes the difference between two {@link Bitmap} instances. */
     public static final class Difference {
 
         public final int greatestPixelDifference;
         public final Pair<Integer, Integer> greatestPixelDifferenceCoordinates;
+        public Pair<Double, Double> bestMatchBorderCrop;
 
         private Difference(int greatestPixelDifference) {
-            this(greatestPixelDifference, null);
+            this(greatestPixelDifference, null, Pair.create(0.0, 0.0));
         }
 
         private Difference(
                 int greatestPixelDifference,
                 Pair<Integer, Integer> greatestPixelDifferenceCoordinates) {
+            this(greatestPixelDifference, greatestPixelDifferenceCoordinates,
+                    Pair.create(0.0, 0.0));
+        }
+
+        private Difference(
+                int greatestPixelDifference,
+                Pair<Integer, Integer> greatestPixelDifferenceCoordinates,
+                Pair<Double, Double> bestMatchBorderCrop) {
             this.greatestPixelDifference = greatestPixelDifference;
             this.greatestPixelDifferenceCoordinates = greatestPixelDifferenceCoordinates;
-        }
+            this.bestMatchBorderCrop = bestMatchBorderCrop;
+       }
     }
 
 }
diff --git a/tests/tests/provider/src/android/provider/cts/Settings_SystemTest.java b/tests/tests/provider/src/android/provider/cts/Settings_SystemTest.java
index b3c545e..badc88e 100644
--- a/tests/tests/provider/src/android/provider/cts/Settings_SystemTest.java
+++ b/tests/tests/provider/src/android/provider/cts/Settings_SystemTest.java
@@ -99,6 +99,12 @@
 
         // first query exist rows
         Cursor c = cr.query(System.CONTENT_URI, null, null, null, null);
+
+        // backup fontScale
+        Configuration cfg = new Configuration();
+        System.getConfiguration(cr, cfg);
+        float store = cfg.fontScale;
+
         try {
             assertNotNull(c);
             int origCount = c.getCount();
@@ -131,25 +137,20 @@
             assertNotNull(c);
             assertEquals(origCount, c.getCount());
 
-            // backup fontScale
-            Configuration cfg = new Configuration();
-            System.getConfiguration(cr, cfg);
-            float store = cfg.fontScale;
-
             // update fontScale row
             cfg = new Configuration();
-            cfg.fontScale = 10.0f;
+            cfg.fontScale = 1.2f;
             assertTrue(System.putConfiguration(cr, cfg));
 
             System.getConfiguration(cr, cfg);
-            assertEquals(10.0f, cfg.fontScale);
+            assertEquals(1.2f, cfg.fontScale);
+        } finally {
+            // TODO should clean up more better
+            c.close();
 
             // restore the fontScale
             cfg.fontScale = store;
             assertTrue(System.putConfiguration(cr, cfg));
-        } finally {
-            // TODO should clean up more better
-            c.close();
         }
     }
 
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/refocus/d1new/RefocusFilterd1new.java b/tests/tests/renderscript/src/android/renderscript/cts/refocus/d1new/RefocusFilterd1new.java
index 3942982..52bc4de 100644
--- a/tests/tests/renderscript/src/android/renderscript/cts/refocus/d1new/RefocusFilterd1new.java
+++ b/tests/tests/renderscript/src/android/renderscript/cts/refocus/d1new/RefocusFilterd1new.java
@@ -143,8 +143,9 @@
 
     startnow = System.nanoTime();
     //scriptC.forEach_MarkLayerMask(buffers.inAllocation);
-    // Pass sharp meta allocation directly into the kernel
-    scriptC.forEach_MarkLayerMaskPassInput(buffers.sharpActualDepthAllocation, buffers.sharpDilatedDepthAllocation);
+    // Pass the sharp actual depth allocation directly into the kernel, and modify the dilated depth
+    // allocation which is set as a global.
+    scriptC.forEach_MarkLayerMaskPassInput(buffers.sharpActualDepthAllocation);
     endnow = System.nanoTime();
     Log.d(myTAG, "MarkLayerMask: "+(endnow - startnow)+ " ns" );
 
@@ -213,8 +214,9 @@
 
     startnow = System.nanoTime();
     //scriptC.forEach_MarkLayerMask(buffers.inAllocation);
-    // Pass sharp meta allocation directly into the kernel
-    scriptC.forEach_MarkLayerMaskPassInput(buffers.sharpActualDepthAllocation, buffers.sharpDilatedDepthAllocation);
+    // Pass the sharp actual depth allocation directly into the kernel, and modify the dilated depth
+    // allocation which is set as a global.
+    scriptC.forEach_MarkLayerMaskPassInput(buffers.sharpActualDepthAllocation);
     endnow = System.nanoTime();
     Log.d(myTAG, "MarkLayerMask: "+(endnow - startnow)+ " ns" );
 
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/refocus/layered_filter_d1new_helper.rsh b/tests/tests/renderscript/src/android/renderscript/cts/refocus/layered_filter_d1new_helper.rsh
index 39c8d90..77a0c31 100644
--- a/tests/tests/renderscript/src/android/renderscript/cts/refocus/layered_filter_d1new_helper.rsh
+++ b/tests/tests/renderscript/src/android/renderscript/cts/refocus/layered_filter_d1new_helper.rsh
@@ -73,7 +73,7 @@
   }
 
   // Converts min_dist to a matte value.
-  rsSetElementAt_uchar(g_sharp_matte, (uchar)(dilation_radius + 1 - (int)half_sqrt((float)min_dist)), index_sharp_meta);
+  rsSetElementAt_uchar(g_sharp_matte, (uchar)(dilation_radius + 1 - (int)(half_sqrt((float)min_dist) + 0.5f)), index_sharp_meta);
   // If sharp->matte > 0, depth must be within the depth range of this layer.
   rsSetElementAt_uchar(g_sharp_dilated_depth, (uchar)depth, index_sharp_meta);
 }
@@ -113,7 +113,7 @@
     current_meta_index += jump_to_next_row;
   }
   // Converts min_dist to a matte value.
-  rsSetElementAt_uchar(g_sharp_matte, (uchar)(dilation_radius + 1 - (int)half_sqrt((float)min_dist)), index_sharp_meta);
+  rsSetElementAt_uchar(g_sharp_matte, (uchar)(dilation_radius + 1 - (int)(half_sqrt((float)min_dist) + 0.5f)), index_sharp_meta);
   // If sharp->matte > 0, depth must be within the depth range of this layer.
   return (uchar)depth;
 }
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/refocus/layered_filter_fast_d1new.rs b/tests/tests/renderscript/src/android/renderscript/cts/refocus/layered_filter_fast_d1new.rs
index e7342c6..e21db8a 100644
--- a/tests/tests/renderscript/src/android/renderscript/cts/refocus/layered_filter_fast_d1new.rs
+++ b/tests/tests/renderscript/src/android/renderscript/cts/refocus/layered_filter_fast_d1new.rs
@@ -181,8 +181,8 @@
 // Another version of MarkLayerMask kernel that directly passes input allocation to kernels
 // Input: g_sharp_actual_depth
 // Output: g_sharp_dilated_depth
-uchar __attribute__((kernel)) MarkLayerMaskPassInput(uchar in_sharp_actual_depth, uint32_t x) {
-  if (!OnTheLayer(in_sharp_actual_depth, g_target_layer_i2)) return rsGetElementAt_uchar(g_sharp_dilated_depth, x);
+void __attribute__((kernel)) MarkLayerMaskPassInput(uchar in_sharp_actual_depth, uint32_t x) {
+  if (!OnTheLayer(in_sharp_actual_depth, g_target_layer_i2)) return;
 
   // Marks this pixel as active.
   rsSetElementAt_uchar(g_sharp_active, 1, x);
@@ -209,7 +209,8 @@
     ValidDepthNotOnTheLayer(sharp_actual_depth, g_target_layer_i2);
 
   if (!is_this_pixel_on_boundary) {
-    return in_sharp_actual_depth;
+    rsSetElementAt_uchar(g_sharp_dilated_depth, in_sharp_actual_depth, x);
+    return;
   }
 
   // Marks pixels near the boundary of active pixels to compute matte later.
@@ -235,9 +236,8 @@
     }
     current_meta_index += jump_to_next_row;
   }
-
-  return in_sharp_actual_depth;
 }
+
 // Distance transform in processing layers in pass one from the back-most to
 // the sharp depth.
 void __attribute__((kernel))
diff --git a/tests/tests/uirendering/src/android/uirendering/cts/testclasses/ExactCanvasTests.java b/tests/tests/uirendering/src/android/uirendering/cts/testclasses/ExactCanvasTests.java
index 108adf0..6f90433 100644
--- a/tests/tests/uirendering/src/android/uirendering/cts/testclasses/ExactCanvasTests.java
+++ b/tests/tests/uirendering/src/android/uirendering/cts/testclasses/ExactCanvasTests.java
@@ -182,4 +182,27 @@
                 .runWithComparer(mExactComparer);
     }
 
+    @Test
+    public void testSaveLayerRounding() {
+        createTest()
+                .addCanvasClient((canvas, width, height) -> {
+                    canvas.saveLayerAlpha(10.5f, 10.5f, 79.5f, 79.5f, 255);
+                    canvas.drawRect(20, 20, 70, 70, new Paint());
+                    canvas.restore();
+                })
+                .runWithVerifier(new RectVerifier(Color.WHITE, Color.BLACK,
+                        new Rect(20, 20, 70, 70)));
+    }
+
+    @Test
+    public void testUnclippedSaveLayerRounding() {
+        createTest()
+                .addCanvasClient((canvas, width, height) -> {
+                    canvas.saveLayerAlpha(10.5f, 10.5f, 79.5f, 79.5f, 255, 0);
+                    canvas.drawRect(20, 20, 70, 70, new Paint());
+                    canvas.restore();
+                })
+                .runWithVerifier(new RectVerifier(Color.WHITE, Color.BLACK,
+                        new Rect(20, 20, 70, 70)));
+    }
 }
diff --git a/tools/device-setup/TestDeviceSetup/src/android/tests/getinfo/DeviceInfoConstants.java b/tools/device-setup/TestDeviceSetup/src/android/tests/getinfo/DeviceInfoConstants.java
index 24cff32..3da1b54 100644
--- a/tools/device-setup/TestDeviceSetup/src/android/tests/getinfo/DeviceInfoConstants.java
+++ b/tools/device-setup/TestDeviceSetup/src/android/tests/getinfo/DeviceInfoConstants.java
@@ -76,7 +76,6 @@
     public static final String MEMORY_CLASS = "memory_class";
     public static final String LARGE_MEMORY_CLASS = "large_memory_class";
     public static final String TOTAL_MEMORY = "total_memory";
-    public static final String REFERENCE_BUILD_FINGERPRINT =
-            "reference_build_fingerprint";
+    public static final String REFERENCE_BUILD_FINGERPRINT = "reference_build_fingerprint";
     public static final String AVAILABLE_PROCESSORS = "available_processors";
 }