Merge "Fix construction of algorithm list" into pi-dev
diff --git a/apps/CameraITS/tests/scene1/test_auto_vs_manual.py b/apps/CameraITS/tests/scene1/test_auto_vs_manual.py
index 9c49575..a7b5add 100644
--- a/apps/CameraITS/tests/scene1/test_auto_vs_manual.py
+++ b/apps/CameraITS/tests/scene1/test_auto_vs_manual.py
@@ -18,6 +18,7 @@
 import its.objects
 import os.path
 import math
+import numpy as np
 
 def main():
     """Capture auto and manual shots that should look the same.
@@ -93,10 +94,14 @@
 
         # Check that the WB gains and transform reported in each capture
         # result match with the original AWB estimate from do_3a.
-        for g,x in [(gains_a,xform_a),(gains_m1,xform_m1),(gains_m2,xform_m2)]:
+        for g,x in [(gains_m1,xform_m1),(gains_m2,xform_m2)]:
             assert(all([abs(xform[i] - x[i]) < 0.05 for i in range(9)]))
             assert(all([abs(gains[i] - g[i]) < 0.05 for i in range(4)]))
 
+        # Check that auto AWB settings are close
+        assert(all([np.isclose(xform_a[i], xform[i], rtol=0.25, atol=0.1) for i in range(9)]))
+        assert(all([np.isclose(gains_a[i], gains[i], rtol=0.25, atol=0.1) for i in range(4)]))
+
 if __name__ == '__main__':
     main()
 
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 002af37..e8cf2ef 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
@@ -186,7 +186,8 @@
     private CaptureResult mCaptureResults[] = null;
 
     private volatile ConditionVariable mInterlock3A = new ConditionVariable(true);
-    private volatile boolean mIssuedRequest3A = false;
+
+    final Object m3AStateLock = new Object();
     private volatile boolean mConvergedAE = false;
     private volatile boolean mConvergedAF = false;
     private volatile boolean mConvergedAWB = false;
@@ -996,6 +997,7 @@
     }
 
     private void do3A(JSONObject params) throws ItsException {
+        ThreeAResultListener threeAListener = new ThreeAResultListener();
         try {
             // Start a 3A action, and wait for it to converge.
             // Get the converged values for each "A", and package into JSON result for caller.
@@ -1048,11 +1050,6 @@
                 }
             }
 
-            // If AE or AWB lock is specified, then the 3A will converge first and then lock these
-            // values, waiting until the HAL has reported that the lock was successful.
-            mNeedsLockedAE = params.optBoolean(LOCK_AE_KEY, false);
-            mNeedsLockedAWB = params.optBoolean(LOCK_AWB_KEY, false);
-
             // An EV compensation can be specified as part of AE convergence.
             int evComp = params.optInt(EVCOMP_KEY, 0);
             if (evComp != 0) {
@@ -1084,12 +1081,17 @@
             }
 
             mInterlock3A.open();
-            mIssuedRequest3A = false;
-            mConvergedAE = false;
-            mConvergedAWB = false;
-            mConvergedAF = false;
-            mLockedAE = false;
-            mLockedAWB = false;
+            synchronized(m3AStateLock) {
+                // If AE or AWB lock is specified, then the 3A will converge first and then lock these
+                // values, waiting until the HAL has reported that the lock was successful.
+                mNeedsLockedAE = params.optBoolean(LOCK_AE_KEY, false);
+                mNeedsLockedAWB = params.optBoolean(LOCK_AWB_KEY, false);
+                mConvergedAE = false;
+                mConvergedAWB = false;
+                mConvergedAF = false;
+                mLockedAE = false;
+                mLockedAWB = false;
+            }
             long tstart = System.currentTimeMillis();
             boolean triggeredAE = false;
             boolean triggeredAF = false;
@@ -1112,71 +1114,83 @@
                 }
                 mInterlock3A.close();
 
-                // If not converged yet, issue another capture request.
-                if (       (doAE && (!triggeredAE || !mConvergedAE))
-                        || !mConvergedAWB
-                        || (doAF && (!triggeredAF || !mConvergedAF))
-                        || (doAE && mNeedsLockedAE && !mLockedAE)
-                        || (mNeedsLockedAWB && !mLockedAWB)) {
+                synchronized(m3AStateLock) {
+                    // If not converged yet, issue another capture request.
+                    if (       (doAE && (!triggeredAE || !mConvergedAE))
+                            || !mConvergedAWB
+                            || (doAF && (!triggeredAF || !mConvergedAF))
+                            || (doAE && mNeedsLockedAE && !mLockedAE)
+                            || (mNeedsLockedAWB && !mLockedAWB)) {
 
-                    // Baseline capture request for 3A.
-                    CaptureRequest.Builder req = mCamera.createCaptureRequest(
-                            CameraDevice.TEMPLATE_PREVIEW);
-                    req.set(CaptureRequest.FLASH_MODE, CaptureRequest.FLASH_MODE_OFF);
-                    req.set(CaptureRequest.CONTROL_MODE, CaptureRequest.CONTROL_MODE_AUTO);
-                    req.set(CaptureRequest.CONTROL_CAPTURE_INTENT,
-                            CaptureRequest.CONTROL_CAPTURE_INTENT_PREVIEW);
-                    req.set(CaptureRequest.CONTROL_AE_MODE,
-                            CaptureRequest.CONTROL_AE_MODE_ON);
-                    req.set(CaptureRequest.CONTROL_AE_EXPOSURE_COMPENSATION, 0);
-                    req.set(CaptureRequest.CONTROL_AE_LOCK, false);
-                    req.set(CaptureRequest.CONTROL_AE_REGIONS, regionAE);
-                    req.set(CaptureRequest.CONTROL_AF_MODE,
-                            CaptureRequest.CONTROL_AF_MODE_AUTO);
-                    req.set(CaptureRequest.CONTROL_AF_REGIONS, regionAF);
-                    req.set(CaptureRequest.CONTROL_AWB_MODE,
-                            CaptureRequest.CONTROL_AWB_MODE_AUTO);
-                    req.set(CaptureRequest.CONTROL_AWB_LOCK, false);
-                    req.set(CaptureRequest.CONTROL_AWB_REGIONS, regionAWB);
-                    // ITS only turns OIS on when it's explicitly requested
-                    req.set(CaptureRequest.LENS_OPTICAL_STABILIZATION_MODE,
-                            CaptureRequest.LENS_OPTICAL_STABILIZATION_MODE_OFF);
+                        // Baseline capture request for 3A.
+                        CaptureRequest.Builder req = mCamera.createCaptureRequest(
+                                CameraDevice.TEMPLATE_PREVIEW);
+                        req.set(CaptureRequest.FLASH_MODE, CaptureRequest.FLASH_MODE_OFF);
+                        req.set(CaptureRequest.CONTROL_MODE, CaptureRequest.CONTROL_MODE_AUTO);
+                        req.set(CaptureRequest.CONTROL_CAPTURE_INTENT,
+                                CaptureRequest.CONTROL_CAPTURE_INTENT_PREVIEW);
+                        req.set(CaptureRequest.CONTROL_AE_MODE,
+                                CaptureRequest.CONTROL_AE_MODE_ON);
+                        req.set(CaptureRequest.CONTROL_AE_EXPOSURE_COMPENSATION, 0);
+                        req.set(CaptureRequest.CONTROL_AE_LOCK, false);
+                        req.set(CaptureRequest.CONTROL_AE_REGIONS, regionAE);
+                        req.set(CaptureRequest.CONTROL_AF_MODE,
+                                CaptureRequest.CONTROL_AF_MODE_AUTO);
+                        req.set(CaptureRequest.CONTROL_AF_REGIONS, regionAF);
+                        req.set(CaptureRequest.CONTROL_AWB_MODE,
+                                CaptureRequest.CONTROL_AWB_MODE_AUTO);
+                        req.set(CaptureRequest.CONTROL_AWB_LOCK, false);
+                        req.set(CaptureRequest.CONTROL_AWB_REGIONS, regionAWB);
+                        // ITS only turns OIS on when it's explicitly requested
+                        req.set(CaptureRequest.LENS_OPTICAL_STABILIZATION_MODE,
+                                CaptureRequest.LENS_OPTICAL_STABILIZATION_MODE_OFF);
 
-                    if (evComp != 0) {
-                        req.set(CaptureRequest.CONTROL_AE_EXPOSURE_COMPENSATION, evComp);
+                        if (evComp != 0) {
+                            req.set(CaptureRequest.CONTROL_AE_EXPOSURE_COMPENSATION, evComp);
+                        }
+
+                        if (mConvergedAE && mNeedsLockedAE) {
+                            req.set(CaptureRequest.CONTROL_AE_LOCK, true);
+                        }
+                        if (mConvergedAWB && mNeedsLockedAWB) {
+                            req.set(CaptureRequest.CONTROL_AWB_LOCK, true);
+                        }
+
+                        boolean triggering = false;
+                        // Trigger AE first.
+                        if (doAE && !triggeredAE) {
+                            Logt.i(TAG, "Triggering AE");
+                            req.set(CaptureRequest.CONTROL_AE_PRECAPTURE_TRIGGER,
+                                    CaptureRequest.CONTROL_AE_PRECAPTURE_TRIGGER_START);
+                            triggeredAE = true;
+                            triggering = true;
+                        }
+
+                        // After AE has converged, trigger AF.
+                        if (doAF && !triggeredAF && (!doAE || (triggeredAE && mConvergedAE))) {
+                            Logt.i(TAG, "Triggering AF");
+                            req.set(CaptureRequest.CONTROL_AF_TRIGGER,
+                                    CaptureRequest.CONTROL_AF_TRIGGER_START);
+                            triggeredAF = true;
+                            triggering = true;
+                        }
+
+                        req.addTarget(mOutputImageReaders[0].getSurface());
+
+                        if (triggering) {
+                            // Send single request for AE/AF trigger
+                            mSession.capture(req.build(),
+                                    threeAListener, mResultHandler);
+                        } else {
+                            // Use repeating request for non-trigger requests
+                            mSession.setRepeatingRequest(req.build(),
+                                    threeAListener, mResultHandler);
+                        }
+                    } else {
+                        mSocketRunnableObj.sendResponse("3aConverged", "");
+                        Logt.i(TAG, "3A converged");
+                        break;
                     }
-
-                    if (mConvergedAE && mNeedsLockedAE) {
-                        req.set(CaptureRequest.CONTROL_AE_LOCK, true);
-                    }
-                    if (mConvergedAWB && mNeedsLockedAWB) {
-                        req.set(CaptureRequest.CONTROL_AWB_LOCK, true);
-                    }
-
-                    // Trigger AE first.
-                    if (doAE && !triggeredAE) {
-                        Logt.i(TAG, "Triggering AE");
-                        req.set(CaptureRequest.CONTROL_AE_PRECAPTURE_TRIGGER,
-                                CaptureRequest.CONTROL_AE_PRECAPTURE_TRIGGER_START);
-                        triggeredAE = true;
-                    }
-
-                    // After AE has converged, trigger AF.
-                    if (doAF && !triggeredAF && (!doAE || (triggeredAE && mConvergedAE))) {
-                        Logt.i(TAG, "Triggering AF");
-                        req.set(CaptureRequest.CONTROL_AF_TRIGGER,
-                                CaptureRequest.CONTROL_AF_TRIGGER_START);
-                        triggeredAF = true;
-                    }
-
-                    req.addTarget(mOutputImageReaders[0].getSurface());
-
-                    mIssuedRequest3A = true;
-                    mSession.capture(req.build(), mCaptureResultListener, mResultHandler);
-                } else {
-                    mSocketRunnableObj.sendResponse("3aConverged", "");
-                    Logt.i(TAG, "3A converged");
-                    break;
                 }
             }
         } catch (android.hardware.camera2.CameraAccessException e) {
@@ -1185,6 +1199,11 @@
             throw new ItsException("JSON error: ", e);
         } finally {
             mSocketRunnableObj.sendResponse("3aDone", "");
+            // stop listener from updating 3A states
+            threeAListener.stop();
+            if (mSession != null) {
+                mSession.close();
+            }
         }
     }
 
@@ -1778,6 +1797,198 @@
         return (float)r.getNumerator() / (float)r.getDenominator();
     }
 
+    private String buildLogString(CaptureResult result) throws ItsException {
+        StringBuilder logMsg = new StringBuilder();
+        logMsg.append(String.format(
+                "Capt result: AE=%d, AF=%d, AWB=%d, ",
+                result.get(CaptureResult.CONTROL_AE_STATE),
+                result.get(CaptureResult.CONTROL_AF_STATE),
+                result.get(CaptureResult.CONTROL_AWB_STATE)));
+        int[] capabilities = mCameraCharacteristics.get(
+                CameraCharacteristics.REQUEST_AVAILABLE_CAPABILITIES);
+        if (capabilities == null) {
+            throw new ItsException("Failed to get capabilities");
+        }
+        boolean readSensorSettings = false;
+        for (int capability : capabilities) {
+            if (capability ==
+                    CameraCharacteristics.
+                            REQUEST_AVAILABLE_CAPABILITIES_READ_SENSOR_SETTINGS) {
+                readSensorSettings = true;
+                break;
+            }
+        }
+        if (readSensorSettings) {
+            logMsg.append(String.format(
+                    "sens=%d, exp=%.1fms, dur=%.1fms, ",
+                    result.get(CaptureResult.SENSOR_SENSITIVITY),
+                    result.get(CaptureResult.SENSOR_EXPOSURE_TIME).longValue() / 1000000.0f,
+                    result.get(CaptureResult.SENSOR_FRAME_DURATION).longValue() /
+                                1000000.0f));
+        }
+        if (result.get(CaptureResult.COLOR_CORRECTION_GAINS) != null) {
+            logMsg.append(String.format(
+                    "gains=[%.1f, %.1f, %.1f, %.1f], ",
+                    result.get(CaptureResult.COLOR_CORRECTION_GAINS).getRed(),
+                    result.get(CaptureResult.COLOR_CORRECTION_GAINS).getGreenEven(),
+                    result.get(CaptureResult.COLOR_CORRECTION_GAINS).getGreenOdd(),
+                    result.get(CaptureResult.COLOR_CORRECTION_GAINS).getBlue()));
+        } else {
+            logMsg.append("gains=[], ");
+        }
+        if (result.get(CaptureResult.COLOR_CORRECTION_TRANSFORM) != null) {
+            logMsg.append(String.format(
+                    "xform=[%.1f, %.1f, %.1f, %.1f, %.1f, %.1f, %.1f, %.1f, %.1f], ",
+                    r2f(result.get(CaptureResult.COLOR_CORRECTION_TRANSFORM).getElement(0,0)),
+                    r2f(result.get(CaptureResult.COLOR_CORRECTION_TRANSFORM).getElement(1,0)),
+                    r2f(result.get(CaptureResult.COLOR_CORRECTION_TRANSFORM).getElement(2,0)),
+                    r2f(result.get(CaptureResult.COLOR_CORRECTION_TRANSFORM).getElement(0,1)),
+                    r2f(result.get(CaptureResult.COLOR_CORRECTION_TRANSFORM).getElement(1,1)),
+                    r2f(result.get(CaptureResult.COLOR_CORRECTION_TRANSFORM).getElement(2,1)),
+                    r2f(result.get(CaptureResult.COLOR_CORRECTION_TRANSFORM).getElement(0,2)),
+                    r2f(result.get(CaptureResult.COLOR_CORRECTION_TRANSFORM).getElement(1,2)),
+                    r2f(result.get(CaptureResult.COLOR_CORRECTION_TRANSFORM).getElement(2,2))));
+        } else {
+            logMsg.append("xform=[], ");
+        }
+        logMsg.append(String.format(
+                "foc=%.1f",
+                result.get(CaptureResult.LENS_FOCUS_DISTANCE)));
+        return logMsg.toString();
+    }
+
+    private class ThreeAResultListener extends CaptureResultListener {
+        private volatile boolean stopped = false;
+        private boolean aeResultSent = false;
+        private boolean awbResultSent = false;
+        private boolean afResultSent = false;
+
+        @Override
+        public void onCaptureStarted(CameraCaptureSession session, CaptureRequest request,
+                long timestamp, long frameNumber) {
+        }
+
+        @Override
+        public void onCaptureCompleted(CameraCaptureSession session, CaptureRequest request,
+                TotalCaptureResult result) {
+            try {
+                if (stopped) {
+                    return;
+                }
+
+                if (request == null || result == null) {
+                    throw new ItsException("Request/result is invalid");
+                }
+
+                Logt.i(TAG, buildLogString(result));
+
+                synchronized(m3AStateLock) {
+                    if (result.get(CaptureResult.CONTROL_AE_STATE) != null) {
+                        mConvergedAE = result.get(CaptureResult.CONTROL_AE_STATE) ==
+                                                  CaptureResult.CONTROL_AE_STATE_CONVERGED ||
+                                       result.get(CaptureResult.CONTROL_AE_STATE) ==
+                                                  CaptureResult.CONTROL_AE_STATE_FLASH_REQUIRED ||
+                                       result.get(CaptureResult.CONTROL_AE_STATE) ==
+                                                  CaptureResult.CONTROL_AE_STATE_LOCKED;
+                        mLockedAE = result.get(CaptureResult.CONTROL_AE_STATE) ==
+                                               CaptureResult.CONTROL_AE_STATE_LOCKED;
+                    }
+                    if (result.get(CaptureResult.CONTROL_AF_STATE) != null) {
+                        mConvergedAF = result.get(CaptureResult.CONTROL_AF_STATE) ==
+                                                  CaptureResult.CONTROL_AF_STATE_FOCUSED_LOCKED;
+                    }
+                    if (result.get(CaptureResult.CONTROL_AWB_STATE) != null) {
+                        mConvergedAWB = result.get(CaptureResult.CONTROL_AWB_STATE) ==
+                                                   CaptureResult.CONTROL_AWB_STATE_CONVERGED ||
+                                        result.get(CaptureResult.CONTROL_AWB_STATE) ==
+                                                   CaptureResult.CONTROL_AWB_STATE_LOCKED;
+                        mLockedAWB = result.get(CaptureResult.CONTROL_AWB_STATE) ==
+                                                CaptureResult.CONTROL_AWB_STATE_LOCKED;
+                    }
+
+                    if (mConvergedAE && (!mNeedsLockedAE || mLockedAE) && !aeResultSent) {
+                        aeResultSent = true;
+                        if (result.get(CaptureResult.SENSOR_SENSITIVITY) != null
+                                && result.get(CaptureResult.SENSOR_EXPOSURE_TIME) != null) {
+                            mSocketRunnableObj.sendResponse("aeResult", String.format("%d %d",
+                                    result.get(CaptureResult.SENSOR_SENSITIVITY).intValue(),
+                                    result.get(CaptureResult.SENSOR_EXPOSURE_TIME).intValue()
+                                    ));
+                        } else {
+                            Logt.i(TAG, String.format(
+                                    "AE converged but NULL exposure values, sensitivity:%b, expTime:%b",
+                                    result.get(CaptureResult.SENSOR_SENSITIVITY) == null,
+                                    result.get(CaptureResult.SENSOR_EXPOSURE_TIME) == null));
+                        }
+                    }
+
+                    if (mConvergedAF && !afResultSent) {
+                        afResultSent = true;
+                        if (result.get(CaptureResult.LENS_FOCUS_DISTANCE) != null) {
+                            mSocketRunnableObj.sendResponse("afResult", String.format("%f",
+                                    result.get(CaptureResult.LENS_FOCUS_DISTANCE)
+                                    ));
+                        } else {
+                            Logt.i(TAG, "AF converged but NULL focus distance values");
+                        }
+                    }
+
+                    if (mConvergedAWB && (!mNeedsLockedAWB || mLockedAWB) && !awbResultSent) {
+                        awbResultSent = true;
+                        if (result.get(CaptureResult.COLOR_CORRECTION_GAINS) != null
+                                && result.get(CaptureResult.COLOR_CORRECTION_TRANSFORM) != null) {
+                            mSocketRunnableObj.sendResponse("awbResult", String.format(
+                                    "%f %f %f %f %f %f %f %f %f %f %f %f %f",
+                                    result.get(CaptureResult.COLOR_CORRECTION_GAINS).getRed(),
+                                    result.get(CaptureResult.COLOR_CORRECTION_GAINS).getGreenEven(),
+                                    result.get(CaptureResult.COLOR_CORRECTION_GAINS).getGreenOdd(),
+                                    result.get(CaptureResult.COLOR_CORRECTION_GAINS).getBlue(),
+                                    r2f(result.get(CaptureResult.COLOR_CORRECTION_TRANSFORM).
+                                            getElement(0,0)),
+                                    r2f(result.get(CaptureResult.COLOR_CORRECTION_TRANSFORM).
+                                            getElement(1,0)),
+                                    r2f(result.get(CaptureResult.COLOR_CORRECTION_TRANSFORM).
+                                            getElement(2,0)),
+                                    r2f(result.get(CaptureResult.COLOR_CORRECTION_TRANSFORM).
+                                            getElement(0,1)),
+                                    r2f(result.get(CaptureResult.COLOR_CORRECTION_TRANSFORM).
+                                            getElement(1,1)),
+                                    r2f(result.get(CaptureResult.COLOR_CORRECTION_TRANSFORM).
+                                            getElement(2,1)),
+                                    r2f(result.get(CaptureResult.COLOR_CORRECTION_TRANSFORM).
+                                            getElement(0,2)),
+                                    r2f(result.get(CaptureResult.COLOR_CORRECTION_TRANSFORM).
+                                            getElement(1,2)),
+                                    r2f(result.get(CaptureResult.COLOR_CORRECTION_TRANSFORM).
+                                            getElement(2,2))));
+                        } else {
+                            Logt.i(TAG, String.format(
+                                    "AWB converged but NULL color correction values, gains:%b, ccm:%b",
+                                    result.get(CaptureResult.COLOR_CORRECTION_GAINS) == null,
+                                    result.get(CaptureResult.COLOR_CORRECTION_TRANSFORM) == null));
+                        }
+                    }
+                }
+
+                mInterlock3A.open();
+            } catch (ItsException e) {
+                Logt.e(TAG, "Script error: ", e);
+            } catch (Exception e) {
+                Logt.e(TAG, "Script error: ", e);
+            }
+        }
+
+        @Override
+        public void onCaptureFailed(CameraCaptureSession session, CaptureRequest request,
+                CaptureFailure failure) {
+            Logt.e(TAG, "Script error: capture failed");
+        }
+
+        public void stop() {
+            stopped = true;
+        }
+    }
+
     private final CaptureResultListener mCaptureResultListener = new CaptureResultListener() {
         @Override
         public void onCaptureStarted(CameraCaptureSession session, CaptureRequest request,
@@ -1788,156 +1999,19 @@
         public void onCaptureCompleted(CameraCaptureSession session, CaptureRequest request,
                 TotalCaptureResult result) {
             try {
-                // Currently result has all 0 values.
                 if (request == null || result == null) {
                     throw new ItsException("Request/result is invalid");
                 }
 
-                StringBuilder logMsg = new StringBuilder();
-                logMsg.append(String.format(
-                        "Capt result: AE=%d, AF=%d, AWB=%d, ",
-                        result.get(CaptureResult.CONTROL_AE_STATE),
-                        result.get(CaptureResult.CONTROL_AF_STATE),
-                        result.get(CaptureResult.CONTROL_AWB_STATE)));
-                int[] capabilities = mCameraCharacteristics.get(
-                        CameraCharacteristics.REQUEST_AVAILABLE_CAPABILITIES);
-                if (capabilities == null) {
-                    throw new ItsException("Failed to get capabilities");
-                }
-                boolean readSensorSettings = false;
-                for (int capability : capabilities) {
-                    if (capability ==
-                            CameraCharacteristics.
-                                    REQUEST_AVAILABLE_CAPABILITIES_READ_SENSOR_SETTINGS) {
-                        readSensorSettings = true;
-                        break;
-                    }
-                }
-                if (readSensorSettings) {
-                    logMsg.append(String.format(
-                            "sens=%d, exp=%.1fms, dur=%.1fms, ",
-                            result.get(CaptureResult.SENSOR_SENSITIVITY),
-                            result.get(CaptureResult.SENSOR_EXPOSURE_TIME).longValue() / 1000000.0f,
-                            result.get(CaptureResult.SENSOR_FRAME_DURATION).longValue() /
-                                        1000000.0f));
-                }
-                if (result.get(CaptureResult.COLOR_CORRECTION_GAINS) != null) {
-                    logMsg.append(String.format(
-                            "gains=[%.1f, %.1f, %.1f, %.1f], ",
-                            result.get(CaptureResult.COLOR_CORRECTION_GAINS).getRed(),
-                            result.get(CaptureResult.COLOR_CORRECTION_GAINS).getGreenEven(),
-                            result.get(CaptureResult.COLOR_CORRECTION_GAINS).getGreenOdd(),
-                            result.get(CaptureResult.COLOR_CORRECTION_GAINS).getBlue()));
-                } else {
-                    logMsg.append("gains=[], ");
-                }
-                if (result.get(CaptureResult.COLOR_CORRECTION_TRANSFORM) != null) {
-                    logMsg.append(String.format(
-                            "xform=[%.1f, %.1f, %.1f, %.1f, %.1f, %.1f, %.1f, %.1f, %.1f], ",
-                            r2f(result.get(CaptureResult.COLOR_CORRECTION_TRANSFORM).getElement(0,0)),
-                            r2f(result.get(CaptureResult.COLOR_CORRECTION_TRANSFORM).getElement(1,0)),
-                            r2f(result.get(CaptureResult.COLOR_CORRECTION_TRANSFORM).getElement(2,0)),
-                            r2f(result.get(CaptureResult.COLOR_CORRECTION_TRANSFORM).getElement(0,1)),
-                            r2f(result.get(CaptureResult.COLOR_CORRECTION_TRANSFORM).getElement(1,1)),
-                            r2f(result.get(CaptureResult.COLOR_CORRECTION_TRANSFORM).getElement(2,1)),
-                            r2f(result.get(CaptureResult.COLOR_CORRECTION_TRANSFORM).getElement(0,2)),
-                            r2f(result.get(CaptureResult.COLOR_CORRECTION_TRANSFORM).getElement(1,2)),
-                            r2f(result.get(CaptureResult.COLOR_CORRECTION_TRANSFORM).getElement(2,2))));
-                } else {
-                    logMsg.append("xform=[], ");
-                }
-                logMsg.append(String.format(
-                        "foc=%.1f",
-                        result.get(CaptureResult.LENS_FOCUS_DISTANCE)));
-                Logt.i(TAG, logMsg.toString());
+                Logt.i(TAG, buildLogString(result));
 
-                if (result.get(CaptureResult.CONTROL_AE_STATE) != null) {
-                    mConvergedAE = result.get(CaptureResult.CONTROL_AE_STATE) ==
-                                              CaptureResult.CONTROL_AE_STATE_CONVERGED ||
-                                   result.get(CaptureResult.CONTROL_AE_STATE) ==
-                                              CaptureResult.CONTROL_AE_STATE_FLASH_REQUIRED ||
-                                   result.get(CaptureResult.CONTROL_AE_STATE) ==
-                                              CaptureResult.CONTROL_AE_STATE_LOCKED;
-                    mLockedAE = result.get(CaptureResult.CONTROL_AE_STATE) ==
-                                           CaptureResult.CONTROL_AE_STATE_LOCKED;
-                }
-                if (result.get(CaptureResult.CONTROL_AF_STATE) != null) {
-                    mConvergedAF = result.get(CaptureResult.CONTROL_AF_STATE) ==
-                                              CaptureResult.CONTROL_AF_STATE_FOCUSED_LOCKED;
-                }
-                if (result.get(CaptureResult.CONTROL_AWB_STATE) != null) {
-                    mConvergedAWB = result.get(CaptureResult.CONTROL_AWB_STATE) ==
-                                               CaptureResult.CONTROL_AWB_STATE_CONVERGED ||
-                                    result.get(CaptureResult.CONTROL_AWB_STATE) ==
-                                               CaptureResult.CONTROL_AWB_STATE_LOCKED;
-                    mLockedAWB = result.get(CaptureResult.CONTROL_AWB_STATE) ==
-                                            CaptureResult.CONTROL_AWB_STATE_LOCKED;
-                }
-
-                if (mConvergedAE && (!mNeedsLockedAE || mLockedAE)) {
-                    if (result.get(CaptureResult.SENSOR_SENSITIVITY) != null
-                            && result.get(CaptureResult.SENSOR_EXPOSURE_TIME) != null) {
-                        mSocketRunnableObj.sendResponse("aeResult", String.format("%d %d",
-                                result.get(CaptureResult.SENSOR_SENSITIVITY).intValue(),
-                                result.get(CaptureResult.SENSOR_EXPOSURE_TIME).intValue()
-                                ));
-                    } else {
-                        Logt.i(TAG, String.format(
-                                "AE converged but NULL exposure values, sensitivity:%b, expTime:%b",
-                                result.get(CaptureResult.SENSOR_SENSITIVITY) == null,
-                                result.get(CaptureResult.SENSOR_EXPOSURE_TIME) == null));
-                    }
-                }
-
-                if (mConvergedAF) {
-                    if (result.get(CaptureResult.LENS_FOCUS_DISTANCE) != null) {
-                        mSocketRunnableObj.sendResponse("afResult", String.format("%f",
-                                result.get(CaptureResult.LENS_FOCUS_DISTANCE)
-                                ));
-                    } else {
-                        Logt.i(TAG, "AF converged but NULL focus distance values");
-                    }
-                }
-
-                if (mConvergedAWB && (!mNeedsLockedAWB || mLockedAWB)) {
-                    if (result.get(CaptureResult.COLOR_CORRECTION_GAINS) != null
-                            && result.get(CaptureResult.COLOR_CORRECTION_TRANSFORM) != null) {
-                        mSocketRunnableObj.sendResponse("awbResult", String.format(
-                                "%f %f %f %f %f %f %f %f %f %f %f %f %f",
-                                result.get(CaptureResult.COLOR_CORRECTION_GAINS).getRed(),
-                                result.get(CaptureResult.COLOR_CORRECTION_GAINS).getGreenEven(),
-                                result.get(CaptureResult.COLOR_CORRECTION_GAINS).getGreenOdd(),
-                                result.get(CaptureResult.COLOR_CORRECTION_GAINS).getBlue(),
-                                r2f(result.get(CaptureResult.COLOR_CORRECTION_TRANSFORM).getElement(0,0)),
-                                r2f(result.get(CaptureResult.COLOR_CORRECTION_TRANSFORM).getElement(1,0)),
-                                r2f(result.get(CaptureResult.COLOR_CORRECTION_TRANSFORM).getElement(2,0)),
-                                r2f(result.get(CaptureResult.COLOR_CORRECTION_TRANSFORM).getElement(0,1)),
-                                r2f(result.get(CaptureResult.COLOR_CORRECTION_TRANSFORM).getElement(1,1)),
-                                r2f(result.get(CaptureResult.COLOR_CORRECTION_TRANSFORM).getElement(2,1)),
-                                r2f(result.get(CaptureResult.COLOR_CORRECTION_TRANSFORM).getElement(0,2)),
-                                r2f(result.get(CaptureResult.COLOR_CORRECTION_TRANSFORM).getElement(1,2)),
-                                r2f(result.get(CaptureResult.COLOR_CORRECTION_TRANSFORM).getElement(2,2))
-                                ));
-                    } else {
-                        Logt.i(TAG, String.format(
-                                "AWB converged but NULL color correction values, gains:%b, ccm:%b",
-                                result.get(CaptureResult.COLOR_CORRECTION_GAINS) == null,
-                                result.get(CaptureResult.COLOR_CORRECTION_TRANSFORM) == null));
-                    }
-                }
-
-                if (mIssuedRequest3A) {
-                    mIssuedRequest3A = false;
-                    mInterlock3A.open();
-                } else {
-                    int count = mCountCapRes.getAndIncrement();
-                    mCaptureResults[count] = result;
-                    mSocketRunnableObj.sendResponseCaptureResult(mCameraCharacteristics,
-                            request, result, mOutputImageReaders);
-                    synchronized(mCountCallbacksRemaining) {
-                        mCountCallbacksRemaining.decrementAndGet();
-                        mCountCallbacksRemaining.notify();
-                    }
+                int count = mCountCapRes.getAndIncrement();
+                mCaptureResults[count] = result;
+                mSocketRunnableObj.sendResponseCaptureResult(mCameraCharacteristics,
+                        request, result, mOutputImageReaders);
+                synchronized(mCountCallbacksRemaining) {
+                    mCountCallbacksRemaining.decrementAndGet();
+                    mCountCallbacksRemaining.notify();
                 }
             } catch (ItsException e) {
                 Logt.e(TAG, "Script error: ", e);
diff --git a/hostsidetests/appsecurity/src/android/appsecurity/cts/DirectBootHostTest.java b/hostsidetests/appsecurity/src/android/appsecurity/cts/DirectBootHostTest.java
index 8a781c6..2d1386f 100644
--- a/hostsidetests/appsecurity/src/android/appsecurity/cts/DirectBootHostTest.java
+++ b/hostsidetests/appsecurity/src/android/appsecurity/cts/DirectBootHostTest.java
@@ -171,7 +171,7 @@
                     doTest = false;
                 }
                 getDevice().waitForDeviceNotAvailable(SHUTDOWN_TIME_MS);
-                getDevice().waitForDeviceOnline();
+                getDevice().waitForDeviceOnline(120000);
             } else {
                 getDevice().rebootUntilOnline();
             }
diff --git a/hostsidetests/incident/src/com/android/server/cts/BatteryStatsValidationTest.java b/hostsidetests/incident/src/com/android/server/cts/BatteryStatsValidationTest.java
index 263327f..65cb2a5 100644
--- a/hostsidetests/incident/src/com/android/server/cts/BatteryStatsValidationTest.java
+++ b/hostsidetests/incident/src/com/android/server/cts/BatteryStatsValidationTest.java
@@ -172,9 +172,11 @@
         startSimpleActivity();
         assertValueRange("st", "", STATE_TIME_FOREGROUND_SERVICE_INDEX, 0,
                 0); // No foreground service time before test
+        final long startTime = System.nanoTime();
         runDeviceTests(DEVICE_SIDE_TEST_PACKAGE, ".BatteryStatsProcessStateTests",
                 "testForegroundService");
-        assertValueRange("st", "", STATE_TIME_FOREGROUND_SERVICE_INDEX, (long) (2000 * 0.8), 4000);
+        assertValueRange("st", "", STATE_TIME_FOREGROUND_SERVICE_INDEX, (long) (2000 * 0.8),
+                (System.nanoTime() - startTime) / 1000000);
         batteryOffScreenOn();
     }
 
diff --git a/hostsidetests/security/src/android/security/cts/Poc17_03.java b/hostsidetests/security/src/android/security/cts/Poc17_03.java
index 80c959c..a6f1e04 100644
--- a/hostsidetests/security/src/android/security/cts/Poc17_03.java
+++ b/hostsidetests/security/src/android/security/cts/Poc17_03.java
@@ -82,4 +82,23 @@
         assertNotMatchesMultiLine(".*Fatal signal 11 \\(SIGSEGV\\).*>>> /system/bin/" +
                          "audioserver <<<.*", logcatOut);
     }
+
+    /*
+     *  b/33178389
+     */
+    @SecurityTest
+    public void testPocCVE_2017_0490() throws Exception {
+        String bootCountBefore =
+                AdbUtils.runCommandLine("settings get global boot_count", getDevice());
+        AdbUtils.runCommandLine("service call wifi 43 s16 content://settings/global/boot_count s16 "
+                + "\"application/x-wifi-config\"",
+                getDevice());
+        String bootCountAfter =
+                AdbUtils.runCommandLine("settings get global boot_count", getDevice());
+        // Poc nukes the boot_count setting, reboot to restore it to a sane value
+        AdbUtils.runCommandLine("reboot", getDevice());
+        getDevice().waitForDeviceOnline(60 * 1000);
+        updateKernelStartTime();
+        assertEquals(bootCountBefore, bootCountAfter);
+    }
 }
diff --git a/hostsidetests/statsd/apps/statsdapp/src/com/android/server/cts/device/statsd/Checkers.java b/hostsidetests/statsd/apps/statsdapp/src/com/android/server/cts/device/statsd/Checkers.java
new file mode 100644
index 0000000..40c4f03
--- /dev/null
+++ b/hostsidetests/statsd/apps/statsdapp/src/com/android/server/cts/device/statsd/Checkers.java
@@ -0,0 +1,36 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.cts.device.statsd;
+
+import android.net.wifi.WifiManager;
+import android.support.test.InstrumentationRegistry;
+
+import static org.junit.Assert.assertTrue;
+import org.junit.Test;
+
+/**
+ * Methods to check device properties. They pass iff the check returns true.
+ */
+public class Checkers {
+    private static final String TAG = Checkers.class.getSimpleName();
+
+    @Test
+    public void checkWifiEnhancedPowerReportingSupported() {
+        WifiManager wm = InstrumentationRegistry.getContext().getSystemService(WifiManager.class);
+        assertTrue(wm.isEnhancedPowerReportingSupported());
+    }
+}
diff --git a/hostsidetests/statsd/src/android/cts/statsd/atom/AtomTestCase.java b/hostsidetests/statsd/src/android/cts/statsd/atom/AtomTestCase.java
index 2fa1ac4..225ebf5 100644
--- a/hostsidetests/statsd/src/android/cts/statsd/atom/AtomTestCase.java
+++ b/hostsidetests/statsd/src/android/cts/statsd/atom/AtomTestCase.java
@@ -15,6 +15,9 @@
  */
 package android.cts.statsd.atom;
 
+import static android.cts.statsd.atom.DeviceAtomTestCase.DEVICE_SIDE_TEST_APK;
+import static android.cts.statsd.atom.DeviceAtomTestCase.DEVICE_SIDE_TEST_PACKAGE;
+
 import android.os.BatteryStatsProto;
 import android.service.batterystats.BatteryStatsServiceDumpProto;
 import android.view.DisplayStateEnum;
@@ -86,11 +89,6 @@
         if (statsdDisabled()) {
             return;
         }
-        // TODO: need to do these before running real test:
-        // 1. compile statsd and push to device
-        // 2. make sure StatsCompanionService and incidentd is running
-        // 3. start statsd
-        // These should go away once we have statsd properly set up.
 
         // Uninstall to clear the history in case it's still on the device.
         removeConfig(CONFIG_ID);
@@ -100,6 +98,7 @@
     @Override
     protected void tearDown() throws Exception {
         removeConfig(CONFIG_ID);
+        getDevice().uninstallPackage(DEVICE_SIDE_TEST_PACKAGE);
         super.tearDown();
     }
 
@@ -130,6 +129,18 @@
         return log.contains(PERFETTO_STARTED_STRING);
     }
 
+    protected boolean checkDeviceFor(String methodName) throws Exception {
+        try {
+            installPackage(DEVICE_SIDE_TEST_APK, true);
+            runDeviceTests(DEVICE_SIDE_TEST_PACKAGE, ".Checkers", methodName);
+            // Test passes, meaning that the answer is true.
+            return true;
+        } catch (AssertionError e) {
+            // Method is designed to fail if the answer is false.
+            return false;
+        }
+    }
+
     protected static StatsdConfig.Builder createConfigBuilder() {
         return StatsdConfig.newBuilder().setId(CONFIG_ID)
                 .addAllowedLogSource("AID_SYSTEM")
diff --git a/hostsidetests/statsd/src/android/cts/statsd/atom/BaseTestCase.java b/hostsidetests/statsd/src/android/cts/statsd/atom/BaseTestCase.java
index fc4a561..cd396ec 100644
--- a/hostsidetests/statsd/src/android/cts/statsd/atom/BaseTestCase.java
+++ b/hostsidetests/statsd/src/android/cts/statsd/atom/BaseTestCase.java
@@ -120,11 +120,11 @@
 
         final TestRunResult result = listener.getCurrentRunResults();
         if (result.isRunFailure()) {
-            throw new AssertionError("Failed to successfully run device tests for "
+            throw new Error("Failed to successfully run device tests for "
                     + result.getName() + ": " + result.getRunFailureMessage());
         }
         if (result.getNumTests() == 0) {
-            throw new AssertionError("No tests were run on the device");
+            throw new Error("No tests were run on the device");
         }
 
         if (result.hasFailedTests()) {
diff --git a/hostsidetests/statsd/src/android/cts/statsd/atom/HostAtomTests.java b/hostsidetests/statsd/src/android/cts/statsd/atom/HostAtomTests.java
index eb96b83..b91ebbb 100644
--- a/hostsidetests/statsd/src/android/cts/statsd/atom/HostAtomTests.java
+++ b/hostsidetests/statsd/src/android/cts/statsd/atom/HostAtomTests.java
@@ -17,7 +17,6 @@
 
 import android.os.BatteryPluggedStateEnum; // From os/enums.proto
 import android.os.BatteryStatusEnum; // From os/enums.proto
-import android.os.TemperatureTypeEnum; // From os/enums.proto
 import android.platform.test.annotations.RestrictedBuildTest;
 import android.server.DeviceIdleModeEnum; // From server/enums.proto
 import android.view.DisplayStateEnum; // From view/enums.proto
@@ -45,7 +44,6 @@
 import com.android.os.AtomsProto.RemainingBatteryCapacity;
 import com.android.os.AtomsProto.ScreenStateChanged;
 import com.android.os.AtomsProto.SubsystemSleepState;
-import com.android.os.AtomsProto.Temperature;
 import com.android.os.StatsLog.EventMetricData;
 import com.android.tradefed.log.LogUtil.CLog;
 
@@ -399,44 +397,6 @@
         assertTrue(atom.getFullBatteryCapacity().getCapacityUAh() > 0);
     }
 
-    @RestrictedBuildTest
-    public void testTemperature() throws Exception {
-        if (statsdDisabled()) {
-            return;
-        }
-        if (!hasFeature(FEATURE_WATCH, false)) return;
-        StatsdConfig.Builder config = getPulledConfig();
-        FieldMatcher.Builder dimension = FieldMatcher.newBuilder()
-                .setField(Atom.TEMPERATURE_FIELD_NUMBER)
-                .addChild(FieldMatcher.newBuilder()
-                        .setField(Temperature.SENSOR_LOCATION_FIELD_NUMBER))
-                .addChild(FieldMatcher.newBuilder()
-                        .setField(Temperature.SENSOR_NAME_FIELD_NUMBER));
-        addGaugeAtom(config, Atom.TEMPERATURE_FIELD_NUMBER, dimension);
-
-        uploadConfig(config);
-
-        Thread.sleep(WAIT_TIME_LONG);
-        setAppBreadcrumbPredicate();
-        Thread.sleep(WAIT_TIME_LONG);
-
-        List<Atom> data = getGaugeMetricDataList();
-
-        assertTrue(data.size() >= TemperatureTypeEnum.values().length - 1);
-        for (int i = 0; i < data.size(); i++) {
-            Temperature temp = data.get(i).getTemperature();
-            assertTrue("Temperature atom " + i + " has no type",
-                    temp.hasSensorLocation());
-            assertTrue("Temperature reported atom " + i + " has no temperature",
-                    temp.hasTemperatureDC());
-            assertTrue("Temperature reported atom " + i + " has an unreasonably low temperature:" +
-                    + temp.getTemperatureDC(), temp.getTemperatureDC() > 0);
-            assertTrue("Temperature reported atom " + i + " has an unreasonably high temperature:" +
-                    + temp.getTemperatureDC(), temp.getTemperatureDC() < 800);
-
-        }
-    }
-
     public void testKernelWakelock() throws Exception {
         if (statsdDisabled()) {
             return;
@@ -522,6 +482,8 @@
         }
         if (!hasFeature(FEATURE_WIFI, true)) return;
         if (!hasFeature(FEATURE_WATCH, false)) return;
+        if (!checkDeviceFor("checkWifiEnhancedPowerReportingSupported")) return;
+
         StatsdConfig.Builder config = getPulledConfig();
         addGaugeAtom(config, Atom.WIFI_ACTIVITY_INFO_FIELD_NUMBER, null);
 
diff --git a/tests/app/src/android/app/cts/DisplayTest.java b/tests/app/src/android/app/cts/DisplayTest.java
index 154f41f..f845bb7 100644
--- a/tests/app/src/android/app/cts/DisplayTest.java
+++ b/tests/app/src/android/app/cts/DisplayTest.java
@@ -58,7 +58,14 @@
         // Change orientation
         mActivity.configurationChangeObserver.startObserving();
         OrientationTestUtils.switchOrientation(mActivity);
-        mActivity.configurationChangeObserver.await();
+
+        final boolean squareDisplay = (origSize.x == origSize.y);
+      
+        // Don't wait for the configuration to change if the
+        // the display is square. In many cases it won't.
+        if (!squareDisplay) {
+            mActivity.configurationChangeObserver.await();
+        }
 
         final Point newOrigSize = new Point();
         origDisplay.getSize(newOrigSize);
@@ -69,7 +76,7 @@
         updatedDisplay.getSize(updatedSize);
 
         // For square screens the following assertions do not make sense and will always fail.
-        if (origSize.x != origSize.y) {
+        if (!squareDisplay) {
             // Ensure that the width and height of the original instance no longer are the same. Note
             // that this will be false if the device width and height are identical.
             // Note there are cases where width and height may not all be updated, such as on docked
diff --git a/tests/autofillservice/res/layout/duplicate_id_layout.xml b/tests/autofillservice/res/layout/duplicate_id_layout.xml
index a5643ea..4d409a2 100644
--- a/tests/autofillservice/res/layout/duplicate_id_layout.xml
+++ b/tests/autofillservice/res/layout/duplicate_id_layout.xml
@@ -17,17 +17,21 @@
 
 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
     android:orientation="vertical"
+    android:focusable="true"
+    android:focusableInTouchMode="true"
     android:layout_width="match_parent"
     android:layout_height="match_parent">
 
     <CheckBox
         android:id="@+id/duplicate_id"
         android:layout_width="match_parent"
-        android:layout_height="wrap_content" />
+        android:layout_height="wrap_content"
+        android:text="cb1" /> <!--  text is set just for debugging purposes -->
 
     <CheckBox
         android:id="@+id/duplicate_id"
         android:layout_width="match_parent"
-        android:layout_height="wrap_content" />
+        android:layout_height="wrap_content"
+        android:text="cb2"/> <!--  text is set just for debugging purposes -->
 
 </LinearLayout>
\ No newline at end of file
diff --git a/tests/autofillservice/src/android/autofillservice/cts/DuplicateIdActivity.java b/tests/autofillservice/src/android/autofillservice/cts/DuplicateIdActivity.java
index 31ac8f7..90871ca 100644
--- a/tests/autofillservice/src/android/autofillservice/cts/DuplicateIdActivity.java
+++ b/tests/autofillservice/src/android/autofillservice/cts/DuplicateIdActivity.java
@@ -20,7 +20,7 @@
 import android.util.Log;
 
 public class DuplicateIdActivity extends AbstractAutoFillActivity {
-    private static final String LOG_TAG = DuplicateIdActivity.class.getSimpleName();
+    private static final String TAG = "DuplicateIdActivity";
 
     static final String DUPLICATE_ID = "duplicate_id";
 
@@ -28,9 +28,7 @@
     protected void onCreate(Bundle savedInstanceState) {
         super.onCreate(savedInstanceState);
 
-        if (savedInstanceState != null) {
-            Log.i(LOG_TAG, "onCreate(" + savedInstanceState + ")");
-        }
+        Log.v(TAG, "onCreate(" + savedInstanceState + ")");
 
         setContentView(R.layout.duplicate_id_layout);
     }
diff --git a/tests/autofillservice/src/android/autofillservice/cts/DuplicateIdActivityTest.java b/tests/autofillservice/src/android/autofillservice/cts/DuplicateIdActivityTest.java
index 29ec2b1..846dcc4 100644
--- a/tests/autofillservice/src/android/autofillservice/cts/DuplicateIdActivityTest.java
+++ b/tests/autofillservice/src/android/autofillservice/cts/DuplicateIdActivityTest.java
@@ -89,13 +89,14 @@
         // Select field to start autofill
         runShellCommand("input keyevent KEYCODE_TAB");
 
-        InstrumentedAutoFillService.FillRequest request = sReplier.getNextFillRequest();
+        final InstrumentedAutoFillService.FillRequest request1 = sReplier.getNextFillRequest();
+        Log.v(LOG_TAG, "request1: " + request1);
 
-        AssistStructure.ViewNode[] views = findViews(request);
-        AssistStructure.ViewNode view1 = views[0];
-        AssistStructure.ViewNode view2 = views[1];
-        AutofillId id1 = view1.getAutofillId();
-        AutofillId id2 = view2.getAutofillId();
+        final AssistStructure.ViewNode[] views1 = findViews(request1);
+        final AssistStructure.ViewNode view1 = views1[0];
+        final AssistStructure.ViewNode view2 = views1[1];
+        final AutofillId id1 = view1.getAutofillId();
+        final AutofillId id2 = view2.getAutofillId();
 
         Log.i(LOG_TAG, "view1=" + id1);
         Log.i(LOG_TAG, "view2=" + id2);
@@ -106,38 +107,39 @@
         // They got different autofill ids though
         assertThat(id1).isNotEqualTo(id2);
 
+        // Because service returned a null response, rotation will trigger another request.
         sReplier.addResponse(NO_RESPONSE);
-
         // Force rotation to force onDestroy->onCreate cycle
         mUiBot.setScreenOrientation(1);
         // Wait context and Views being recreated in rotation
         mUiBot.assertShownByRelativeId(DUPLICATE_ID);
+        // Ignore 2nd request.
+        final InstrumentedAutoFillService.FillRequest request2 = sReplier.getNextFillRequest();
+        Log.v(LOG_TAG, "request2: " + request2);
 
-        // Because service returned a null response, rotation will trigger another request.
+        // Select other field to trigger new partition (because server didn't return 2nd field
+        // on 1st response)
         sReplier.addResponse(NO_RESPONSE);
-
-        // Select other field to trigger new partition
         runShellCommand("input keyevent KEYCODE_TAB");
 
-        request = sReplier.getNextFillRequest();
-
-        // Ignore 2nd request.
-        sReplier.getNextFillRequest();
-
-        views = findViews(request);
-        AutofillId recreatedId1 = views[0].getAutofillId();
-        AutofillId recreatedId2 = views[1].getAutofillId();
+        final InstrumentedAutoFillService.FillRequest request3 = sReplier.getNextFillRequest();
+        Log.v(LOG_TAG, "request3: " + request3);
+        final AssistStructure.ViewNode[] views2 = findViews(request3);
+        final AssistStructure.ViewNode recreatedView1 = views2[0];
+        final AssistStructure.ViewNode recreatedView2 = views2[1];
+        final AutofillId recreatedId1 = recreatedView1.getAutofillId();
+        final AutofillId recreatedId2 = recreatedView2.getAutofillId();
 
         Log.i(LOG_TAG, "restored view1=" + recreatedId1);
         Log.i(LOG_TAG, "restored view2=" + recreatedId2);
 
         // For the restoring logic the two views are the same. Hence it might happen that the first
-        // view is restored with the id of the second view or the other way round.
+        // view is restored with the autofill id of the second view or the other way round.
         // We just need
         // - to restore as many views as we can (i.e. one)
         // - make sure the autofill ids are still unique after
-        boolean view1WasRestored = (recreatedId1.equals(id1) || recreatedId1.equals(id2));
-        boolean view2WasRestored = (recreatedId2.equals(id1) || recreatedId2.equals(id2));
+        final boolean view1WasRestored = (recreatedId1.equals(id1) || recreatedId1.equals(id2));
+        final boolean view2WasRestored = (recreatedId2.equals(id1) || recreatedId2.equals(id2));
 
         // One id was restored
         assertThat(view1WasRestored || view2WasRestored).isTrue();
diff --git a/tests/autofillservice/src/android/autofillservice/cts/Helper.java b/tests/autofillservice/src/android/autofillservice/cts/Helper.java
index 7934730..4e5418b 100644
--- a/tests/autofillservice/src/android/autofillservice/cts/Helper.java
+++ b/tests/autofillservice/src/android/autofillservice/cts/Helper.java
@@ -156,19 +156,37 @@
         return hasHint(view.getAutofillHints(), id);
     };
 
+    private static String toString(AssistStructure structure, StringBuilder builder) {
+        builder.append("[component=").append(structure.getActivityComponent());
+        final int nodes = structure.getWindowNodeCount();
+        for (int i = 0; i < nodes; i++) {
+            final WindowNode windowNode = structure.getWindowNodeAt(i);
+            dump(builder, windowNode.getRootViewNode(), " ", 0);
+        }
+        return builder.append(']').toString();
+    }
+
+    @NonNull
+    static String toString(@NonNull AssistStructure structure) {
+        return toString(structure, new StringBuilder());
+    }
+
+    @Nullable
+    static String toString(@Nullable AutofillValue value) {
+        if (value == null) return null;
+        if (value.isText()) {
+            // We don't care about PII...
+            final CharSequence text = value.getTextValue();
+            return text == null ? null : text.toString();
+        }
+        return value.toString();
+    }
+
     /**
      * Dump the assist structure on logcat.
      */
     static void dumpStructure(String message, AssistStructure structure) {
-        final StringBuffer buffer = new StringBuffer(message)
-                .append(": component=")
-                .append(structure.getActivityComponent());
-        final int nodes = structure.getWindowNodeCount();
-        for (int i = 0; i < nodes; i++) {
-            final WindowNode windowNode = structure.getWindowNodeAt(i);
-            dump(buffer, windowNode.getRootViewNode(), " ", 0);
-        }
-        Log.i(TAG, buffer.toString());
+        Log.i(TAG, toString(structure, new StringBuilder(message)));
     }
 
     /**
@@ -194,39 +212,69 @@
         SettingsHelper.syncSet(context, USER_SETUP_COMPLETE, complete ? "1" : null);
     }
 
-    private static void dump(StringBuffer buffer, ViewNode node, String prefix, int childId) {
+    private static void dump(@NonNull StringBuilder builder, @NonNull ViewNode node,
+            @NonNull String prefix, int childId) {
         final int childrenSize = node.getChildCount();
-        buffer.append("\n").append(prefix)
-            .append('#').append(childId).append(':')
-            .append("resId=").append(node.getIdEntry())
-            .append(" class=").append(node.getClassName())
-            .append(" text=").append(node.getText())
-            .append(" class=").append(node.getClassName())
-            .append(" webDomain=").append(node.getWebDomain())
-            .append(" #children=").append(childrenSize);
-
-        buffer.append("\n").append(prefix)
-            .append("   afId=").append(node.getAutofillId())
-            .append(" afType=").append(node.getAutofillType())
-            .append(" afValue=").append(node.getAutofillValue())
-            .append(" checked=").append(node.isChecked())
-            .append(" focused=").append(node.isFocused());
-
+        builder.append("\n").append(prefix)
+            .append("child #").append(childId).append(':');
+        append(builder, "afId", node.getAutofillId());
+        append(builder, "afType", node.getAutofillType());
+        append(builder, "afValue", toString(node.getAutofillValue()));
+        append(builder, "resId", node.getIdEntry());
+        append(builder, "class", node.getClassName());
+        append(builder, "text", node.getText());
+        append(builder, "webDomain", node.getWebDomain());
+        append(builder, "checked", node.isChecked());
+        append(builder, "focused", node.isFocused());
         final HtmlInfo htmlInfo = node.getHtmlInfo();
         if (htmlInfo != null) {
-            buffer.append("\nHtmlInfo: tag=").append(htmlInfo.getTag())
-                .append(", attrs: ").append(htmlInfo.getAttributes());
+            builder.append(", HtmlInfo[tag=").append(htmlInfo.getTag())
+                .append(", attrs: ").append(htmlInfo.getAttributes()).append(']');
         }
-
-        prefix += " ";
         if (childrenSize > 0) {
-            for (int i = 0; i < childrenSize; i++) {
-                dump(buffer, node.getChildAt(i), prefix, i);
+            append(builder, "#children", childrenSize).append("\n").append(prefix);
+            prefix += " ";
+            if (childrenSize > 0) {
+                for (int i = 0; i < childrenSize; i++) {
+                    dump(builder, node.getChildAt(i), prefix, i);
+                }
             }
         }
     }
 
     /**
+     * Appends a field value to a {@link StringBuilder} when it's not {@code null}.
+     */
+    @NonNull
+    static StringBuilder append(@NonNull StringBuilder builder, @NonNull String field,
+            @Nullable Object value) {
+        if (value == null) return builder;
+
+        if ((value instanceof Boolean) && ((Boolean) value)) {
+            return builder.append(", ").append(field);
+        }
+
+        if (value instanceof Integer && ((Integer) value) == 0
+                || value instanceof CharSequence && TextUtils.isEmpty((CharSequence) value)) {
+            return builder;
+        }
+
+        return builder.append(", ").append(field).append('=').append(value);
+    }
+
+    /**
+     * Appends a field value to a {@link StringBuilder} when it's {@code true}.
+     */
+    @NonNull
+    static StringBuilder append(@NonNull StringBuilder builder, @NonNull String field,
+            boolean value) {
+        if (value) {
+            builder.append(", ").append(field);
+        }
+        return builder;
+    }
+
+    /**
      * Gets a node if it matches the filter criteria for the given id.
      */
     static ViewNode findNodeByFilter(@NonNull AssistStructure structure, @NonNull Object id,
diff --git a/tests/autofillservice/src/android/autofillservice/cts/InstrumentedAutoFillService.java b/tests/autofillservice/src/android/autofillservice/cts/InstrumentedAutoFillService.java
index 42b6b41..6b47c9f 100644
--- a/tests/autofillservice/src/android/autofillservice/cts/InstrumentedAutoFillService.java
+++ b/tests/autofillservice/src/android/autofillservice/cts/InstrumentedAutoFillService.java
@@ -293,12 +293,13 @@
             this.cancellationSignal = cancellationSignal;
             this.callback = callback;
             this.flags = flags;
-            structure = contexts.get(contexts.size() - 1).getStructure();
+            this.structure = contexts.get(contexts.size() - 1).getStructure();
         }
 
         @Override
         public String toString() {
-            return "FillRequest:" + getActivityName(contexts);
+            return "FillRequest[activity=" + getActivityName(contexts) + ", flags=" + flags
+                    + ", bundle=" + data + ", structure=" + Helper.toString(structure) + "]";
         }
     }
 
diff --git a/tests/tests/location/src/android/location/cts/GnssTestCase.java b/tests/tests/location/src/android/location/cts/GnssTestCase.java
index 0258244..e1c5e88 100644
--- a/tests/tests/location/src/android/location/cts/GnssTestCase.java
+++ b/tests/tests/location/src/android/location/cts/GnssTestCase.java
@@ -15,9 +15,12 @@
  */
 package android.location.cts;
 
+import android.os.Build;
 import android.test.AndroidTestCase;
 import android.util.Log;
 
+import com.android.compatibility.common.util.PropertyUtil;
+
 /**
  * Base Test Case class for all Gnss Tests.
  */
@@ -32,14 +35,15 @@
     protected GnssTestCase() {
     }
 
-    // When CTS testing is run in Verifier mode access to GNSS signals is expected
     // On devices using newer hardware, GNSS measurement support is required.
-    // Hence when both conditions are true, we can verify stricter tests of functionality
-    // availability.
     protected boolean isMeasurementTestStrict() {
-        return ((mTestLocationManager.getLocationManager().getGnssYearOfHardware() >=
-                 MIN_HARDWARE_YEAR_MEASUREMENTS_REQUIRED) &&
-                isCtsVerifierTest());
+        // Enforce strict measurement test on devices with first API level at least P.
+        if (PropertyUtil.getFirstApiLevel() >= Build.VERSION_CODES.P) {
+            return true;
+        }
+
+        return (mTestLocationManager.getLocationManager().getGnssYearOfHardware() >=
+                MIN_HARDWARE_YEAR_MEASUREMENTS_REQUIRED);
     }
 
     public void setTestAsCtsVerifierTest(boolean value) {
diff --git a/tests/tests/security/src/android/security/cts/BluetoothIntentsTest.java b/tests/tests/security/src/android/security/cts/BluetoothIntentsTest.java
new file mode 100644
index 0000000..6a4990f
--- /dev/null
+++ b/tests/tests/security/src/android/security/cts/BluetoothIntentsTest.java
@@ -0,0 +1,61 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package android.security.cts;
+
+import org.junit.Test;
+
+import android.content.ComponentName;
+import android.content.Intent;
+import android.platform.test.annotations.SecurityTest;
+import android.test.AndroidTestCase;
+
+@SecurityTest
+public class BluetoothIntentsTest extends AndroidTestCase {
+  /**
+   * b/35258579
+   */
+  @SecurityTest
+  public void testAcceptIntent() {
+    genericIntentTest("ACCEPT");
+  }
+
+  /**
+   * b/35258579
+   */
+  @SecurityTest
+  public void testDeclineIntent() {
+      genericIntentTest("DECLINE");
+  }
+
+  private static final String prefix = "android.btopp.intent.action.";
+  private void genericIntentTest(String action) throws SecurityException {
+    try {
+      Intent should_be_protected_broadcast = new Intent();
+      should_be_protected_broadcast.setComponent(
+          new ComponentName("com.android.bluetooth",
+            "com.android.bluetooth.opp.BluetoothOppReceiver"));
+      should_be_protected_broadcast.setAction(prefix + action);
+      mContext.sendBroadcast(should_be_protected_broadcast);
+    }
+    catch (SecurityException e) {
+      return;
+    }
+
+    throw new SecurityException("An " + prefix + action +
+        " intent should not be broadcastable except by the system (declare " +
+        " as protected-broadcast in manifest)");
+  }
+}
diff --git a/tests/tests/view/src/android/view/cts/TextureViewTest.java b/tests/tests/view/src/android/view/cts/TextureViewTest.java
index f3f5318..88ac1f5 100644
--- a/tests/tests/view/src/android/view/cts/TextureViewTest.java
+++ b/tests/tests/view/src/android/view/cts/TextureViewTest.java
@@ -32,6 +32,7 @@
 import android.graphics.ColorSpace;
 import android.graphics.Matrix;
 import android.graphics.Point;
+import android.graphics.Rect;
 import android.support.test.filters.MediumTest;
 import android.support.test.rule.ActivityTestRule;
 import android.support.test.runner.AndroidJUnit4;
@@ -128,11 +129,93 @@
         mActivityRule.runOnUiThread(() -> {
             activity.getTextureView().getBitmap(bitmap);
         });
+        // Verify the matrix did not rotate content of getTextureView.getBitmap().
         PixelCopyTest.assertBitmapQuadColor(bitmap,
+                Color.RED, Color.GREEN, Color.BLUE, Color.BLACK);
+
+        // Remove cover and calculate TextureView position on the screen.
+        WidgetTestUtils.runOnMainAndDrawSync(mActivityRule,
+                activity.findViewById(android.R.id.content), () -> activity.removeCover());
+        final Rect viewPos = new Rect();
+        mActivityRule.runOnUiThread(() -> {
+            int[] outLocation = new int[2];
+            textureView.getLocationOnScreen(outLocation);
+            viewPos.left = outLocation[0];
+            viewPos.top = outLocation[1];
+            viewPos.right = viewPos.left + textureView.getWidth();
+            viewPos.bottom = viewPos.top + textureView.getHeight();
+        });
+
+        // Capture the portion of the screen that contains the texture view only.
+        Window window = activity.getWindow();
+        Bitmap screenshot = Bitmap.createBitmap(100, 100, Bitmap.Config.ARGB_8888);
+        int result = new SynchronousPixelCopy().request(window, viewPos, screenshot);
+        assertEquals("Copy request failed", PixelCopy.SUCCESS, result);
+        // Verify the matrix rotated the TextureView content drawn on the screen.
+        PixelCopyTest.assertBitmapQuadColor(screenshot,
                 Color.BLACK, Color.BLUE, Color.GREEN, Color.RED);
     }
 
     @Test
+    public void testTransformScale() throws Throwable {
+        final TextureViewCtsActivity activity = mActivityRule.launchActivity(null);
+        final TextureView textureView = activity.getTextureView();
+        WidgetTestUtils.runOnMainAndDrawSync(mActivityRule, activity.getTextureView(), null);
+        Matrix transform = new Matrix();
+        final float translateY = 100.0f;
+        final float scaleY = 0.25f;
+        float[] values = {1, 0, 0, 0, scaleY, translateY, 0, 0, 1};
+        transform.setValues(values);
+        activity.drawFrame(transform, TextureViewTest::drawGlQuad);
+        final Bitmap bitmap = Bitmap.createBitmap(10, 10, Bitmap.Config.ARGB_8888);
+        mActivityRule.runOnUiThread(() -> {
+            activity.getTextureView().getBitmap(bitmap);
+        });
+        // Verify the matrix did not affect the content of getTextureView.getBitmap().
+        PixelCopyTest.assertBitmapQuadColor(bitmap,
+                Color.RED, Color.GREEN, Color.BLUE, Color.BLACK);
+
+        // Remove cover and calculate TextureView position on the screen.
+        WidgetTestUtils.runOnMainAndDrawSync(mActivityRule,
+                activity.findViewById(android.R.id.content), () -> activity.removeCover());
+        final Rect viewPos = new Rect();
+        mActivityRule.runOnUiThread(() -> {
+            int[] outLocation = new int[2];
+            textureView.getLocationOnScreen(outLocation);
+            viewPos.left = outLocation[0];
+            viewPos.top = outLocation[1];
+            viewPos.right = viewPos.left + textureView.getWidth();
+            viewPos.bottom = viewPos.top + textureView.getHeight();
+        });
+
+        // Capture the portion of the screen that contains the texture view only.
+        Window window = activity.getWindow();
+        Bitmap screenshot = Bitmap.createBitmap(viewPos.width(), viewPos.height(),
+                Bitmap.Config.ARGB_8888);
+        int result = new SynchronousPixelCopy().request(window, viewPos, screenshot);
+        assertEquals("Copy request failed", PixelCopy.SUCCESS, result);
+        // Verify the matrix scaled and translated the TextureView content drawn on the screen.
+        // "texturePos" has SurfaceTexture position inside the TextureView.
+        final Rect texturePos = new Rect(0, (int) translateY, viewPos.width(),
+                (int) (viewPos.height() * scaleY + translateY));
+
+        // Areas not covered by the texture are black, because FrameLayout background is set to
+        // Color.BLACK in TextureViewCtsActivity.onCreate.
+        assertEquals("above texture", Color.BLACK,
+                screenshot.getPixel(10, texturePos.top - 10));
+        assertEquals("below texture", Color.BLACK,
+                screenshot.getPixel(10, texturePos.bottom + 10));
+        assertEquals("top left", Color.RED,
+                screenshot.getPixel(texturePos.left + 10, texturePos.top + 10));
+        assertEquals("top right", Color.GREEN,
+                screenshot.getPixel(texturePos.right - 10, texturePos.top + 10));
+        assertEquals("Bottom left", Color.BLUE,
+                screenshot.getPixel(texturePos.left + 10, texturePos.bottom - 10));
+        assertEquals("Bottom right", Color.BLACK,
+                screenshot.getPixel(texturePos.right - 10, texturePos.bottom - 10));
+    }
+
+    @Test
     public void testGetBitmap_8888_P3() throws Throwable {
         testGetBitmap(EGL_GL_COLORSPACE_DISPLAY_P3_EXT, ColorSpace.Named.DISPLAY_P3, false,
                 new FP16Compare(ColorSpace.Named.EXTENDED_SRGB));