Merge "Camera2: Remove some full hardware level check" into lmp-dev
diff --git a/tests/res/drawable-nodpi/vector_icon_stroke_1_golden.png b/tests/res/drawable-nodpi/vector_icon_stroke_1_golden.png
new file mode 100644
index 0000000..c57ad20
--- /dev/null
+++ b/tests/res/drawable-nodpi/vector_icon_stroke_1_golden.png
Binary files differ
diff --git a/tests/res/drawable-nodpi/vector_icon_stroke_2_golden.png b/tests/res/drawable-nodpi/vector_icon_stroke_2_golden.png
new file mode 100644
index 0000000..aee8ff5
--- /dev/null
+++ b/tests/res/drawable-nodpi/vector_icon_stroke_2_golden.png
Binary files differ
diff --git a/tests/res/drawable-nodpi/vector_icon_stroke_3_golden.png b/tests/res/drawable-nodpi/vector_icon_stroke_3_golden.png
new file mode 100644
index 0000000..1212fb3
--- /dev/null
+++ b/tests/res/drawable-nodpi/vector_icon_stroke_3_golden.png
Binary files differ
diff --git a/tests/res/drawable/vector_icon_stroke_1.xml b/tests/res/drawable/vector_icon_stroke_1.xml
new file mode 100644
index 0000000..9b766c0
--- /dev/null
+++ b/tests/res/drawable/vector_icon_stroke_1.xml
@@ -0,0 +1,45 @@
+<!--
+ Copyright (C) 2014 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+    android:height="64dp"
+    android:viewportHeight="200"
+    android:viewportWidth="200"
+    android:width="64dp" >
+
+    <group>
+        <path
+            android:name="background1"
+            android:fillColor="#FF000000"
+            android:pathData="M 0,0 l 100,0 l 0, 100 l -100, 0 z" />
+        <path
+            android:name="background2"
+            android:fillColor="#FF000000"
+            android:pathData="M 100,100 l 100,0 l 0, 100 l -100, 0 z" />
+    </group>
+    <group
+        android:translateX="50"
+        android:translateY="50" >
+        <path
+            android:name="twoLines"
+            android:pathData="M 100,20 l 0 80 l -30 -80"
+            android:strokeColor="#FF00FF00"
+            android:strokeLineCap="butt"
+            android:strokeLineJoin="miter"
+            android:strokeMiterLimit="6"
+            android:strokeWidth="20" />
+    </group>
+
+</vector>
\ No newline at end of file
diff --git a/tests/res/drawable/vector_icon_stroke_2.xml b/tests/res/drawable/vector_icon_stroke_2.xml
new file mode 100644
index 0000000..b0f0cee
--- /dev/null
+++ b/tests/res/drawable/vector_icon_stroke_2.xml
@@ -0,0 +1,45 @@
+<!--
+ Copyright (C) 2014 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+    android:height="64dp"
+    android:viewportHeight="200"
+    android:viewportWidth="200"
+    android:width="64dp" >
+
+    <group>
+        <path
+            android:name="background1"
+            android:fillColor="#FF000000"
+            android:pathData="M 0,0 l 100,0 l 0, 100 l -100, 0 z" />
+        <path
+            android:name="background2"
+            android:fillColor="#FF000000"
+            android:pathData="M 100,100 l 100,0 l 0, 100 l -100, 0 z" />
+    </group>
+    <group
+        android:translateX="50"
+        android:translateY="50" >
+        <path
+            android:name="twoLines"
+            android:pathData="M 100,20 l 0 80 l -30 -80"
+            android:strokeColor="#FF00FF00"
+            android:strokeLineCap="round"
+            android:strokeLineJoin="round"
+            android:strokeMiterLimit="10"
+            android:strokeWidth="20" />
+    </group>
+
+</vector>
\ No newline at end of file
diff --git a/tests/res/drawable/vector_icon_stroke_3.xml b/tests/res/drawable/vector_icon_stroke_3.xml
new file mode 100644
index 0000000..cd7bb16
--- /dev/null
+++ b/tests/res/drawable/vector_icon_stroke_3.xml
@@ -0,0 +1,45 @@
+<!--
+ Copyright (C) 2014 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+    android:height="64dp"
+    android:viewportHeight="200"
+    android:viewportWidth="200"
+    android:width="64dp" >
+
+    <group>
+        <path
+            android:name="background1"
+            android:fillColor="#FF000000"
+            android:pathData="M 0,0 l 100,0 l 0, 100 l -100, 0 z" />
+        <path
+            android:name="background2"
+            android:fillColor="#FF000000"
+            android:pathData="M 100,100 l 100,0 l 0, 100 l -100, 0 z" />
+    </group>
+    <group
+        android:translateX="50"
+        android:translateY="50" >
+        <path
+            android:name="twoLines"
+            android:pathData="M 100,20 l 0 80 l -30 -80"
+            android:strokeColor="#FF00FF00"
+            android:strokeLineCap="square"
+            android:strokeLineJoin="bevel"
+            android:strokeMiterLimit="10"
+            android:strokeWidth="20" />
+    </group>
+
+</vector>
\ No newline at end of file
diff --git a/tests/tests/graphics/src/android/graphics/drawable/cts/BitmapDrawableTest.java b/tests/tests/graphics/src/android/graphics/drawable/cts/BitmapDrawableTest.java
index b415386..1bb6f6d 100644
--- a/tests/tests/graphics/src/android/graphics/drawable/cts/BitmapDrawableTest.java
+++ b/tests/tests/graphics/src/android/graphics/drawable/cts/BitmapDrawableTest.java
@@ -246,10 +246,12 @@
         final InputStream source = mContext.getResources().openRawResource(R.raw.testimage);
         final BitmapDrawable d = new BitmapDrawable(source);
 
-        d.setTint(ColorStateList.valueOf(Color.BLACK), Mode.SRC_OVER);
+        d.setTint(Color.BLACK);
+        d.setTintMode(Mode.SRC_OVER);
         assertEquals("Nine-patch is tinted", Color.BLACK, DrawableTestingUtils.getPixel(d, 0, 0));
 
-        d.setTint(null, null);
+        d.setTintList(null);
+        d.setTintMode(null);
     }
 
     public void testGetOpacity() {
diff --git a/tests/tests/graphics/src/android/graphics/drawable/cts/ColorDrawableTest.java b/tests/tests/graphics/src/android/graphics/drawable/cts/ColorDrawableTest.java
index b4237d7..18d07ce 100644
--- a/tests/tests/graphics/src/android/graphics/drawable/cts/ColorDrawableTest.java
+++ b/tests/tests/graphics/src/android/graphics/drawable/cts/ColorDrawableTest.java
@@ -131,7 +131,8 @@
         final ColorDrawable d = new ColorDrawable(Color.WHITE);
         assertEquals(Color.WHITE, DrawableTestingUtils.getPixel(d, 0, 0));
 
-        d.setTint(ColorStateList.valueOf(Color.BLACK), Mode.SRC_OVER);
+        d.setTint(Color.BLACK);
+        d.setTintMode(Mode.SRC_OVER);
         assertEquals(Color.BLACK, DrawableTestingUtils.getPixel(d, 0, 0));
     }
 }
diff --git a/tests/tests/graphics/src/android/graphics/drawable/cts/DrawableContainerTest.java b/tests/tests/graphics/src/android/graphics/drawable/cts/DrawableContainerTest.java
index 5a81feb..036c756 100644
--- a/tests/tests/graphics/src/android/graphics/drawable/cts/DrawableContainerTest.java
+++ b/tests/tests/graphics/src/android/graphics/drawable/cts/DrawableContainerTest.java
@@ -212,7 +212,8 @@
         assertNull(mDrawableContainer.getCurrent());
 
         mDrawableContainer.setConstantState(mDrawableContainerState);
-        mDrawableContainer.setTint(ColorStateList.valueOf(Color.BLACK), Mode.SRC_OVER);
+        mDrawableContainer.setTint(Color.BLACK);
+        mDrawableContainer.setTintMode(Mode.SRC_OVER);
 
         MockDrawable dr = new MockDrawable();
         addAndSelectDrawable(dr);
@@ -220,8 +221,9 @@
         assertEquals("Initial tint propagates", Mode.SRC_OVER, dr.getTintMode());
 
         dr.reset();
-        mDrawableContainer.setTint(null, null);
-        assertTrue("setTint() propagates", dr.hasSetTintCalled());
+        mDrawableContainer.setTintList(null);
+        mDrawableContainer.setTintMode(null);
+        assertTrue("setImageTintList() propagates", dr.hasSetTintCalled());
     }
 
     public void testOnBoundsChange() {
@@ -857,7 +859,7 @@
         }
 
         @Override
-        public void setTint(ColorStateList tint, Mode tintMode) {
+        public void setTintMode(Mode tintMode) {
             mTintMode = tintMode;
             mHasCalledSetTint = true;
         }
diff --git a/tests/tests/graphics/src/android/graphics/drawable/cts/NinePatchDrawableTest.java b/tests/tests/graphics/src/android/graphics/drawable/cts/NinePatchDrawableTest.java
index d02a297..10ca311 100644
--- a/tests/tests/graphics/src/android/graphics/drawable/cts/NinePatchDrawableTest.java
+++ b/tests/tests/graphics/src/android/graphics/drawable/cts/NinePatchDrawableTest.java
@@ -183,11 +183,13 @@
     }
 
     public void testSetTint() {
-        mNinePatchDrawable.setTint(ColorStateList.valueOf(Color.BLACK), Mode.SRC_OVER);
+        mNinePatchDrawable.setTint(Color.BLACK);
+        mNinePatchDrawable.setTintMode(Mode.SRC_OVER);
         assertEquals("Nine-patch is tinted", Color.BLACK,
                 DrawableTestingUtils.getPixel(mNinePatchDrawable, 0, 0));
 
-        mNinePatchDrawable.setTint(null, null);
+        mNinePatchDrawable.setTintList(null);
+        mNinePatchDrawable.setTintMode(null);
     }
 
     public void testSetDither() {
diff --git a/tests/tests/graphics/src/android/graphics/drawable/cts/ShapeDrawableTest.java b/tests/tests/graphics/src/android/graphics/drawable/cts/ShapeDrawableTest.java
index 0243f24..3475757 100644
--- a/tests/tests/graphics/src/android/graphics/drawable/cts/ShapeDrawableTest.java
+++ b/tests/tests/graphics/src/android/graphics/drawable/cts/ShapeDrawableTest.java
@@ -318,7 +318,8 @@
 
     public void testSetTint() {
         final ShapeDrawable d = new ShapeDrawable(new RectShape());
-        d.setTint(ColorStateList.valueOf(Color.BLACK), Mode.SRC_OVER);
+        d.setTint(Color.BLACK);
+        d.setTintMode(Mode.SRC_OVER);
         assertEquals("Shape is tinted", Color.BLACK, DrawableTestingUtils.getPixel(d, 0, 0));
     }
 
diff --git a/tests/tests/graphics/src/android/graphics/drawable/cts/VectorDrawableTest.java b/tests/tests/graphics/src/android/graphics/drawable/cts/VectorDrawableTest.java
index 1594431..76ff73d 100644
--- a/tests/tests/graphics/src/android/graphics/drawable/cts/VectorDrawableTest.java
+++ b/tests/tests/graphics/src/android/graphics/drawable/cts/VectorDrawableTest.java
@@ -60,6 +60,9 @@
             R.drawable.vector_icon_transformation_6,
             R.drawable.vector_icon_render_order_1,
             R.drawable.vector_icon_render_order_2,
+            R.drawable.vector_icon_stroke_1,
+            R.drawable.vector_icon_stroke_2,
+            R.drawable.vector_icon_stroke_3,
     };
 
     private int[] mGoldenImages = new int[] {
@@ -83,6 +86,9 @@
             R.drawable.vector_icon_transformation_6_golden,
             R.drawable.vector_icon_render_order_1_golden,
             R.drawable.vector_icon_render_order_2_golden,
+            R.drawable.vector_icon_stroke_1_golden,
+            R.drawable.vector_icon_stroke_2_golden,
+            R.drawable.vector_icon_stroke_3_golden,
     };
 
     private static final int IMAGE_WIDTH = 64;
diff --git a/tests/tests/hardware/src/android/hardware/camera2/cts/AllocationTest.java b/tests/tests/hardware/src/android/hardware/camera2/cts/AllocationTest.java
index a77d2ab..fb23a5f 100644
--- a/tests/tests/hardware/src/android/hardware/camera2/cts/AllocationTest.java
+++ b/tests/tests/hardware/src/android/hardware/camera2/cts/AllocationTest.java
@@ -26,6 +26,7 @@
 import android.graphics.ImageFormat;
 import android.graphics.RectF;
 import android.hardware.camera2.CameraAccessException;
+import android.hardware.camera2.CameraCaptureSession;
 import android.hardware.camera2.CameraCharacteristics;
 import android.hardware.camera2.CameraDevice;
 import android.hardware.camera2.CameraManager;
@@ -56,6 +57,7 @@
 
 import com.android.ex.camera2.blocking.BlockingCameraManager.BlockingOpenException;
 import com.android.ex.camera2.blocking.BlockingStateListener;
+import com.android.ex.camera2.blocking.BlockingSessionListener;
 
 import java.util.ArrayList;
 import java.util.Arrays;
@@ -75,7 +77,10 @@
 
     private CameraManager mCameraManager;
     private CameraDevice mCamera;
+    private CameraCaptureSession mSession;
     private BlockingStateListener mCameraListener;
+    private BlockingSessionListener mSessionListener;
+
     private String[] mCameraIds;
 
     private Handler mHandler;
@@ -355,10 +360,9 @@
         assertNotNull("Failed to get Surface", cameraTarget);
         outputSurfaces.add(cameraTarget);
 
-        mCamera.configureOutputs(outputSurfaces);
-        mCameraListener.waitForState(STATE_BUSY, CAMERA_BUSY_TIMEOUT_MS);
-        mCameraListener.waitForState(STATE_IDLE, CAMERA_IDLE_TIMEOUT_MS);
-
+        mSessionListener = new BlockingSessionListener();
+        mCamera.createCaptureSession(outputSurfaces, mSessionListener, mHandler);
+        mSession = mSessionListener.waitAndGetSession(SESSION_CONFIGURE_TIMEOUT_MS);
         CaptureRequest.Builder captureBuilder =
                 mCamera.createCaptureRequest(CameraDevice.TEMPLATE_PREVIEW);
         assertNotNull("Fail to create captureRequest", captureBuilder);
@@ -380,9 +384,9 @@
         checkNotNull("request", request);
         checkNotNull("graph", graph);
 
-        mCamera.capture(request, new CameraDevice.CaptureListener() {
+        mSession.capture(request, new CameraCaptureSession.CaptureListener() {
             @Override
-            public void onCaptureCompleted(CameraDevice camera, CaptureRequest request,
+            public void onCaptureCompleted(CameraCaptureSession session, CaptureRequest request,
                     TotalCaptureResult result) {
                 if (VERBOSE) Log.v(TAG, "Capture completed");
             }
@@ -397,9 +401,11 @@
     private void stopCapture() throws CameraAccessException {
         if (VERBOSE) Log.v(TAG, "Stopping capture and waiting for idle");
         // Stop repeat, wait for captures to complete, and disconnect from surfaces
-        mCamera.configureOutputs(/*outputs*/null);
-        mCameraListener.waitForState(STATE_BUSY, CAMERA_BUSY_TIMEOUT_MS);
-        mCameraListener.waitForState(STATE_UNCONFIGURED, CAMERA_IDLE_TIMEOUT_MS);
+        mSession.close();
+        mSessionListener.getStateWaiter().waitForState(BlockingSessionListener.SESSION_CLOSED,
+                SESSION_CLOSE_TIMEOUT_MS);
+        mSession = null;
+        mSessionListener = null;
     }
 
     /**
@@ -747,7 +753,7 @@
             } catch (BlockingOpenException e) {
                 fail("Fail to open camera asynchronously, " + Log.getStackTraceString(e));
             }
-            mCameraListener.waitForState(STATE_UNCONFIGURED, CAMERA_OPEN_TIMEOUT_MS);
+            mCameraListener.waitForState(STATE_OPENED, CAMERA_OPEN_TIMEOUT_MS);
         }
 
         private void closeDevice(String cameraId) {
@@ -822,14 +828,14 @@
 
             if (!repeating) {
                 for (int i = 0; i < count; ++i) {
-                    mCamera.capture(request, listener, mHandler);
+                    mSession.capture(request, listener, mHandler);
                 }
             } else {
-                mCamera.setRepeatingRequest(request, listener, mHandler);
+                mSession.setRepeatingRequest(request, listener, mHandler);
             }
 
             // Assume that the device is already IDLE.
-            mCameraListener.waitForState(BlockingStateListener.STATE_ACTIVE,
+            mSessionListener.getStateWaiter().waitForState(BlockingSessionListener.SESSION_ACTIVE,
                     CAMERA_ACTIVE_TIMEOUT_MS);
 
             for (int i = 0; i < count; ++i) {
@@ -843,9 +849,9 @@
             }
 
             if (repeating) {
-                mCamera.stopRepeating();
-                mCameraListener.waitForState(BlockingStateListener.STATE_IDLE,
-                        CAMERA_IDLE_TIMEOUT_MS);
+                mSession.stopRepeating();
+                mSessionListener.getStateWaiter().waitForState(
+                    BlockingSessionListener.SESSION_READY, CAMERA_IDLE_TIMEOUT_MS);
             }
 
             // TODO: Make a Configure decorator or some such for configureOutputs
diff --git a/tests/tests/hardware/src/android/hardware/camera2/cts/CameraDeviceTest.java b/tests/tests/hardware/src/android/hardware/camera2/cts/CameraDeviceTest.java
index 103ff31..bd35387 100644
--- a/tests/tests/hardware/src/android/hardware/camera2/cts/CameraDeviceTest.java
+++ b/tests/tests/hardware/src/android/hardware/camera2/cts/CameraDeviceTest.java
@@ -308,47 +308,46 @@
     }
 
     public void testCameraDeviceCapture() throws Exception {
-        runCaptureTest(/*burst*/false, /*repeating*/false, /*flush*/false);
+        runCaptureTest(/*burst*/false, /*repeating*/false, /*abort*/false);
     }
 
     public void testCameraDeviceCaptureBurst() throws Exception {
-        runCaptureTest(/*burst*/true, /*repeating*/false, /*flush*/false);
+        runCaptureTest(/*burst*/true, /*repeating*/false, /*abort*/false);
     }
 
     public void testCameraDeviceRepeatingRequest() throws Exception {
-        runCaptureTest(/*burst*/false, /*repeating*/true, /*flush*/false);
+        runCaptureTest(/*burst*/false, /*repeating*/true, /*abort*/false);
     }
 
     public void testCameraDeviceRepeatingBurst() throws Exception {
-        runCaptureTest(/*burst*/true, /*repeating*/true, /*flush*/false);
+        runCaptureTest(/*burst*/true, /*repeating*/true, /*abort*/false);
     }
 
     /**
-     * Test {@link CameraDevice#flush} API.
+     * Test {@link android.hardware.camera2.CameraCaptureSession#abortCaptures} API.
      *
-     * <p>
-     * Flush is the fastest way to idle the camera device for reconfiguration
-     * with {@link #configureOutputs}, at the cost of discarding in-progress
-     * work. Once the flush is complete, the idle callback will be called.
+     * <p>Abort is the fastest way to idle the camera device for reconfiguration with
+     * {@link android.hardware.camera2.CameraCaptureSession#abortCaptures}, at the cost of
+     * discarding in-progress work. Once the abort is complete, the idle callback will be called.
      * </p>
      */
-    public void testCameraDeviceFlush() throws Exception {
-        runCaptureTest(/*burst*/false, /*repeating*/true, /*flush*/true);
-        runCaptureTest(/*burst*/true, /*repeating*/true, /*flush*/true);
+    public void testCameraDeviceAbort() throws Exception {
+        runCaptureTest(/*burst*/false, /*repeating*/true, /*abort*/true);
+        runCaptureTest(/*burst*/true, /*repeating*/true, /*abort*/true);
         /**
-         * TODO: this is only basic test of flush. we probably should also test below cases:
+         * TODO: this is only basic test of abort. we probably should also test below cases:
          *
-         * 1. Performance. Make sure flush is faster than stopRepeating, we can test each one
-         * a couple of times, then compare the average. Also, for flush() alone, we should make
-         * sure it doesn't take too long time (e.g. <100ms for full devices, <500ms for limited
-         * devices), after the flush, we should be able to get all results back very quickly.
-         * This can be done in performance test.
+         * 1. Performance. Make sure abort is faster than stopRepeating, we can test each one a
+         * couple of times, then compare the average. Also, for abortCaptures() alone, we should
+         * make sure it doesn't take too long time (e.g. <100ms for full devices, <500ms for limited
+         * devices), after the abort, we should be able to get all results back very quickly.  This
+         * can be done in performance test.
          *
-         * 2. Make sure all in-flight request comes back after flush, e.g. submit a couple of
-         * long exposure single captures, then flush, then check if we can get the pending
+         * 2. Make sure all in-flight request comes back after abort, e.g. submit a couple of
+         * long exposure single captures, then abort, then check if we can get the pending
          * request back quickly.
          *
-         * 3. Also need check onCaptureSequenceCompleted for repeating burst after flush().
+         * 3. Also need check onCaptureSequenceCompleted for repeating burst after abortCaptures().
          */
     }
 
@@ -694,14 +693,14 @@
     /**
      * Run capture test with different test configurations.
      *
-     * @param burst If the test uses {@link CameraDevice#captureBurst} or
-     * {@link CameraDevice#setRepeatingBurst} to capture the burst.
-     * @param repeating If the test uses {@link CameraDevice#setRepeatingBurst} or
-     * {@link CameraDevice#setRepeatingRequest} for repeating capture.
-     * @param flush If the test uses {@link CameraDevice#flush} to stop the repeating capture.
-     * It has no effect if repeating is false.
+     * @param burst If the test uses {@link CameraCaptureSession#captureBurst} or
+     * {@link CameraCaptureSession#setRepeatingBurst} to capture the burst.
+     * @param repeating If the test uses {@link CameraCaptureSession#setRepeatingBurst} or
+     * {@link CameraCaptureSession#setRepeatingRequest} for repeating capture.
+     * @param abort If the test uses {@link CameraCaptureSession#abortCaptures} to stop the
+     * repeating capture.  It has no effect if repeating is false.
      */
-    private void runCaptureTest(boolean burst, boolean repeating, boolean flush) throws Exception {
+    private void runCaptureTest(boolean burst, boolean repeating, boolean abort) throws Exception {
         for (int i = 0; i < mCameraIds.length; i++) {
             try {
                 openDevice(mCameraIds[i], mCameraMockListener);
@@ -712,12 +711,12 @@
                 if (!burst) {
                     // Test: that a single capture of each template type succeeds.
                     for (int j = 0; j < sTemplates.length; j++) {
-                        captureSingleShot(mCameraIds[i], sTemplates[j], repeating, flush);
+                        captureSingleShot(mCameraIds[i], sTemplates[j], repeating, abort);
                     }
                 }
                 else {
                     // Test: burst of one shot
-                    captureBurstShot(mCameraIds[i], sTemplates, 1, repeating, flush);
+                    captureBurstShot(mCameraIds[i], sTemplates, 1, repeating, abort);
 
                     int[] templates = new int[] {
                             CameraDevice.TEMPLATE_STILL_CAPTURE,
@@ -728,11 +727,11 @@
                             };
 
                     // Test: burst of 5 shots of the same template type
-                    captureBurstShot(mCameraIds[i], templates, templates.length, repeating, flush);
+                    captureBurstShot(mCameraIds[i], templates, templates.length, repeating, abort);
 
                     // Test: burst of 5 shots of different template types
                     captureBurstShot(
-                            mCameraIds[i], sTemplates, sTemplates.length, repeating, flush);
+                            mCameraIds[i], sTemplates, sTemplates.length, repeating, abort);
                 }
                 verify(mCameraMockListener, never())
                         .onError(
@@ -752,7 +751,7 @@
     private void captureSingleShot(
             String id,
             int template,
-            boolean repeating, boolean flush) throws Exception {
+            boolean repeating, boolean abort) throws Exception {
 
         assertEquals("Bad initial state for preparing to capture",
                 mLatestSessionState, SESSION_READY);
@@ -775,7 +774,7 @@
         verifyCaptureResults(mockCaptureListener, expectedCaptureResultCount);
 
         if (repeating) {
-            if (flush) {
+            if (abort) {
                 mSession.abortCaptures();
             } else {
                 mSession.stopRepeating();
@@ -789,7 +788,7 @@
             int[] templates,
             int len,
             boolean repeating,
-            boolean flush) throws Exception {
+            boolean abort) throws Exception {
 
         assertEquals("Bad initial state for preparing to capture",
                 mLatestSessionState, SESSION_READY);
@@ -825,7 +824,7 @@
         verifyCaptureResults(mockCaptureListener, expectedResultCount);
 
         if (repeating) {
-            if (flush) {
+            if (abort) {
                 mSession.abortCaptures();
             } else {
                 mSession.stopRepeating();
diff --git a/tests/tests/hardware/src/android/hardware/camera2/cts/CameraManagerTest.java b/tests/tests/hardware/src/android/hardware/camera2/cts/CameraManagerTest.java
index 6668db0..a8c9896 100644
--- a/tests/tests/hardware/src/android/hardware/camera2/cts/CameraManagerTest.java
+++ b/tests/tests/hardware/src/android/hardware/camera2/cts/CameraManagerTest.java
@@ -211,14 +211,13 @@
                     mCameraManager.openCamera(ids[i], mCameraListener, mHandler);
 
                     // Block until unConfigured
-                    mCameraListener.waitForState(BlockingStateListener.STATE_UNCONFIGURED,
+                    mCameraListener.waitForState(BlockingStateListener.STATE_OPENED,
                             CameraTestUtils.CAMERA_IDLE_TIMEOUT_MS);
 
                     // Ensure state transitions are in right order:
                     // -- 1) Opened
-                    // -- 2) Unconfigured
                     // Ensure no other state transitions have occurred:
-                    camera = verifyCameraStateOpenedThenUnconfigured(ids[i], mockListener);
+                    camera = verifyCameraStateOpened(ids[i], mockListener);
                 } finally {
                     if (camera != null) {
                         camera.close();
@@ -272,7 +271,7 @@
                 }
 
                 List<Integer> expectedStates = new ArrayList<Integer>();
-                expectedStates.add(BlockingStateListener.STATE_UNCONFIGURED);
+                expectedStates.add(BlockingStateListener.STATE_OPENED);
                 expectedStates.add(BlockingStateListener.STATE_ERROR);
                 int state = mCameraListener.waitForAnyOfStates(
                         expectedStates, CameraTestUtils.CAMERA_IDLE_TIMEOUT_MS);
@@ -316,10 +315,10 @@
                     camera = argument.getValue();
                     assertNotNull("Expected a non-null camera for the error transition for ID: "
                             + ids[i], camera);
-                } else if (state == BlockingStateListener.STATE_UNCONFIGURED) {
+                } else if (state == BlockingStateListener.STATE_OPENED) {
                     // Camera opened successfully.
-                    // => onOpened+onUnconfigured called exactly once with same argument
-                    camera = verifyCameraStateOpenedThenUnconfigured(cameraId,
+                    // => onOpened called exactly once
+                    camera = verifyCameraStateOpened(cameraId,
                             mockListener);
                 } else {
                     fail("Unexpected state " + state);
@@ -373,7 +372,7 @@
      *
      * @return The camera device (non-{@code null}).
      */
-    private static CameraDevice verifyCameraStateOpenedThenUnconfigured(String cameraId,
+    private static CameraDevice verifyCameraStateOpened(String cameraId,
             MockStateListener listener) {
         ArgumentCaptor<CameraDevice> argument =
                 ArgumentCaptor.forClass(CameraDevice.class);
@@ -382,7 +381,6 @@
         /**
          * State transitions (in that order):
          *  1) onOpened
-         *  2) onUnconfigured
          *
          * No other transitions must occur for successful #openCamera
          */
@@ -391,16 +389,9 @@
 
         CameraDevice camera = argument.getValue();
         assertNotNull(
-                String.format("Failed to unconfigure camera device ID: %s", cameraId),
+                String.format("Failed to open camera device ID: %s", cameraId),
                 camera);
 
-        inOrder.verify(listener)
-                .onUnconfigured(argument.capture());
-
-        assertEquals(String.format("Opened camera did not match unconfigured camera " +
-                "for camera device ID: %s", cameraId),
-                camera,
-                argument.getValue());
         // Do not use inOrder here since that would skip anything called before onOpened
         verifyNoMoreInteractions(listener);
 
@@ -450,13 +441,11 @@
                 ArgumentCaptor<CameraDevice> argument =
                         ArgumentCaptor.forClass(CameraDevice.class);
                 verify(mockSuccessListener, atLeastOnce()).onOpened(argument.capture());
-                successListener.waitForState(BlockingStateListener.STATE_UNCONFIGURED,
-                        CameraTestUtils.CAMERA_IDLE_TIMEOUT_MS);
 
                 failListener.waitForState(BlockingStateListener.STATE_ERROR,
                         CameraTestUtils.CAMERA_IDLE_TIMEOUT_MS);
 
-                successCamera = verifyCameraStateOpenedThenUnconfigured(
+                successCamera = verifyCameraStateOpened(
                         ids[i], mockSuccessListener);
 
                 verify(mockFailListener)
diff --git a/tests/tests/hardware/src/android/hardware/camera2/cts/CameraTestUtils.java b/tests/tests/hardware/src/android/hardware/camera2/cts/CameraTestUtils.java
index ffddb99..bbfd7b5 100644
--- a/tests/tests/hardware/src/android/hardware/camera2/cts/CameraTestUtils.java
+++ b/tests/tests/hardware/src/android/hardware/camera2/cts/CameraTestUtils.java
@@ -193,17 +193,17 @@
         }
     }
 
-    public static class SimpleCaptureListener extends CameraDevice.CaptureListener {
+    public static class SimpleCaptureListener extends CameraCaptureSession.CaptureListener {
         private final LinkedBlockingQueue<CaptureResult> mQueue =
                 new LinkedBlockingQueue<CaptureResult>();
 
         @Override
-        public void onCaptureStarted(CameraDevice camera, CaptureRequest request, long timestamp)
+        public void onCaptureStarted(CameraCaptureSession session, CaptureRequest request, long timestamp)
         {
         }
 
         @Override
-        public void onCaptureCompleted(CameraDevice camera, CaptureRequest request,
+        public void onCaptureCompleted(CameraCaptureSession session, CaptureRequest request,
                 TotalCaptureResult result) {
             try {
                 mQueue.put(result);
@@ -214,12 +214,12 @@
         }
 
         @Override
-        public void onCaptureFailed(CameraDevice camera, CaptureRequest request,
+        public void onCaptureFailed(CameraCaptureSession session, CaptureRequest request,
                 CaptureFailure failure) {
         }
 
         @Override
-        public void onCaptureSequenceCompleted(CameraDevice camera, int sequenceId,
+        public void onCaptureSequenceCompleted(CameraCaptureSession session, int sequenceId,
                 long frameNumber) {
         }
 
@@ -328,29 +328,11 @@
     }
 
     /**
-     * Configure camera output surfaces.
-     *
-     * @param camera The CameraDevice to be configured.
-     * @param outputSurfaces The surface list that used for camera output.
-     * @param listener The callback CameraDevice will notify when capture results are available.
-     */
-    public static void configureCameraOutputs(CameraDevice camera, List<Surface> outputSurfaces,
-            BlockingStateListener listener) throws CameraAccessException {
-        camera.configureOutputs(outputSurfaces);
-        listener.waitForState(STATE_BUSY, CAMERA_BUSY_TIMEOUT_MS);
-        if (outputSurfaces == null || outputSurfaces.size() == 0) {
-            listener.waitForState(STATE_UNCONFIGURED, CAMERA_UNCONFIGURED_TIMEOUT_MS);
-        } else {
-            listener.waitForState(STATE_IDLE, CAMERA_IDLE_TIMEOUT_MS);
-        }
-    }
-
-    /**
      * Configure a new camera session with output surfaces.
      *
      * @param camera The CameraDevice to be configured.
      * @param outputSurfaces The surface list that used for camera output.
-     * @param listener The callback camera session will notify when capture results are available.
+     * @param listener The callback CameraDevice will notify when capture results are available.
      */
     public static CameraCaptureSession configureCameraSession(CameraDevice camera,
             List<Surface> outputSurfaces,
diff --git a/tests/tests/hardware/src/android/hardware/camera2/cts/CaptureRequestTest.java b/tests/tests/hardware/src/android/hardware/camera2/cts/CaptureRequestTest.java
index a9b0583..d275197 100644
--- a/tests/tests/hardware/src/android/hardware/camera2/cts/CaptureRequestTest.java
+++ b/tests/tests/hardware/src/android/hardware/camera2/cts/CaptureRequestTest.java
@@ -565,7 +565,7 @@
         for (int mode : availableModes) {
             requestBuilder.set(CaptureRequest.NOISE_REDUCTION_MODE, mode);
             resultListener = new SimpleCaptureListener();
-            mCamera.setRepeatingRequest(requestBuilder.build(), resultListener, mHandler);
+            mSession.setRepeatingRequest(requestBuilder.build(), resultListener, mHandler);
             waitForSettingsApplied(resultListener, NUM_FRAMES_WAITED_FOR_UNKNOWN_LATENCY);
 
             verifyCaptureResultForKey(CaptureResult.NOISE_REDUCTION_MODE, mode,
@@ -596,7 +596,7 @@
             requestBuilder.set(CaptureRequest.LENS_FOCUS_DISTANCE, testDistances[i]);
             request = requestBuilder.build();
             resultListener = new SimpleCaptureListener();
-            mCamera.setRepeatingRequest(request, resultListener, mHandler);
+            mSession.setRepeatingRequest(request, resultListener, mHandler);
             waitForSettingsApplied(resultListener, NUM_FRAMES_WAITED_FOR_UNKNOWN_LATENCY);
             resultDistances[i] = verifyFocusDistanceControl(testDistances[i], request,
                     resultListener);
@@ -619,7 +619,7 @@
                 requestBuilder.set(CaptureRequest.LENS_FOCUS_DISTANCE, hyperFocalDistance);
                 request = requestBuilder.build();
                 resultListener = new SimpleCaptureListener();
-                mCamera.setRepeatingRequest(request, resultListener, mHandler);
+                mSession.setRepeatingRequest(request, resultListener, mHandler);
                 waitForSettingsApplied(resultListener, NUM_FRAMES_WAITED_FOR_UNKNOWN_LATENCY);
 
                 // Then wait for the lens.state to be stationary.
@@ -692,7 +692,7 @@
         for (int mode : edgeModes) {
             requestBuilder.set(CaptureRequest.EDGE_MODE, mode);
             resultListener = new SimpleCaptureListener();
-            mCamera.setRepeatingRequest(requestBuilder.build(), resultListener, mHandler);
+            mSession.setRepeatingRequest(requestBuilder.build(), resultListener, mHandler);
             waitForSettingsApplied(resultListener, NUM_FRAMES_WAITED_FOR_UNKNOWN_LATENCY);
 
             verifyCaptureResultForKey(CaptureResult.EDGE_MODE, mode, resultListener,
@@ -747,7 +747,7 @@
         manualRequestBuilder.set(CaptureRequest.COLOR_CORRECTION_GAINS, UNIT_GAIN);
         manualRequestBuilder.set(CaptureRequest.COLOR_CORRECTION_TRANSFORM, IDENTITY_TRANSFORM);
         request = manualRequestBuilder.build();
-        mCamera.capture(request, listener, mHandler);
+        mSession.capture(request, listener, mHandler);
         result = listener.getCaptureResultForRequest(request, NUM_RESULTS_WAIT_TIMEOUT);
         RggbChannelVector gains = result.get(CaptureResult.COLOR_CORRECTION_GAINS);
         ColorSpaceTransform transform = result.get(CaptureResult.COLOR_CORRECTION_TRANSFORM);
@@ -764,7 +764,7 @@
         manualRequestBuilder.set(CaptureRequest.CONTROL_MODE, CaptureRequest.CONTROL_MODE_AUTO);
         manualRequestBuilder.set(CaptureRequest.COLOR_CORRECTION_MODE, colorCorrectionMode);
         request = manualRequestBuilder.build();
-        mCamera.capture(request, listener, mHandler);
+        mSession.capture(request, listener, mHandler);
         result = listener.getCaptureResultForRequest(request, NUM_RESULTS_WAIT_TIMEOUT);
         validateColorCorrectionResult(result, colorCorrectionMode);
         mCollector.expectEquals("control mode result/request mismatch",
@@ -775,7 +775,7 @@
         manualRequestBuilder.set(CaptureRequest.CONTROL_MODE, CaptureRequest.CONTROL_MODE_AUTO);
         manualRequestBuilder.set(CaptureRequest.COLOR_CORRECTION_MODE, colorCorrectionMode);
         request = manualRequestBuilder.build();
-        mCamera.capture(request, listener, mHandler);
+        mSession.capture(request, listener, mHandler);
         result = listener.getCaptureResultForRequest(request, NUM_RESULTS_WAIT_TIMEOUT);
         validateColorCorrectionResult(result, colorCorrectionMode);
         mCollector.expectEquals("control mode result/request mismatch",
@@ -831,7 +831,7 @@
             throw new IllegalArgumentException("This test only works when AE mode is ON or OFF");
         }
 
-        mCamera.setRepeatingRequest(requestBuilder.build(), listener, mHandler);
+        mSession.setRepeatingRequest(requestBuilder.build(), listener, mHandler);
         waitForSettingsApplied(listener, NUM_FRAMES_WAITED_FOR_UNKNOWN_LATENCY);
 
         // For camera that doesn't have flash unit, flash state should always be UNAVAILABLE.
@@ -1067,7 +1067,7 @@
         // Just send several captures with auto AE, lock off.
         CaptureRequest request = requestBuilder.build();
         for (int i = 0; i < NUM_CAPTURES_BEFORE_LOCK; i++) {
-            mCamera.capture(request, listener, mHandler);
+            mSession.capture(request, listener, mHandler);
         }
         waitForNumResults(listener, NUM_CAPTURES_BEFORE_LOCK);
 
@@ -1136,7 +1136,7 @@
                 }
 
                 changeExposure(requestBuilder, expTimes[i], sensitivities[j]);
-                mCamera.capture(requestBuilder.build(), listener, mHandler);
+                mSession.capture(requestBuilder.build(), listener, mHandler);
 
                 CaptureResult result = listener.getCaptureResult(WAIT_FOR_RESULT_TIMEOUT_MS);
                 long resultExpTime = getValueNotNull(result, CaptureResult.SENSOR_EXPOSURE_TIME);
@@ -1468,7 +1468,7 @@
             SimpleCaptureListener listener;
             requestBuilder.set(CaptureRequest.CONTROL_AWB_MODE, mode);
             listener = new SimpleCaptureListener();
-            mCamera.setRepeatingRequest(requestBuilder.build(), listener, mHandler);
+            mSession.setRepeatingRequest(requestBuilder.build(), listener, mHandler);
             waitForSettingsApplied(listener, NUM_FRAMES_WAITED_FOR_UNKNOWN_LATENCY);
 
             // Verify AWB mode in capture result.
@@ -1478,7 +1478,7 @@
             // Verify color correction transform and gains stay unchanged after a lock.
             requestBuilder.set(CaptureRequest.CONTROL_AWB_LOCK, true);
             listener = new SimpleCaptureListener();
-            mCamera.setRepeatingRequest(requestBuilder.build(), listener, mHandler);
+            mSession.setRepeatingRequest(requestBuilder.build(), listener, mHandler);
             waitForSettingsApplied(listener, NUM_FRAMES_WAITED_FOR_UNKNOWN_LATENCY);
 
             if (mStaticInfo.areKeysAvailable(CaptureResult.CONTROL_AWB_STATE)) {
@@ -1541,7 +1541,7 @@
             SimpleCaptureListener listener;
             requestBuilder.set(CaptureRequest.CONTROL_AF_MODE, mode);
             listener = new SimpleCaptureListener();
-            mCamera.setRepeatingRequest(requestBuilder.build(), listener, mHandler);
+            mSession.setRepeatingRequest(requestBuilder.build(), listener, mHandler);
             waitForSettingsApplied(listener, NUM_FRAMES_WAITED_FOR_UNKNOWN_LATENCY);
 
             // Verify AF mode in capture result.
@@ -1583,7 +1583,7 @@
         for (int mode : videoStabModes) {
             listener = new SimpleCaptureListener();
             requestBuilder.set(CaptureRequest.CONTROL_VIDEO_STABILIZATION_MODE, mode);
-            mCamera.setRepeatingRequest(requestBuilder.build(), listener, mHandler);
+            mSession.setRepeatingRequest(requestBuilder.build(), listener, mHandler);
             waitForSettingsApplied(listener, NUM_FRAMES_WAITED_FOR_UNKNOWN_LATENCY);
             verifyCaptureResultForKey(CaptureResult.CONTROL_VIDEO_STABILIZATION_MODE, mode,
                     listener, NUM_FRAMES_VERIFIED);
@@ -1592,7 +1592,7 @@
         for (int mode : opticalStabModes) {
             listener = new SimpleCaptureListener();
             requestBuilder.set(CaptureRequest.LENS_OPTICAL_STABILIZATION_MODE, mode);
-            mCamera.setRepeatingRequest(requestBuilder.build(), listener, mHandler);
+            mSession.setRepeatingRequest(requestBuilder.build(), listener, mHandler);
             waitForSettingsApplied(listener, NUM_FRAMES_WAITED_FOR_UNKNOWN_LATENCY);
             verifyCaptureResultForKey(CaptureResult.LENS_OPTICAL_STABILIZATION_MODE, mode,
                     listener, NUM_FRAMES_VERIFIED);
@@ -1683,7 +1683,7 @@
                 requestBuilder.set(CaptureRequest.SCALER_CROP_REGION, cropRegions[i]);
                 requests[i] = requestBuilder.build();
                 for (int j = 0; j < CAPTURE_SUBMIT_REPEAT; ++j) {
-                    mCamera.capture(requests[i], listener, mHandler);
+                    mSession.capture(requests[i], listener, mHandler);
                 }
 
                 /*
@@ -1774,7 +1774,7 @@
         for(int mode : sceneModes) {
             requestBuilder.set(CaptureRequest.CONTROL_SCENE_MODE, mode);
             listener = new SimpleCaptureListener();
-            mCamera.setRepeatingRequest(requestBuilder.build(), listener, mHandler);
+            mSession.setRepeatingRequest(requestBuilder.build(), listener, mHandler);
             waitForSettingsApplied(listener, NUM_FRAMES_WAITED_FOR_UNKNOWN_LATENCY);
 
             verifyCaptureResultForKey(CaptureResult.CONTROL_SCENE_MODE,
@@ -1797,7 +1797,7 @@
         for(int mode : effectModes) {
             requestBuilder.set(CaptureRequest.CONTROL_EFFECT_MODE, mode);
             listener = new SimpleCaptureListener();
-            mCamera.setRepeatingRequest(requestBuilder.build(), listener, mHandler);
+            mSession.setRepeatingRequest(requestBuilder.build(), listener, mHandler);
             waitForSettingsApplied(listener, NUM_FRAMES_WAITED_FOR_UNKNOWN_LATENCY);
 
             verifyCaptureResultForKey(CaptureResult.CONTROL_EFFECT_MODE,
@@ -2056,7 +2056,7 @@
             }
         }
 
-        mCamera.stopRepeating();
+        mSession.stopRepeating();
     }
 
     /**
diff --git a/tests/tests/hardware/src/android/hardware/camera2/cts/CaptureResultTest.java b/tests/tests/hardware/src/android/hardware/camera2/cts/CaptureResultTest.java
index 8293fb0..2ccbc3d 100644
--- a/tests/tests/hardware/src/android/hardware/camera2/cts/CaptureResultTest.java
+++ b/tests/tests/hardware/src/android/hardware/camera2/cts/CaptureResultTest.java
@@ -102,7 +102,7 @@
                 // Configure output streams.
                 List<Surface> outputSurfaces = new ArrayList<Surface>(1);
                 outputSurfaces.add(mReaderSurface);
-                configureCameraOutputs(mCamera, outputSurfaces, mCameraListener);;
+                createSession(outputSurfaces);
 
                 CaptureRequest.Builder requestBuilder =
                         mCamera.createCaptureRequest(CameraDevice.TEMPLATE_PREVIEW);
diff --git a/tests/tests/hardware/src/android/hardware/camera2/cts/DngCreatorTest.java b/tests/tests/hardware/src/android/hardware/camera2/cts/DngCreatorTest.java
index 5a9baeb..136cd0d 100644
--- a/tests/tests/hardware/src/android/hardware/camera2/cts/DngCreatorTest.java
+++ b/tests/tests/hardware/src/android/hardware/camera2/cts/DngCreatorTest.java
@@ -17,6 +17,7 @@
 package android.hardware.camera2.cts;
 
 import android.graphics.ImageFormat;
+import android.hardware.camera2.CameraCaptureSession;
 import android.hardware.camera2.CameraCharacteristics;
 import android.hardware.camera2.CameraDevice;
 import android.hardware.camera2.CaptureRequest;
@@ -36,7 +37,7 @@
 import java.util.ArrayList;
 import java.util.List;
 
-import static android.hardware.camera2.cts.CameraTestUtils.configureCameraOutputs;
+import static android.hardware.camera2.cts.CameraTestUtils.configureCameraSession;
 
 /**
  * Tests for the DngCreator API.
@@ -189,7 +190,7 @@
 
     private CaptureRequest.Builder prepareCaptureRequestForSurfaces(List<Surface> surfaces)
             throws Exception {
-        configureCameraOutputs(mCamera, surfaces, mCameraListener);
+        createSession(surfaces);
 
         CaptureRequest.Builder captureBuilder =
                 mCamera.createCaptureRequest(CameraDevice.TEMPLATE_PREVIEW);
diff --git a/tests/tests/hardware/src/android/hardware/camera2/cts/ImageReaderTest.java b/tests/tests/hardware/src/android/hardware/camera2/cts/ImageReaderTest.java
index d3e9bef..a44b255 100644
--- a/tests/tests/hardware/src/android/hardware/camera2/cts/ImageReaderTest.java
+++ b/tests/tests/hardware/src/android/hardware/camera2/cts/ImageReaderTest.java
@@ -373,7 +373,7 @@
 
     private CaptureRequest.Builder prepareCaptureRequestForSurfaces(List<Surface> surfaces)
             throws Exception {
-        configureCameraOutputs(mCamera, surfaces, mCameraListener);
+        createSession(surfaces);
 
         CaptureRequest.Builder captureBuilder =
                 mCamera.createCaptureRequest(CameraDevice.TEMPLATE_PREVIEW);
diff --git a/tests/tests/hardware/src/android/hardware/camera2/cts/RecordingTest.java b/tests/tests/hardware/src/android/hardware/camera2/cts/RecordingTest.java
index b120000..c36c937 100644
--- a/tests/tests/hardware/src/android/hardware/camera2/cts/RecordingTest.java
+++ b/tests/tests/hardware/src/android/hardware/camera2/cts/RecordingTest.java
@@ -12,10 +12,11 @@
 package android.hardware.camera2.cts;
 
 import static android.hardware.camera2.cts.CameraTestUtils.*;
-import static com.android.ex.camera2.blocking.BlockingStateListener.*;
+import static com.android.ex.camera2.blocking.BlockingSessionListener.*;
 
 import android.graphics.ImageFormat;
 import android.hardware.camera2.CameraCharacteristics;
+import android.hardware.camera2.CameraCaptureSession;
 import android.hardware.camera2.CameraDevice;
 import android.hardware.camera2.CaptureRequest;
 import android.hardware.camera2.CaptureResult;
@@ -38,6 +39,8 @@
 import android.util.Range;
 import android.view.Surface;
 
+import com.android.ex.camera2.blocking.BlockingSessionListener;
+
 import junit.framework.AssertionFailedError;
 
 import java.io.File;
@@ -336,9 +339,8 @@
         if (mReaderSurface != null) {
             outputSurfaces.add(mReaderSurface);
         }
-        mCamera.configureOutputs(outputSurfaces);
-        mCameraListener.waitForState(STATE_BUSY, CAMERA_BUSY_TIMEOUT_MS);
-        mCameraListener.waitForState(STATE_IDLE, CAMERA_IDLE_TIMEOUT_MS);
+        mSessionListener = new BlockingSessionListener();
+        mSession = configureCameraSession(mCamera, outputSurfaces, mSessionListener, mHandler);
 
         CaptureRequest.Builder recordingRequestBuilder =
                 mCamera.createCaptureRequest(CameraDevice.TEMPLATE_RECORD);
@@ -368,7 +370,7 @@
         for (int i = 0; i < slowMotionFactor - 1; i++) {
             slowMoRequests.add(recordingOnlyBuilder.build()); // Recording only.
         }
-        mCamera.setRepeatingBurst(slowMoRequests, null, null);
+        mSession.setRepeatingBurst(slowMoRequests, null, null);
 
         if (useMediaRecorder) {
             mMediaRecorder.start();
@@ -584,9 +586,9 @@
                 for (int i = 0; i < BURST_VIDEO_SNAPSHOT_NUM; i++) {
                     requests.add(request);
                 }
-                mCamera.captureBurst(requests, resultListener, mHandler);
+                mSession.captureBurst(requests, resultListener, mHandler);
             } else {
-                mCamera.capture(request, resultListener, mHandler);
+                mSession.capture(request, resultListener, mHandler);
             }
 
             // make sure recording is still going after video snapshot
@@ -679,8 +681,8 @@
         mVideoSize = sz;
     }
 
-    private void startRecording(boolean useMediaRecorder, CameraDevice.CaptureListener listener)
-            throws Exception {
+    private void startRecording(boolean useMediaRecorder,
+            CameraCaptureSession.CaptureListener listener) throws Exception {
         List<Surface> outputSurfaces = new ArrayList<Surface>(2);
         assertTrue("Both preview and recording surfaces should be valid",
                 mPreviewSurface.isValid() && mRecordingSurface.isValid());
@@ -690,9 +692,8 @@
         if (mReaderSurface != null) {
             outputSurfaces.add(mReaderSurface);
         }
-        mCamera.configureOutputs(outputSurfaces);
-        mCameraListener.waitForState(STATE_BUSY, CAMERA_BUSY_TIMEOUT_MS);
-        mCameraListener.waitForState(STATE_IDLE, CAMERA_IDLE_TIMEOUT_MS);
+        mSessionListener = new BlockingSessionListener();
+        mSession = configureCameraSession(mCamera, outputSurfaces, mSessionListener, mHandler);
 
         CaptureRequest.Builder recordingRequestBuilder =
                 mCamera.createCaptureRequest(CameraDevice.TEMPLATE_RECORD);
@@ -701,7 +702,7 @@
         recordingRequestBuilder.set(CaptureRequest.CONTROL_AE_TARGET_FPS_RANGE, fpsRange);
         recordingRequestBuilder.addTarget(mRecordingSurface);
         recordingRequestBuilder.addTarget(mPreviewSurface);
-        mCamera.setRepeatingRequest(recordingRequestBuilder.build(), listener, mHandler);
+        mSession.setRepeatingRequest(recordingRequestBuilder.build(), listener, mHandler);
 
         if (useMediaRecorder) {
             mMediaRecorder.start();
@@ -720,9 +721,8 @@
         }
         // Stop repeating, wait for captures to complete, and disconnect from
         // surfaces
-        mCamera.configureOutputs(/* outputs */null);
-        mCameraListener.waitForState(STATE_BUSY, CAMERA_BUSY_TIMEOUT_MS);
-        mCameraListener.waitForState(STATE_UNCONFIGURED, CAMERA_IDLE_TIMEOUT_MS);
+        mSession.close();
+        mSessionListener.getStateWaiter().waitForState(SESSION_CLOSED, SESSION_CLOSE_TIMEOUT_MS);
     }
 
     private void stopRecording(boolean useMediaRecorder) throws Exception {
@@ -757,7 +757,8 @@
             mediaPlayer.setDataSource(mOutMediaFileName);
             mediaPlayer.prepare();
             Size videoSz = new Size(mediaPlayer.getVideoWidth(), mediaPlayer.getVideoHeight());
-            assertTrue("Video size doesn't match", videoSz.equals(sz));
+            assertTrue("Video size doesn't match, expected " + sz.toString() +
+                    " got " + videoSz.toString(), videoSz.equals(sz));
             int duration = mediaPlayer.getDuration();
 
             // TODO: Don't skip this for video snapshot
diff --git a/tests/tests/hardware/src/android/hardware/camera2/cts/StillCaptureTest.java b/tests/tests/hardware/src/android/hardware/camera2/cts/StillCaptureTest.java
index c821d2f..2384fb4 100644
--- a/tests/tests/hardware/src/android/hardware/camera2/cts/StillCaptureTest.java
+++ b/tests/tests/hardware/src/android/hardware/camera2/cts/StillCaptureTest.java
@@ -43,6 +43,7 @@
 import android.util.Rational;
 import android.view.Surface;
 
+import com.android.ex.camera2.blocking.BlockingSessionListener;
 import com.android.ex.camera2.exceptions.TimeoutRuntimeException;
 
 import java.io.ByteArrayOutputStream;
@@ -389,7 +390,7 @@
 
         // take a picture
         CaptureRequest request = stillRequest.build();
-        mCamera.capture(request, stillResultListener, mHandler);
+        mSession.capture(request, stillResultListener, mHandler);
         stillResultListener.getCaptureResultForRequest(request,
                 WAIT_FOR_RESULT_TIMEOUT_MS);
 
@@ -451,7 +452,7 @@
                 isRegionsSupportedFor3A(MAX_REGIONS_AF_INDEX);
         if (hasFocuser) {
             SimpleAutoFocusListener afListener = new SimpleAutoFocusListener();
-            focuser = new Camera2Focuser(mCamera, mPreviewSurface, afListener,
+            focuser = new Camera2Focuser(mCamera, mSession, mPreviewSurface, afListener,
                     mStaticInfo.getCharacteristics(), mHandler);
             if (canSetAfRegion) {
                 stillRequest.set(CaptureRequest.CONTROL_AF_REGIONS, afRegions);
@@ -486,7 +487,7 @@
             previewRequest.set(CaptureRequest.CONTROL_AWB_REGIONS, awbRegions);
             stillRequest.set(CaptureRequest.CONTROL_AWB_REGIONS, awbRegions);
         }
-        mCamera.setRepeatingRequest(previewRequest.build(), resultListener, mHandler);
+        mSession.setRepeatingRequest(previewRequest.build(), resultListener, mHandler);
         if (mStaticInfo.isHardwareLevelLimitedOrBetter()) {
             waitForResultValue(resultListener, CaptureResult.CONTROL_AWB_STATE,
                     CaptureResult.CONTROL_AWB_STATE_CONVERGED, NUM_RESULTS_WAIT_TIMEOUT);
@@ -495,7 +496,7 @@
             waitForSettingsApplied(resultListener, NUM_FRAMES_WAITED_FOR_UNKNOWN_LATENCY);
         }
         previewRequest.set(CaptureRequest.CONTROL_AWB_LOCK, true);
-        mCamera.setRepeatingRequest(previewRequest.build(), resultListener, mHandler);
+        mSession.setRepeatingRequest(previewRequest.build(), resultListener, mHandler);
         // Validate the next result immediately for region and mode.
         result = resultListener.getCaptureResult(WAIT_FOR_RESULT_TIMEOUT_MS);
         mCollector.expectEquals("AWB mode in result and request should be same",
@@ -518,10 +519,10 @@
             previewRequest.set(CaptureRequest.CONTROL_AE_REGIONS, aeRegions);
             stillRequest.set(CaptureRequest.CONTROL_AE_REGIONS, aeRegions);
         }
-        mCamera.setRepeatingRequest(previewRequest.build(), resultListener, mHandler);
+        mSession.setRepeatingRequest(previewRequest.build(), resultListener, mHandler);
         previewRequest.set(CaptureRequest.CONTROL_AE_PRECAPTURE_TRIGGER,
                 CaptureRequest.CONTROL_AE_PRECAPTURE_TRIGGER_START);
-        mCamera.capture(previewRequest.build(), resultListener, mHandler);
+        mSession.capture(previewRequest.build(), resultListener, mHandler);
         waitForAeStable(resultListener, NUM_FRAMES_WAITED_FOR_UNKNOWN_LATENCY);
 
         // Validate the next result immediately for region and mode.
@@ -545,7 +546,7 @@
          */
         resultListener = new SimpleCaptureListener();
         CaptureRequest request = stillRequest.build();
-        mCamera.capture(request, resultListener, mHandler);
+        mSession.capture(request, resultListener, mHandler);
         // Validate the next result immediately for region and mode.
         result = resultListener.getCaptureResultForRequest(request, WAIT_FOR_RESULT_TIMEOUT_MS);
         mCollector.expectEquals("AF mode in result and request should be same",
@@ -581,7 +582,7 @@
         startPreview(requestBuilder, maxPreviewSz, listener);
 
         SimpleAutoFocusListener afListener = new SimpleAutoFocusListener();
-        Camera2Focuser focuser = new Camera2Focuser(mCamera, mPreviewSurface, afListener,
+        Camera2Focuser focuser = new Camera2Focuser(mCamera, mSession, mPreviewSurface, afListener,
                 mStaticInfo.getCharacteristics(), mHandler);
         ArrayList<MeteringRectangle[]> testAfRegions = get3ARegionTestCasesForCamera();
 
@@ -609,7 +610,7 @@
                         mCamera.createCaptureRequest(CameraDevice.TEMPLATE_STILL_CAPTURE);
                 prepareStillCaptureAndStartPreview(previewRequest, stillRequest, previewSz,
                         stillSz, resultListener, imageListener);
-                mCamera.capture(stillRequest.build(), resultListener, mHandler);
+                mSession.capture(stillRequest.build(), resultListener, mHandler);
                 Image image = imageListener.getImage(CAPTURE_IMAGE_TIMEOUT_MS);
                 validateJpegCapture(image, stillSz);
                 // stopPreview must be called here to make sure next time a preview stream
@@ -641,7 +642,7 @@
                     resultListener, imageListener);
 
             CaptureRequest rawRequest = rawBuilder.build();
-            mCamera.capture(rawRequest, resultListener, mHandler);
+            mSession.capture(rawRequest, resultListener, mHandler);
 
             Image image = imageListener.getImage(CAPTURE_IMAGE_TIMEOUT_MS);
             validateRaw16Image(image, size);
@@ -696,7 +697,9 @@
                 outputSurfaces.add(rawReader.getSurface());
                 outputSurfaces.add(jpegReader.getSurface());
                 outputSurfaces.add(mPreviewSurface);
-                configureCameraOutputs(mCamera, outputSurfaces, mCameraListener);
+                mSessionListener = new BlockingSessionListener();
+                mSession = configureCameraSession(mCamera, outputSurfaces,
+                        mSessionListener, mHandler);
 
                 // Configure the requests.
                 previewBuilder.addTarget(mPreviewSurface);
@@ -705,7 +708,7 @@
                 multiBuilder.addTarget(jpegReader.getSurface());
 
                 // Start preview.
-                mCamera.setRepeatingRequest(previewBuilder.build(), null, mHandler);
+                mSession.setRepeatingRequest(previewBuilder.build(), null, mHandler);
 
                 // Poor man's 3A, wait 2 seconds for AE/AF (if any) to settle.
                 // TODO: Do proper 3A trigger and lock (see testTakePictureTest).
@@ -715,7 +718,7 @@
                         CaptureRequest.STATISTICS_LENS_SHADING_MAP_MODE_ON);
                 CaptureRequest multiRequest = multiBuilder.build();
 
-                mCamera.capture(multiRequest, resultListener, mHandler);
+                mSession.capture(multiRequest, resultListener, mHandler);
 
                 CaptureResult result = resultListener.getCaptureResultForRequest(multiRequest,
                         NUM_RESULTS_WAIT_TIMEOUT);
@@ -838,7 +841,7 @@
 
             // Capture a jpeg image.
             CaptureRequest request = stillBuilder.build();
-            mCamera.capture(request, resultListener, mHandler);
+            mSession.capture(request, resultListener, mHandler);
             CaptureResult stillResult =
                     resultListener.getCaptureResultForRequest(request, NUM_RESULTS_WAIT_TIMEOUT);
             Image image = imageListener.getImage(CAPTURE_IMAGE_TIMEOUT_MS);
@@ -1166,7 +1169,7 @@
             previewRequest.set(CaptureRequest.CONTROL_AE_EXPOSURE_COMPENSATION,
                     exposureCompensation);
             previewRequest.set(CaptureRequest.CONTROL_AE_LOCK, true);
-            mCamera.setRepeatingRequest(previewRequest.build(), resultListener, mHandler);
+            mSession.setRepeatingRequest(previewRequest.build(), resultListener, mHandler);
             waitForAeLocked(resultListener, NUM_FRAMES_WAITED_FOR_UNKNOWN_LATENCY);
 
             // Issue still capture
@@ -1177,7 +1180,7 @@
 
             stillRequest.set(CaptureRequest.CONTROL_AE_EXPOSURE_COMPENSATION, exposureCompensation);
             CaptureRequest request = stillRequest.build();
-            mCamera.capture(request, resultListener, mHandler);
+            mSession.capture(request, resultListener, mHandler);
 
             result = resultListener.getCaptureResultForRequest(request, WAIT_FOR_RESULT_TIMEOUT_MS);
 
@@ -1210,7 +1213,7 @@
             // Recover AE compensation and lock
             previewRequest.set(CaptureRequest.CONTROL_AE_EXPOSURE_COMPENSATION, 0);
             previewRequest.set(CaptureRequest.CONTROL_AE_LOCK, false);
-            mCamera.setRepeatingRequest(previewRequest.build(), resultListener, mHandler);
+            mSession.setRepeatingRequest(previewRequest.build(), resultListener, mHandler);
         }
     }
 
diff --git a/tests/tests/hardware/src/android/hardware/camera2/cts/SurfaceViewPreviewTest.java b/tests/tests/hardware/src/android/hardware/camera2/cts/SurfaceViewPreviewTest.java
index 11f3620..6dd7c1e 100644
--- a/tests/tests/hardware/src/android/hardware/camera2/cts/SurfaceViewPreviewTest.java
+++ b/tests/tests/hardware/src/android/hardware/camera2/cts/SurfaceViewPreviewTest.java
@@ -18,8 +18,9 @@
 
 import static android.hardware.camera2.cts.CameraTestUtils.*;
 
+import android.hardware.camera2.CameraCaptureSession;
+import android.hardware.camera2.CameraCaptureSession.CaptureListener;
 import android.hardware.camera2.CameraDevice;
-import android.hardware.camera2.CameraDevice.CaptureListener;
 import android.hardware.camera2.CaptureFailure;
 import android.hardware.camera2.CaptureRequest;
 import android.hardware.camera2.CaptureResult;
@@ -149,7 +150,7 @@
             }
 
             resultListener = new SimpleCaptureListener();
-            mCamera.setRepeatingRequest(requestBuilder.build(), resultListener, mHandler);
+            mSession.setRepeatingRequest(requestBuilder.build(), resultListener, mHandler);
 
             verifyPreviewTargetFpsRange(resultListener, NUM_FRAMES_VERIFIED, fpsRange,
                     maxPreviewSz);
@@ -206,10 +207,10 @@
             CaptureRequest.Builder requestBuilder =
                     mCamera.createCaptureRequest(CameraDevice.TEMPLATE_PREVIEW);
             CaptureListener mockCaptureListener =
-                    mock(CameraDevice.CaptureListener.class);
+                    mock(CameraCaptureSession.CaptureListener.class);
 
             startPreview(requestBuilder, sz, mockCaptureListener);
-            verifyCaptureResults(mCamera, mockCaptureListener, NUM_FRAMES_VERIFIED,
+            verifyCaptureResults(mSession, mockCaptureListener, NUM_FRAMES_VERIFIED,
                     NUM_FRAMES_VERIFIED * FRAME_TIMEOUT_MS);
             stopPreview();
         }
@@ -232,9 +233,9 @@
                 // Assign color pattern to SENSOR_TEST_PATTERN_MODE_DATA
                 requestBuilder.set(CaptureRequest.SENSOR_TEST_PATTERN_DATA, TEST_PATTERN_DATA);
             }
-            mockCaptureListener = mock(CameraDevice.CaptureListener.class);
+            mockCaptureListener = mock(CaptureListener.class);
             startPreview(requestBuilder, maxPreviewSize, mockCaptureListener);
-            verifyCaptureResults(mCamera, mockCaptureListener, NUM_TEST_PATTERN_FRAMES_VERIFIED,
+            verifyCaptureResults(mSession, mockCaptureListener, NUM_TEST_PATTERN_FRAMES_VERIFIED,
                     NUM_TEST_PATTERN_FRAMES_VERIFIED * FRAME_TIMEOUT_MS);
         }
 
@@ -254,8 +255,8 @@
     }
 
     private void verifyCaptureResults(
-            CameraDevice camera,
-            CameraDevice.CaptureListener mockListener,
+            CameraCaptureSession session,
+            CaptureListener mockListener,
             int expectResultCount,
             int timeOutMs) {
         // Should receive expected number of onCaptureStarted callbacks.
@@ -263,7 +264,7 @@
         verify(mockListener,
                 timeout(timeOutMs).atLeast(expectResultCount))
                         .onCaptureStarted(
-                                eq(camera),
+                                eq(session),
                                 isA(CaptureRequest.class),
                                 timestamps.capture());
 
@@ -279,14 +280,14 @@
         verify(mockListener,
                 timeout(timeOutMs).atLeast(expectResultCount))
                         .onCaptureCompleted(
-                                eq(camera),
+                                eq(session),
                                 isA(CaptureRequest.class),
                                 argThat(new IsCaptureResultValid()));
 
         // Should not receive any capture failed callbacks.
         verify(mockListener, never())
                         .onCaptureFailed(
-                                eq(camera),
+                                eq(session),
                                 isA(CaptureRequest.class),
                                 isA(CaptureFailure.class));
     }
diff --git a/tests/tests/hardware/src/android/hardware/camera2/cts/helpers/Camera2Focuser.java b/tests/tests/hardware/src/android/hardware/camera2/cts/helpers/Camera2Focuser.java
index ce9f88d..c03caca 100644
--- a/tests/tests/hardware/src/android/hardware/camera2/cts/helpers/Camera2Focuser.java
+++ b/tests/tests/hardware/src/android/hardware/camera2/cts/helpers/Camera2Focuser.java
@@ -18,9 +18,10 @@
 
 import android.graphics.Rect;
 import android.hardware.camera2.CameraAccessException;
+import android.hardware.camera2.CameraCaptureSession;
+import android.hardware.camera2.CameraCaptureSession.CaptureListener;
 import android.hardware.camera2.CameraCharacteristics;
 import android.hardware.camera2.CameraDevice;
-import android.hardware.camera2.CameraDevice.CaptureListener;
 import android.hardware.camera2.params.MeteringRectangle;
 import android.hardware.camera2.CaptureRequest;
 import android.hardware.camera2.CaptureResult;
@@ -50,6 +51,7 @@
     private final Handler mHandler;
     private final AutoFocusListener mAutoFocusListener;
     private final CameraDevice mCamera;
+    private final CameraCaptureSession mSession;
     private final Surface mRequestSurface;
     private final StaticMetadata mStaticInfo;
 
@@ -81,17 +83,22 @@
      * </p>
      *
      * @param camera The camera device associated with this focuser
+     * @param session The camera capture session associated with this focuser
      * @param requestSurface The surface to issue the capture request with
      * @param listener The auto focus listener to notify AF result
      * @param staticInfo The CameraCharacteristics of the camera device
      * @param handler The handler used to post auto focus callbacks
      * @throws CameraAccessException
      */
-    public Camera2Focuser(CameraDevice camera, Surface requestSurface, AutoFocusListener listener,
-            CameraCharacteristics staticInfo, Handler handler) throws CameraAccessException {
+    public Camera2Focuser(CameraDevice camera, CameraCaptureSession session, Surface requestSurface,
+            AutoFocusListener listener, CameraCharacteristics staticInfo, Handler handler)
+            throws CameraAccessException {
         if (camera == null) {
             throw new IllegalArgumentException("camera must not be null");
         }
+        if (session == null) {
+            throw new IllegalArgumentException("session must not be null");
+        }
         if (listener == null) {
             throw new IllegalArgumentException("listener must not be null");
         }
@@ -106,6 +113,7 @@
         }
 
         mCamera = camera;
+        mSession = session;
         mRequestSurface = requestSurface;
         mAutoFocusListener = listener;
         mStaticInfo = new StaticMetadata(staticInfo,
@@ -208,8 +216,8 @@
         mAutoFocus.setPassiveAutoFocus(/*picture*/true, mRepeatingBuilder);
         mAutoFocus.unlockAutoFocus(mRepeatingBuilder, requestBuilder);
         CaptureListener listener = createCaptureListener();
-        mCamera.setRepeatingRequest(mRepeatingBuilder.build(), listener, mHandler);
-        mCamera.capture(requestBuilder.build(), listener, mHandler);
+        mSession.setRepeatingRequest(mRepeatingBuilder.build(), listener, mHandler);
+        mSession.capture(requestBuilder.build(), listener, mHandler);
     }
 
     /**
@@ -245,8 +253,8 @@
             } else if (mSuccess) {
                 mAutoFocus.lockAutoFocus(mRepeatingBuilder, requestBuilder);
                 CaptureListener listener = createCaptureListener();
-                mCamera.setRepeatingRequest(mRepeatingBuilder.build(), listener, mHandler);
-                mCamera.capture(requestBuilder.build(), listener, mHandler);
+                mSession.setRepeatingRequest(mRepeatingBuilder.build(), listener, mHandler);
+                mSession.capture(requestBuilder.build(), listener, mHandler);
             } else {
                 startAutoFocusFullActiveLocked();
             }
@@ -269,8 +277,8 @@
         mAutoFocus.resetState();
 
         CaptureListener listener = createCaptureListener();
-        mCamera.setRepeatingRequest(mRepeatingBuilder.build(), listener, mHandler);
-        mCamera.capture(requestBuilder.build(), listener, mHandler);
+        mSession.setRepeatingRequest(mRepeatingBuilder.build(), listener, mHandler);
+        mSession.capture(requestBuilder.build(), listener, mHandler);
     }
 
     private void dispatchAutoFocusStatusLocked(final boolean success) {
@@ -337,7 +345,7 @@
             private long mLatestFrameCount = -1;
 
             @Override
-            public void onCaptureProgressed(CameraDevice camera, CaptureRequest request,
+            public void onCaptureProgressed(CameraCaptureSession session, CaptureRequest request,
                     CaptureResult result) {
                 // In case of a partial result, send to focuser if necessary
                 // 3A fields are present
@@ -352,7 +360,7 @@
             }
 
             @Override
-            public void onCaptureCompleted(CameraDevice camera, CaptureRequest request,
+            public void onCaptureCompleted(CameraCaptureSession session, CaptureRequest request,
                     TotalCaptureResult result) {
                     dispatchToFocuser(result);
             }
diff --git a/tests/tests/hardware/src/android/hardware/camera2/cts/testcases/Camera2AndroidTestCase.java b/tests/tests/hardware/src/android/hardware/camera2/cts/testcases/Camera2AndroidTestCase.java
index 9210d56..56f0dba 100644
--- a/tests/tests/hardware/src/android/hardware/camera2/cts/testcases/Camera2AndroidTestCase.java
+++ b/tests/tests/hardware/src/android/hardware/camera2/cts/testcases/Camera2AndroidTestCase.java
@@ -21,8 +21,8 @@
 
 import android.content.Context;
 import android.hardware.camera2.CameraCaptureSession;
+import android.hardware.camera2.CameraCaptureSession.CaptureListener;
 import android.hardware.camera2.CameraDevice;
-import android.hardware.camera2.CameraDevice.CaptureListener;
 import android.hardware.camera2.CameraManager;
 import android.hardware.camera2.CaptureRequest;
 import android.util.Size;
@@ -39,6 +39,7 @@
 import android.util.Log;
 import android.view.Surface;
 
+import com.android.ex.camera2.blocking.BlockingSessionListener;
 import com.android.ex.camera2.blocking.BlockingStateListener;
 
 import java.util.List;
@@ -55,6 +56,8 @@
 
     protected CameraManager mCameraManager;
     protected CameraDevice mCamera;
+    protected CameraCaptureSession mCameraSession;
+    protected BlockingSessionListener mCameraSessionListener;
     protected BlockingStateListener mCameraListener;
     protected String[] mCameraIds;
     protected ImageReader mReader;
@@ -128,9 +131,9 @@
         if (VERBOSE) Log.v(TAG, "Starting capture from device");
 
         if (repeating) {
-            mCamera.setRepeatingRequest(request, listener, handler);
+            mCameraSession.setRepeatingRequest(request, listener, handler);
         } else {
-            mCamera.capture(request, listener, handler);
+            mCameraSession.capture(request, listener, handler);
         }
     }
 
@@ -148,10 +151,11 @@
              * Flush is useful for canceling long exposure single capture, it also could help
              * to make the streaming capture stop sooner.
              */
-            mCamera.flush();
-            mCameraListener.waitForState(STATE_IDLE, CAMERA_IDLE_TIMEOUT_MS);
+            mCameraSession.abortCaptures();
+            mCameraSessionListener.getStateWaiter().
+                    waitForState(BlockingSessionListener.SESSION_READY, CAMERA_IDLE_TIMEOUT_MS);
         } else {
-            configureCameraOutputs(mCamera, /*outputSurfaces*/null, mCameraListener);
+            mCameraSession.close();
         }
     }
 
@@ -188,6 +192,17 @@
     }
 
     /**
+     * Create a {@link #CameraCaptureSession} using the currently open camera.
+     *
+     * @param outputSurfaces The set of output surfaces to configure for this session
+     */
+    protected void createSession(List<Surface> outputSurfaces) throws Exception {
+        mCameraSessionListener = new BlockingSessionListener();
+        mCameraSession = CameraTestUtils.configureCameraSession(mCamera, outputSurfaces,
+                mCameraSessionListener, mHandler);
+    }
+
+    /**
      * Close a {@link #CameraDevice camera device} and clear the associated StaticInfo field for a
      * given camera id. The default mCameraListener is used to wait for states.
      * <p>
@@ -220,6 +235,8 @@
             mCamera.close();
             listener.waitForState(STATE_CLOSED, CAMERA_CLOSE_TIMEOUT_MS);
             mCamera = null;
+            mCameraSession = null;
+            mCameraSessionListener = null;
             mStaticInfo = null;
             mOrderedPreviewSizes = null;
             mOrderedVideoSizes = null;
diff --git a/tests/tests/hardware/src/android/hardware/camera2/cts/testcases/Camera2SurfaceViewTestCase.java b/tests/tests/hardware/src/android/hardware/camera2/cts/testcases/Camera2SurfaceViewTestCase.java
index ac0b4da..3fa7b58 100644
--- a/tests/tests/hardware/src/android/hardware/camera2/cts/testcases/Camera2SurfaceViewTestCase.java
+++ b/tests/tests/hardware/src/android/hardware/camera2/cts/testcases/Camera2SurfaceViewTestCase.java
@@ -32,6 +32,8 @@
 import android.content.Context;
 import android.graphics.ImageFormat;
 import android.hardware.camera2.CameraAccessException;
+import android.hardware.camera2.CameraCaptureSession;
+import android.hardware.camera2.CameraCaptureSession.CaptureListener;
 import android.hardware.camera2.CameraDevice;
 import android.hardware.camera2.CameraManager;
 import android.hardware.camera2.CameraMetadata;
@@ -39,7 +41,6 @@
 import android.hardware.camera2.CaptureResult;
 import android.util.Size;
 import android.util.Range;
-import android.hardware.camera2.CameraDevice.CaptureListener;
 import android.hardware.camera2.cts.Camera2SurfaceViewStubActivity;
 import android.hardware.camera2.cts.CameraTestUtils;
 import android.hardware.camera2.cts.CameraTestUtils.SimpleCaptureListener;
@@ -47,6 +48,7 @@
 import android.hardware.camera2.cts.helpers.StaticMetadata;
 import android.hardware.camera2.cts.helpers.StaticMetadata.CheckLevel;
 
+import com.android.ex.camera2.blocking.BlockingSessionListener;
 import com.android.ex.camera2.blocking.BlockingStateListener;
 import com.android.ex.camera2.exceptions.TimeoutRuntimeException;
 
@@ -84,10 +86,12 @@
     protected HandlerThread mHandlerThread;
     protected Handler mHandler;
     protected BlockingStateListener mCameraListener;
+    protected BlockingSessionListener mSessionListener;
     protected CameraErrorCollector mCollector;
     // Per device fields:
     protected StaticMetadata mStaticInfo;
     protected CameraDevice mCamera;
+    protected CameraCaptureSession mSession;
     protected ImageReader mReader;
     protected Surface mReaderSurface;
     protected Surface mPreviewSurface;
@@ -169,7 +173,7 @@
 
         configurePreviewOutput(request);
 
-        mCamera.setRepeatingRequest(request.build(), listener, mHandler);
+        mSession.setRepeatingRequest(request.build(), listener, mHandler);
     }
 
     /**
@@ -181,7 +185,8 @@
             throws CameraAccessException {
         List<Surface> outputSurfaces = new ArrayList<Surface>(/*capacity*/1);
         outputSurfaces.add(mPreviewSurface);
-        configureCameraOutputs(mCamera, outputSurfaces, mCameraListener);
+        mSessionListener = new BlockingSessionListener();
+        mSession = configureCameraSession(mCamera, outputSurfaces, mSessionListener, mHandler);
 
         request.addTarget(mPreviewSurface);
     }
@@ -210,7 +215,7 @@
     protected void stopPreview() throws Exception {
         if (VERBOSE) Log.v(TAG, "Stopping preview and waiting for idle");
         // Stop repeat, wait for captures to complete, and disconnect from surfaces
-        configureCameraOutputs(mCamera, /*outputSurfaces*/null, mCameraListener);
+        mSession.close();
     }
 
     /**
@@ -409,7 +414,7 @@
         int numCaptures = maxLatency + count;
 
         for (int i = 0; i < numCaptures; ++i) {
-            mCamera.capture(request, listener, handler);
+            mSession.capture(request, listener, handler);
         }
 
         return numCaptures;
@@ -570,6 +575,8 @@
             mCamera.close();
             mCameraListener.waitForState(STATE_CLOSED, CAMERA_CLOSE_TIMEOUT_MS);
             mCamera = null;
+            mSession = null;
+            mSessionListener = null;
             mStaticInfo = null;
             mOrderedPreviewSizes = null;
             mOrderedVideoSizes = null;
@@ -634,7 +641,8 @@
         List<Surface> outputSurfaces = new ArrayList<Surface>();
         outputSurfaces.add(mPreviewSurface);
         outputSurfaces.add(mReaderSurface);
-        configureCameraOutputs(mCamera, outputSurfaces, mCameraListener);
+        mSessionListener = new BlockingSessionListener();
+        mSession = configureCameraSession(mCamera, outputSurfaces, mSessionListener, mHandler);
 
         // Configure the requests.
         previewRequest.addTarget(mPreviewSurface);
@@ -642,7 +650,7 @@
         stillRequest.addTarget(mReaderSurface);
 
         // Start preview.
-        mCamera.setRepeatingRequest(previewRequest.build(), resultListener, mHandler);
+        mSession.setRepeatingRequest(previewRequest.build(), resultListener, mHandler);
     }
 
     /**
diff --git a/tests/tests/hardware/src/android/hardware/cts/SingleSensorTests.java b/tests/tests/hardware/src/android/hardware/cts/SingleSensorTests.java
index cd6adb1..d33a108 100644
--- a/tests/tests/hardware/src/android/hardware/cts/SingleSensorTests.java
+++ b/tests/tests/hardware/src/android/hardware/cts/SingleSensorTests.java
@@ -89,6 +89,7 @@
     private static final int BATCHING_OFF = 0;
     private static final int BATCHING_5S = 5000000;
 
+    private static final int RATE_200HZ = 5000;
     private static final int RATE_100HZ = 10000;
     private static final int RATE_50HZ = 20000;
     private static final int RATE_25HZ = 40000;
@@ -144,6 +145,10 @@
         runSensorTest(Sensor.TYPE_ACCELEROMETER, RATE_100HZ, BATCHING_OFF);
     }
 
+    public void testAccelerometer_200hz() throws Throwable {
+        runSensorTest(Sensor.TYPE_ACCELEROMETER, RATE_200HZ, BATCHING_OFF);
+    }
+
     public void testAccelerometer_50hz() throws Throwable {
         runSensorTest(Sensor.TYPE_ACCELEROMETER, RATE_50HZ, BATCHING_OFF);
     }
@@ -180,6 +185,10 @@
         runSensorTest(Sensor.TYPE_MAGNETIC_FIELD, SensorManager.SENSOR_DELAY_FASTEST, BATCHING_OFF);
     }
 
+    public void testMagneticField_200hz() throws Throwable {
+        runSensorTest(Sensor.TYPE_MAGNETIC_FIELD, RATE_200HZ, BATCHING_OFF);
+    }
+
     public void testMagneticField_100hz() throws Throwable {
         runSensorTest(Sensor.TYPE_MAGNETIC_FIELD, RATE_100HZ, BATCHING_OFF);
     }
@@ -222,6 +231,10 @@
     }
 
     @SuppressWarnings("deprecation")
+    public void testOrientation_200hz() throws Throwable {
+        runSensorTest(Sensor.TYPE_ORIENTATION, RATE_200HZ, BATCHING_OFF);
+    }
+    @SuppressWarnings("deprecation")
     public void testOrientation_100hz() throws Throwable {
         runSensorTest(Sensor.TYPE_ORIENTATION, RATE_100HZ, BATCHING_OFF);
     }
@@ -270,6 +283,10 @@
         runSensorTest(Sensor.TYPE_GYROSCOPE, SensorManager.SENSOR_DELAY_FASTEST, BATCHING_OFF);
     }
 
+    public void testGyroscope_200hz() throws Throwable {
+        runSensorTest(Sensor.TYPE_GYROSCOPE, RATE_200HZ, BATCHING_OFF);
+    }
+
     public void testGyroscope_100hz() throws Throwable {
         runSensorTest(Sensor.TYPE_GYROSCOPE, RATE_100HZ, BATCHING_OFF);
     }
@@ -310,6 +327,10 @@
         runSensorTest(Sensor.TYPE_PRESSURE, SensorManager.SENSOR_DELAY_FASTEST, BATCHING_OFF);
     }
 
+    public void testPressure_200hz() throws Throwable {
+        runSensorTest(Sensor.TYPE_PRESSURE, RATE_200HZ, BATCHING_OFF);
+    }
+
     public void testPressure_100hz() throws Throwable {
         runSensorTest(Sensor.TYPE_PRESSURE, RATE_100HZ, BATCHING_OFF);
     }
@@ -350,6 +371,10 @@
         runSensorTest(Sensor.TYPE_GRAVITY, SensorManager.SENSOR_DELAY_FASTEST, BATCHING_OFF);
     }
 
+    public void testGravity_200hz() throws Throwable {
+        runSensorTest(Sensor.TYPE_GRAVITY, RATE_200HZ, BATCHING_OFF);
+    }
+
     public void testGravity_100hz() throws Throwable {
         runSensorTest(Sensor.TYPE_GRAVITY, RATE_100HZ, BATCHING_OFF);
     }
@@ -390,6 +415,11 @@
         runSensorTest(Sensor.TYPE_ROTATION_VECTOR, SensorManager.SENSOR_DELAY_FASTEST,
                 BATCHING_OFF);
     }
+
+    public void testRotationVector_200hz() throws Throwable {
+        runSensorTest(Sensor.TYPE_ROTATION_VECTOR, RATE_200HZ, BATCHING_OFF);
+    }
+
     public void testRotationVector_100hz() throws Throwable {
         runSensorTest(Sensor.TYPE_ROTATION_VECTOR, RATE_100HZ, BATCHING_OFF);
     }
@@ -431,6 +461,10 @@
                 BATCHING_OFF);
     }
 
+    public void testMagneticFieldUncalibrated_200hz() throws Throwable {
+        runSensorTest(Sensor.TYPE_MAGNETIC_FIELD_UNCALIBRATED, RATE_200HZ, BATCHING_OFF);
+    }
+
     public void testMagneticFieldUncalibrated_100hz() throws Throwable {
         runSensorTest(Sensor.TYPE_MAGNETIC_FIELD_UNCALIBRATED, RATE_100HZ, BATCHING_OFF);
     }
@@ -473,6 +507,10 @@
                 BATCHING_OFF);
     }
 
+    public void testGameRotationVector_200hz() throws Throwable {
+        runSensorTest(Sensor.TYPE_GAME_ROTATION_VECTOR, RATE_200HZ, BATCHING_OFF);
+    }
+
     public void testGameRotationVector_100hz() throws Throwable {
         runSensorTest(Sensor.TYPE_GAME_ROTATION_VECTOR, RATE_100HZ, BATCHING_OFF);
     }
@@ -515,6 +553,10 @@
                 BATCHING_OFF);
     }
 
+    public void testGyroscopeUncalibrated_200hz() throws Throwable {
+        runSensorTest(Sensor.TYPE_GYROSCOPE_UNCALIBRATED, RATE_200HZ, BATCHING_OFF);
+    }
+
     public void testGyroscopeUncalibrated_100hz() throws Throwable {
         runSensorTest(Sensor.TYPE_GYROSCOPE_UNCALIBRATED, RATE_100HZ, BATCHING_OFF);
     }
@@ -557,41 +599,45 @@
                 BATCHING_OFF);
     }
 
-    public void  testGeomagneticRotationVector_100hz() throws Throwable {
-        runSensorTest(Sensor.TYPE_GEOMAGNETIC_ROTATION_VECTOR, RATE_100HZ, BATCHING_OFF);
+    public void  testLinearAcceleration_200hz() throws Throwable {
+        runSensorTest(Sensor.TYPE_LINEAR_ACCELERATION, RATE_200HZ, BATCHING_OFF);
     }
 
-    public void testGeomagneticRotationVector_50hz() throws Throwable {
-        runSensorTest(Sensor.TYPE_GEOMAGNETIC_ROTATION_VECTOR, RATE_50HZ, BATCHING_OFF);
+    public void  testLinearAcceleration_100hz() throws Throwable {
+        runSensorTest(Sensor.TYPE_LINEAR_ACCELERATION, RATE_100HZ, BATCHING_OFF);
     }
 
-    public void testGeomagneticRotationVector_25hz() throws Throwable {
-        runSensorTest(Sensor.TYPE_GEOMAGNETIC_ROTATION_VECTOR, RATE_25HZ, BATCHING_OFF);
+    public void testLinearAcceleration_50hz() throws Throwable {
+        runSensorTest(Sensor.TYPE_LINEAR_ACCELERATION, RATE_50HZ, BATCHING_OFF);
     }
 
-    public void testGeomagneticRotationVector_15hz() throws Throwable {
-        runSensorTest(Sensor.TYPE_GEOMAGNETIC_ROTATION_VECTOR, RATE_15HZ, BATCHING_OFF);
+    public void testLinearAcceleration_25hz() throws Throwable {
+        runSensorTest(Sensor.TYPE_LINEAR_ACCELERATION, RATE_25HZ, BATCHING_OFF);
     }
 
-    public void testGeomagneticRotationVector_10hz() throws Throwable {
-        runSensorTest(Sensor.TYPE_GEOMAGNETIC_ROTATION_VECTOR, RATE_10HZ, BATCHING_OFF);
+    public void testLinearAcceleration_15hz() throws Throwable {
+        runSensorTest(Sensor.TYPE_LINEAR_ACCELERATION, RATE_15HZ, BATCHING_OFF);
     }
 
-    public void testGeomagneticRotationVector_5hz() throws Throwable {
-        runSensorTest(Sensor.TYPE_GEOMAGNETIC_ROTATION_VECTOR, RATE_5HZ, BATCHING_OFF);
+    public void testLinearAcceleration_10hz() throws Throwable {
+        runSensorTest(Sensor.TYPE_LINEAR_ACCELERATION, RATE_10HZ, BATCHING_OFF);
     }
 
-    public void testGeomagneticRotationVector_1hz() throws Throwable {
-        runSensorTest(Sensor.TYPE_GEOMAGNETIC_ROTATION_VECTOR, RATE_1HZ, BATCHING_OFF);
+    public void testLinearAcceleration_5hz() throws Throwable {
+        runSensorTest(Sensor.TYPE_LINEAR_ACCELERATION, RATE_5HZ, BATCHING_OFF);
     }
 
-    public void testGeomagneticRotationVector_fastest_batching() throws Throwable {
-        runSensorTest(Sensor.TYPE_GEOMAGNETIC_ROTATION_VECTOR, SensorManager.SENSOR_DELAY_FASTEST,
+    public void testLinearAcceleration_1hz() throws Throwable {
+        runSensorTest(Sensor.TYPE_LINEAR_ACCELERATION, RATE_1HZ, BATCHING_OFF);
+    }
+
+    public void testLinearAcceleration_fastest_batching() throws Throwable {
+        runSensorTest(Sensor.TYPE_LINEAR_ACCELERATION, SensorManager.SENSOR_DELAY_FASTEST,
                 BATCHING_5S);
     }
 
-    public void testGeomagneticRotationVector_50hz_batching() throws Throwable {
-        runSensorTest(Sensor.TYPE_GEOMAGNETIC_ROTATION_VECTOR, RATE_50HZ, BATCHING_5S);
+    public void testLinearAcceleration_50hz_batching() throws Throwable {
+        runSensorTest(Sensor.TYPE_LINEAR_ACCELERATION, RATE_50HZ, BATCHING_5S);
     }
 
     private void runSensorTest(int sensorType, int rateUs, int maxBatchReportLatencyUs)
diff --git a/tests/tests/hardware/src/android/hardware/cts/helpers/sensorverification/FrequencyVerification.java b/tests/tests/hardware/src/android/hardware/cts/helpers/sensorverification/FrequencyVerification.java
index 4815688..b6704b6 100644
--- a/tests/tests/hardware/src/android/hardware/cts/helpers/sensorverification/FrequencyVerification.java
+++ b/tests/tests/hardware/src/android/hardware/cts/helpers/sensorverification/FrequencyVerification.java
@@ -22,6 +22,7 @@
 import android.hardware.cts.helpers.SensorTestInformation;
 import android.hardware.cts.helpers.SensorTestInformation.SensorReportingMode;
 import android.hardware.cts.helpers.TestSensorEvent;
+import android.util.Log;
 
 import junit.framework.Assert;
 
@@ -33,15 +34,17 @@
  */
 public class FrequencyVerification extends AbstractSensorVerification {
     public static final String PASSED_KEY = "frequency_passed";
+    private static final String LOG_TAG = FrequencyVerification.class.getSimpleName();
 
-    // lower threshold is (100 - 10)% expected
-    private static final int DEFAULT_LOWER_THRESHOLD = 10;
-    // upper threshold is (100 + 110)% expected
-    private static final int DEFAULT_UPPER_THRESHOLD = 110;
+    // Lowest acceptable frequency, as percentage of the requested one.
+    private static final int DEFAULT_LOWER_THRESHOLD = 90;
+    // Highest acceptable frequency, as percentage of the requested one.
+    private static final int DEFAULT_UPPER_THRESHOLD = 220;
 
-    private final double mExpected;
-    private final double mLowerThreshold;
-    private final double mUpperThreshold;
+    private final double mRequestedFrequencyHz;
+    private final double mLowerThresholdHz;
+    private final double mUpperThresholdHz;
+    private final String mSensorName;
 
     private long mMinTimestamp = 0;
     private long mMaxTimestamp = 0;
@@ -51,15 +54,15 @@
      * Construct a {@link FrequencyVerification}.
      *
      * @param expected the expected frequency in Hz.
-     * @param lowerTheshold the lower threshold in Hz. {@code expected - lower} should be the
-     * slowest acceptable frequency of the sensor.
-     * @param upperThreshold the upper threshold in Hz. {@code expected + upper} should be the
-     * fastest acceptable frequency of the sensor.
+     * @param lowerTheshold Lowest acceptable frequency Hz.
+     * @param upperThreshold Highest acceptable frequency Hz.
      */
-    public FrequencyVerification(double expected, double lowerTheshold, double upperThreshold) {
-        mExpected = expected;
-        mLowerThreshold = lowerTheshold;
-        mUpperThreshold = upperThreshold;
+    public FrequencyVerification(double expected, double lowerTheshold, double upperThreshold,
+        String sensorName) {
+        mRequestedFrequencyHz = expected;
+        mLowerThresholdHz = lowerTheshold;
+        mUpperThresholdHz = upperThreshold;
+        mSensorName = sensorName;
     }
 
     /**
@@ -75,13 +78,38 @@
             return null;
         }
 
-        // Expected frequency in Hz
-        double expected = SensorCtsHelper.getFrequency(SensorCtsHelper.getDelay(sensor, rateUs),
-                TimeUnit.MICROSECONDS);
-        // Expected frequency * threshold percentage
-        double lowerThreshold = expected * DEFAULT_LOWER_THRESHOLD / 100;
-        double upperThreshold = expected * DEFAULT_UPPER_THRESHOLD / 100;
-        return new FrequencyVerification(expected, lowerThreshold, upperThreshold);
+        Log.i(LOG_TAG, String.format("Preparing frequency test for \"%s\" for which "
+                + "minDelay=%dus and maxDelay=%dus",
+                sensor.getName(), sensor.getMinDelay(), sensor.getMaxDelay()));
+        double maxDelayUs = sensor.getMaxDelay();
+        if (maxDelayUs <= 0) {
+            // This sensor didn't report its maxDelay.
+            // It might be only capable of producing its max rate.
+            // Do as if it reported its minDelay as its maxDelay.
+            Log.w(LOG_TAG, "This sensor (" + sensor.getName() + ") didn't report its maxDelay."
+                    + "Please update it in the sensor HAL to avoid failures in coming "
+                    + "android releases.");
+            maxDelayUs = sensor.getMinDelay();
+        }
+
+        // Convert the rateUs parameter into a delay in microseconds and rate in Hz.
+        double delayUs = SensorCtsHelper.getDelay(sensor, rateUs);
+        double requestedFrequencyHz = SensorCtsHelper.getFrequency(
+            delayUs, TimeUnit.MICROSECONDS);
+
+        // When rateUs > maxDelay, the sensor can do as if we requested maxDelay.
+        double upperExpectedHz = SensorCtsHelper.getFrequency(
+                Math.min(delayUs, maxDelayUs), TimeUnit.MICROSECONDS);
+        // When rateUs < minDelay, the sensor can do as if we requested minDelay
+        double lowerExpectedHz = SensorCtsHelper.getFrequency(
+                Math.max(delayUs, sensor.getMinDelay()), TimeUnit.MICROSECONDS);
+
+        // Set the pass thresholds based on default multipliers.
+        double lowerThresholdHz = lowerExpectedHz * DEFAULT_LOWER_THRESHOLD / 100;
+        double upperThresholdHz = upperExpectedHz * DEFAULT_UPPER_THRESHOLD / 100;
+
+        return new FrequencyVerification(requestedFrequencyHz, lowerThresholdHz, upperThresholdHz,
+            sensor.getName());
     }
 
     /**
@@ -97,18 +125,22 @@
             return;
         }
 
-        double frequency = SensorCtsHelper.getFrequency(
+        double measuredFrequencyHz = SensorCtsHelper.getFrequency(
                 ((double) (mMaxTimestamp - mMinTimestamp)) / (mCount - 1), TimeUnit.NANOSECONDS);
-        boolean failed = (frequency <= mExpected - mLowerThreshold
-                || frequency >= mExpected + mUpperThreshold);
+        boolean failed = (measuredFrequencyHz <= mLowerThresholdHz
+                || measuredFrequencyHz >= mUpperThresholdHz);
 
-        stats.addValue(SensorStats.FREQUENCY_KEY, frequency);
+        stats.addValue(SensorStats.FREQUENCY_KEY, measuredFrequencyHz);
         stats.addValue(PASSED_KEY, !failed);
+        String resultString = String.format("Requested \"" + mSensorName + "\" at %.2fHz "
+                + "(expecting between %.2fHz and %.2fHz, measured %.2fHz)",
+                mRequestedFrequencyHz, mLowerThresholdHz, mUpperThresholdHz, measuredFrequencyHz);
 
         if (failed) {
-            Assert.fail(String.format("Frequency out of range: frequency=%.2fHz "
-                    + "(expected (%.2f-%.2fHz, %.2f+%.2fHz))", frequency, mExpected,
-                    mLowerThreshold, mExpected, mUpperThreshold));
+            Log.e(LOG_TAG, "Frequency test FAIL: " + resultString);
+            Assert.fail(String.format("Frequency out of range: " + resultString));
+        } else {
+            Log.i(LOG_TAG, "Frequency test pass: " + resultString);
         }
     }
 
@@ -117,7 +149,8 @@
      */
     @Override
     public FrequencyVerification clone() {
-        return new FrequencyVerification(mExpected, mLowerThreshold, mUpperThreshold);
+        return new FrequencyVerification(mRequestedFrequencyHz, mLowerThresholdHz,
+            mUpperThresholdHz, mSensorName);
     }
 
     /**
diff --git a/tests/tests/hardware/src/android/hardware/cts/helpers/sensorverification/FrequencyVerificationTest.java b/tests/tests/hardware/src/android/hardware/cts/helpers/sensorverification/FrequencyVerificationTest.java
index cec09a5..82d93e5 100644
--- a/tests/tests/hardware/src/android/hardware/cts/helpers/sensorverification/FrequencyVerificationTest.java
+++ b/tests/tests/hardware/src/android/hardware/cts/helpers/sensorverification/FrequencyVerificationTest.java
@@ -33,22 +33,22 @@
         long[] timestamps = {0, 1000000, 2000000, 3000000, 4000000};  // 1000Hz
 
         SensorStats stats = new SensorStats();
-        ISensorVerification verification = getVerification(1000.0, 1.0, 1.0, timestamps);
+        ISensorVerification verification = getVerification(1000.0, 999.0, 1001.0, timestamps);
         verification.verify(stats);
         verifyStats(stats, true, 1000.0);
 
         stats = new SensorStats();
-        verification = getVerification(950.0, 100.0, 100.0, timestamps);
+        verification = getVerification(950.0, 850.0, 1050.0, timestamps);
         verification.verify(stats);
         verifyStats(stats, true, 1000.0);
 
         stats = new SensorStats();
-        verification = getVerification(1050.0, 100.0, 100.0, timestamps);
+        verification = getVerification(1050.0, 950.0, 1150.0, timestamps);
         verification.verify(stats);
         verifyStats(stats, true, 1000.0);
 
         stats = new SensorStats();
-        verification = getVerification(950.0, 100.0, 25.0, timestamps);
+        verification = getVerification(950.0, 850.0, 975.0, timestamps);
         try {
             verification.verify(stats);
             fail("Expected an AssertionError");
@@ -58,7 +58,7 @@
         verifyStats(stats, false, 1000.0);
 
         stats = new SensorStats();
-        verification = getVerification(1050.0, 25.0, 100.0, timestamps);
+        verification = getVerification(1050.0, 1025.0, 1150.0, timestamps);
         try {
             verification.verify(stats);
             fail("Expected an AssertionError");
@@ -71,7 +71,7 @@
     private ISensorVerification getVerification(double expected, double lowerThreshold,
             double upperThreshold, long ... timestamps) {
         ISensorVerification verification = new FrequencyVerification(expected, lowerThreshold,
-                upperThreshold);
+                upperThreshold, "Test sensor");
         for (long timestamp : timestamps) {
             verification.addSensorEvent(new TestSensorEvent(null, timestamp, 0, null));
         }
diff --git a/tests/tests/view/src/android/view/cts/ViewTest.java b/tests/tests/view/src/android/view/cts/ViewTest.java
index 55bef14..ce16b79 100644
--- a/tests/tests/view/src/android/view/cts/ViewTest.java
+++ b/tests/tests/view/src/android/view/cts/ViewTest.java
@@ -21,12 +21,11 @@
 import android.graphics.Color;
 import android.graphics.ColorFilter;
 import android.graphics.PorterDuff;
-import android.view.LayoutInflater;
+
 import com.android.cts.stub.R;
 import com.android.internal.view.menu.ContextMenuBuilder;
 import com.google.android.collect.Lists;
 
-import android.app.Activity;
 import android.content.Context;
 import android.content.res.Resources;
 import android.content.res.XmlResourceParser;
@@ -60,7 +59,6 @@
 import android.view.SoundEffectConstants;
 import android.view.TouchDelegate;
 import android.view.View;
-import android.view.MotionEvent.PointerProperties;
 import android.view.View.BaseSavedState;
 import android.view.View.OnClickListener;
 import android.view.View.OnCreateContextMenuListener;
@@ -3348,7 +3346,7 @@
         View inflatedView = mActivity.findViewById(R.id.background_tint);
 
         assertEquals("Background tint inflated correctly",
-                Color.WHITE, inflatedView.getBackgroundTint().getDefaultColor());
+                Color.WHITE, inflatedView.getBackgroundTintList().getDefaultColor());
         assertEquals("Background tint mode inflated correctly",
                 PorterDuff.Mode.SRC_OVER, inflatedView.getBackgroundTintMode());
 
@@ -3358,14 +3356,14 @@
         view.setBackground(bg);
         assertFalse("No background tint applied by default", bg.hasCalledSetTint());
 
-        view.setBackgroundTint(ColorStateList.valueOf(Color.WHITE));
-        assertTrue("Background tint applied when setBackgroundTint() called after setBackground()",
+        view.setBackgroundTints(ColorStateList.valueOf(Color.WHITE));
+        assertTrue("Background tint applied when setBackgroundTints() called after setBackground()",
                 bg.hasCalledSetTint());
 
         bg.reset();
         view.setBackground(null);
         view.setBackground(bg);
-        assertTrue("Background tint applied when setBackgroundTint() called before setBackground()",
+        assertTrue("Background tint applied when setBackgroundTints() called before setBackground()",
                 bg.hasCalledSetTint());
     }
 
@@ -3387,8 +3385,8 @@
         }
 
         @Override
-        public void setTint(ColorStateList tint, PorterDuff.Mode tintMode) {
-            super.setTint(tint, tintMode);
+        public void setTints(ColorStateList tint) {
+            super.setTints(tint);
             mCalledSetTint = true;
         }
 
diff --git a/tests/tests/widget/src/android/widget/cts/AbsSeekBarTest.java b/tests/tests/widget/src/android/widget/cts/AbsSeekBarTest.java
index 96ebbc7..72c074a 100644
--- a/tests/tests/widget/src/android/widget/cts/AbsSeekBarTest.java
+++ b/tests/tests/widget/src/android/widget/cts/AbsSeekBarTest.java
@@ -20,7 +20,7 @@
 import android.graphics.Color;
 import android.graphics.PorterDuff;
 import android.test.UiThreadTest;
-import android.view.View;
+
 import com.android.cts.stub.R;
 
 
@@ -34,7 +34,6 @@
 import android.test.ActivityInstrumentationTestCase2;
 import android.util.AttributeSet;
 import android.view.KeyEvent;
-import android.view.MotionEvent;
 import android.widget.AbsSeekBar;
 import android.widget.SeekBar;
 
@@ -219,7 +218,7 @@
         SeekBar inflatedView = (SeekBar) mActivity.findViewById(R.id.thumb_tint);
 
         assertEquals("Thumb tint inflated correctly",
-                Color.WHITE, inflatedView.getThumbTint().getDefaultColor());
+                Color.WHITE, inflatedView.getThumbTintList().getDefaultColor());
         assertEquals("Thumb tint mode inflated correctly",
                 PorterDuff.Mode.SRC_OVER, inflatedView.getThumbTintMode());
 
@@ -229,14 +228,14 @@
         view.setThumb(thumb);
         assertFalse("No thumb tint applied by default", thumb.hasCalledSetTint());
 
-        view.setThumbTint(ColorStateList.valueOf(Color.WHITE));
-        assertTrue("Thumb tint applied when setThumbTint() called after setThumb()",
+        view.setThumbTintList(ColorStateList.valueOf(Color.WHITE));
+        assertTrue("Thumb tint applied when setThumbTintList() called after setThumb()",
                 thumb.hasCalledSetTint());
 
         thumb.reset();
         view.setThumb(null);
         view.setThumb(thumb);
-        assertTrue("Thumb tint applied when setThumbTint() called before setThumb()",
+        assertTrue("Thumb tint applied when setThumbTintList() called before setThumb()",
                 thumb.hasCalledSetTint());
     }
 
@@ -307,8 +306,8 @@
         public void setColorFilter(ColorFilter cf) { }
 
         @Override
-        public void setTint(ColorStateList tint, PorterDuff.Mode tintMode) {
-            super.setTint(tint, tintMode);
+        public void setTints(ColorStateList tint) {
+            super.setTints(tint);
             mCalledSetTint = true;
         }
 
diff --git a/tests/tests/widget/src/android/widget/cts/CompoundButtonTest.java b/tests/tests/widget/src/android/widget/cts/CompoundButtonTest.java
index 06ec535..bc04fc2 100644
--- a/tests/tests/widget/src/android/widget/cts/CompoundButtonTest.java
+++ b/tests/tests/widget/src/android/widget/cts/CompoundButtonTest.java
@@ -21,7 +21,6 @@
 import android.graphics.ColorFilter;
 import android.graphics.PorterDuff;
 import android.view.LayoutInflater;
-import android.widget.SeekBar;
 import android.widget.ToggleButton;
 import com.android.cts.stub.R;
 
@@ -334,7 +333,7 @@
         CompoundButton inflatedView = (CompoundButton) layout.findViewById(R.id.button_tint);
 
         assertEquals("Button tint inflated correctly",
-                Color.WHITE, inflatedView.getButtonTint().getDefaultColor());
+                Color.WHITE, inflatedView.getButtonTintList().getDefaultColor());
         assertEquals("Button tint mode inflated correctly",
                 PorterDuff.Mode.SRC_OVER, inflatedView.getButtonTintMode());
 
@@ -344,14 +343,14 @@
         view.setButtonDrawable(button);
         assertFalse("No button tint applied by default", button.hasCalledSetTint());
 
-        view.setButtonTint(ColorStateList.valueOf(Color.WHITE));
-        assertTrue("Button tint applied when setButtonTint() called after setButton()",
+        view.setButtonTintList(ColorStateList.valueOf(Color.WHITE));
+        assertTrue("Button tint applied when setButtonTintList() called after setButton()",
                 button.hasCalledSetTint());
 
         button.reset();
         view.setButtonDrawable(null);
         view.setButtonDrawable(button);
-        assertTrue("Button tint applied when setButtonTint() called before setButton()",
+        assertTrue("Button tint applied when setButtonTintList() called before setButton()",
                 button.hasCalledSetTint());
     }
 
@@ -368,8 +367,8 @@
         public void setColorFilter(ColorFilter cf) {}
 
         @Override
-        public void setTint(ColorStateList tint, PorterDuff.Mode tintMode) {
-            super.setTint(tint, tintMode);
+        public void setTints(ColorStateList tint) {
+            super.setTints(tint);
             mCalledSetTint = true;
         }
 
diff --git a/tests/tests/widget/src/android/widget/cts/FrameLayoutTest.java b/tests/tests/widget/src/android/widget/cts/FrameLayoutTest.java
index d5a2dea..a78f693 100644
--- a/tests/tests/widget/src/android/widget/cts/FrameLayoutTest.java
+++ b/tests/tests/widget/src/android/widget/cts/FrameLayoutTest.java
@@ -21,7 +21,7 @@
 import android.graphics.Color;
 import android.graphics.ColorFilter;
 import android.graphics.PorterDuff;
-import android.widget.SeekBar;
+
 import com.android.cts.stub.R;
 
 import org.xmlpull.v1.XmlPullParser;
@@ -278,7 +278,7 @@
         FrameLayout inflatedView = (FrameLayout) mActivity.findViewById(R.id.foreground_tint);
 
         assertEquals("Foreground tint inflated correctly",
-                Color.WHITE, inflatedView.getForegroundTint().getDefaultColor());
+                Color.WHITE, inflatedView.getForegroundTintList().getDefaultColor());
         assertEquals("Foreground tint mode inflated correctly",
                 PorterDuff.Mode.SRC_OVER, inflatedView.getForegroundTintMode());
 
@@ -288,14 +288,14 @@
         view.setForeground(foreground);
         assertFalse("No foreground tint applied by default", foreground.hasCalledSetTint());
 
-        view.setForegroundTint(ColorStateList.valueOf(Color.WHITE));
-        assertTrue("Foreground tint applied when setForegroundTint() called after setForeground()",
+        view.setForegroundTintList(ColorStateList.valueOf(Color.WHITE));
+        assertTrue("Foreground tint applied when setForegroundTintList() called after setForeground()",
                 foreground.hasCalledSetTint());
 
         foreground.reset();
         view.setForeground(null);
         view.setForeground(foreground);
-        assertTrue("Foreground tint applied when setForegroundTint() called before setForeground()",
+        assertTrue("Foreground tint applied when setForegroundTintList() called before setForeground()",
                 foreground.hasCalledSetTint());
     }
 
@@ -329,8 +329,8 @@
         public void setColorFilter(ColorFilter cf) {}
 
         @Override
-        public void setTint(ColorStateList tint, PorterDuff.Mode tintMode) {
-            super.setTint(tint, tintMode);
+        public void setTints(ColorStateList tint) {
+            super.setTints(tint);
             mCalledSetTint = true;
         }
 
diff --git a/tests/tests/widget/src/android/widget/cts/ImageViewTest.java b/tests/tests/widget/src/android/widget/cts/ImageViewTest.java
index c44051a..8f14b31 100644
--- a/tests/tests/widget/src/android/widget/cts/ImageViewTest.java
+++ b/tests/tests/widget/src/android/widget/cts/ImageViewTest.java
@@ -24,7 +24,7 @@
 
 import android.content.res.ColorStateList;
 import android.graphics.Color;
-import android.widget.FrameLayout;
+
 import org.xmlpull.v1.XmlPullParser;
 
 import android.app.Activity;
@@ -444,9 +444,9 @@
         ImageView inflatedView = (ImageView) mActivity.findViewById(R.id.image_tint);
 
         assertEquals("Image tint inflated correctly",
-                Color.WHITE, inflatedView.getTint().getDefaultColor());
+                Color.WHITE, inflatedView.getImageTintList().getDefaultColor());
         assertEquals("Image tint mode inflated correctly",
-                PorterDuff.Mode.SRC_OVER, inflatedView.getTintMode());
+                PorterDuff.Mode.SRC_OVER, inflatedView.getImageTintMode());
 
         MockDrawable image = new MockDrawable();
         ImageView view = new ImageView(mActivity);
@@ -454,14 +454,14 @@
         view.setImageDrawable(image);
         assertFalse("No image tint applied by default", image.hasCalledSetTint());
 
-        view.setTint(ColorStateList.valueOf(Color.WHITE));
-        assertTrue("Image tint applied when setTint() called after set()",
+        view.setImageTintList(ColorStateList.valueOf(Color.WHITE));
+        assertTrue("Image tint applied when setImageTintList() called after set()",
                 image.hasCalledSetTint());
 
         image.reset();
         view.setImageDrawable(null);
         view.setImageDrawable(image);
-        assertTrue("Image tint applied when setTint() called before set()",
+        assertTrue("Image tint applied when setImageTintList() called before set()",
                 image.hasCalledSetTint());
     }
 
@@ -568,8 +568,8 @@
         }
 
         @Override
-        public void setTint(ColorStateList tint, PorterDuff.Mode tintMode) {
-            super.setTint(tint, tintMode);
+        public void setTints(ColorStateList tint) {
+            super.setTints(tint);
             mCalledSetTint = true;
         }
 
diff --git a/tests/tests/widget/src/android/widget/cts/ProgressBarTest.java b/tests/tests/widget/src/android/widget/cts/ProgressBarTest.java
index b5c03ec..cd82aed 100644
--- a/tests/tests/widget/src/android/widget/cts/ProgressBarTest.java
+++ b/tests/tests/widget/src/android/widget/cts/ProgressBarTest.java
@@ -20,8 +20,7 @@
 import android.graphics.Color;
 import android.graphics.PorterDuff;
 import android.view.LayoutInflater;
-import android.widget.CompoundButton;
-import android.widget.ToggleButton;
+
 import com.android.cts.stub.R;
 
 
@@ -331,7 +330,7 @@
                 PorterDuff.Mode.SRC_OVER, inflatedView.getProgressTintMode());
 
         assertEquals("Progress background tint inflated correctly",
-                Color.WHITE, inflatedView.getProgressBackgroundTint().getDefaultColor());
+                Color.WHITE, inflatedView.getProgressBackgroundTintList().getDefaultColor());
         assertEquals("Progress background tint mode inflated correctly",
                 PorterDuff.Mode.SRC_OVER, inflatedView.getProgressBackgroundTintMode());
 
@@ -355,13 +354,13 @@
                 progress.hasCalledSetTint());
 
         view.setProgressTint(ColorStateList.valueOf(Color.WHITE));
-        assertTrue("Progress tint applied when setProgressTint() called after setProgress()",
+        assertTrue("Progress tint applied when setProgressTintList() called after setProgress()",
                 progress.hasCalledSetTint());
 
         progress.reset();
         view.setProgressDrawable(null);
         view.setProgressDrawable(progress);
-        assertTrue("Progress tint applied when setProgressTint() called before setProgress()",
+        assertTrue("Progress tint applied when setProgressTintList() called before setProgress()",
                 progress.hasCalledSetTint());
     }
 
@@ -382,13 +381,13 @@
         assertFalse("No indeterminate tint applied by default", indeterminate.hasCalledSetTint());
 
         view.setIndeterminateTint(ColorStateList.valueOf(Color.WHITE));
-        assertTrue("Indeterminate tint applied when setIndeterminateTint() called after "
+        assertTrue("Indeterminate tint applied when setIndeterminateTintList() called after "
                 + "setIndeterminate()", indeterminate.hasCalledSetTint());
 
         indeterminate.reset();
         view.setIndeterminateDrawable(null);
         view.setIndeterminateDrawable(indeterminate);
-        assertTrue("Indeterminate tint applied when setIndeterminateTint() called before "
+        assertTrue("Indeterminate tint applied when setIndeterminateTintList() called before "
                 + "setIndeterminate()", indeterminate.hasCalledSetTint());
     }
 
@@ -415,8 +414,8 @@
         }
 
         @Override
-        public void setTint(ColorStateList tint, PorterDuff.Mode tintMode) {
-            super.setTint(tint, tintMode);
+        public void setTints(ColorStateList tint) {
+            super.setTints(tint);
             mCalledSetTint = true;
         }
 
diff --git a/tools/tradefed-host/src/com/android/cts/tradefed/result/CtsXmlResultReporter.java b/tools/tradefed-host/src/com/android/cts/tradefed/result/CtsXmlResultReporter.java
index f6e10d0..956f1b1 100644
--- a/tools/tradefed-host/src/com/android/cts/tradefed/result/CtsXmlResultReporter.java
+++ b/tools/tradefed-host/src/com/android/cts/tradefed/result/CtsXmlResultReporter.java
@@ -29,6 +29,7 @@
 import com.android.tradefed.config.Option.Importance;
 import com.android.tradefed.log.LogUtil.CLog;
 import com.android.tradefed.result.ITestInvocationListener;
+import com.android.tradefed.result.ITestSummaryListener;
 import com.android.tradefed.result.InputStreamSource;
 import com.android.tradefed.result.LogDataType;
 import com.android.tradefed.result.LogFileSaver;
@@ -45,6 +46,7 @@
 import java.io.IOException;
 import java.io.InputStream;
 import java.io.OutputStream;
+import java.util.List;
 import java.util.Map;
 import java.util.regex.Matcher;
 import java.util.regex.Pattern;
@@ -56,7 +58,7 @@
  * <p/>
  * Outputs xml in format governed by the cts_result.xsd
  */
-public class CtsXmlResultReporter implements ITestInvocationListener {
+public class CtsXmlResultReporter implements ITestInvocationListener, ITestSummaryListener {
     private static final String LOG_TAG = "CtsXmlResultReporter";
 
     static final String TEST_RESULT_FILE_NAME = "testResult.xml";
@@ -100,6 +102,7 @@
     private ResultReporter mReporter;
     private File mLogDir;
     private String mSuiteName;
+    private String mReferenceUrl;
 
     private static final Pattern mCtsLogPattern = Pattern.compile("(.*)\\+\\+\\+\\+(.*)");
 
@@ -313,7 +316,7 @@
         zipResults(mReportDir);
 
         try {
-            mReporter.reportResult(reportFile);
+            mReporter.reportResult(reportFile, mReferenceUrl);
         } catch (IOException e) {
             CLog.e(e);
         }
@@ -472,4 +475,17 @@
     public TestSummary getSummary() {
         return null;
     }
+
+    /**
+     * {@inheritDoc}
+     */
+     @Override
+     public void putSummary(List<TestSummary> summaries) {
+         // By convention, only store the first summary that we see as the summary URL.
+         if (summaries.isEmpty()) {
+             return;
+         }
+
+         mReferenceUrl = summaries.get(0).getSummary().getString();
+     }
 }
diff --git a/tools/tradefed-host/src/com/android/cts/tradefed/result/ResultReporter.java b/tools/tradefed-host/src/com/android/cts/tradefed/result/ResultReporter.java
index 199cbc5..39969d3 100644
--- a/tools/tradefed-host/src/com/android/cts/tradefed/result/ResultReporter.java
+++ b/tools/tradefed-host/src/com/android/cts/tradefed/result/ResultReporter.java
@@ -21,6 +21,8 @@
 import java.io.IOException;
 import java.io.InputStream;
 
+import javax.annotation.Nullable;
+
 /**
  * Class that sends a HTTP POST multipart/form-data request containing
  * the test result XML.
@@ -37,7 +39,7 @@
         mSuiteName = suiteName;
     }
 
-    public void reportResult(File reportFile) throws IOException {
+    public void reportResult(File reportFile, @Nullable String referenceUrl) throws IOException {
         if (isEmpty(mServerUrl)) {
             return;
         }
@@ -45,16 +47,19 @@
         InputStream input = new FileInputStream(reportFile);
         try {
             byte[] data = IssueReporter.getBytes(input, RESULT_XML_BYTES);
-            new MultipartForm(mServerUrl)
+            MultipartForm multipartForm = new MultipartForm(mServerUrl)
                     .addFormValue("suite", mSuiteName)
-                    .addFormFile("resultXml", "testResult.xml.gz", data)
-                    .submit();
+                    .addFormFile("resultXml", "testResult.xml.gz", data);
+            if (!isEmpty(referenceUrl)) {
+                multipartForm.addFormValue("referenceUrl", referenceUrl);
+            }
+            multipartForm.submit();
         } finally {
             input.close();
         }
     }
 
-    private boolean isEmpty(String value) {
+    private static boolean isEmpty(String value) {
         return value == null || value.trim().isEmpty();
     }
 }
diff --git a/tools/tradefed-host/tests/src/com/android/cts/tradefed/result/CtsXmlResultReporterTest.java b/tools/tradefed-host/tests/src/com/android/cts/tradefed/result/CtsXmlResultReporterTest.java
index 5776568..26cf39c 100644
--- a/tools/tradefed-host/tests/src/com/android/cts/tradefed/result/CtsXmlResultReporterTest.java
+++ b/tools/tradefed-host/tests/src/com/android/cts/tradefed/result/CtsXmlResultReporterTest.java
@@ -21,6 +21,7 @@
 import com.android.ddmlib.testrunner.TestIdentifier;
 import com.android.tradefed.build.IFolderBuildInfo;
 import com.android.tradefed.log.LogUtil.CLog;
+import com.android.tradefed.result.TestSummary;
 import com.android.tradefed.result.XmlResultReporter;
 import com.android.tradefed.util.FileUtil;
 
@@ -32,7 +33,10 @@
 import java.io.File;
 import java.io.IOException;
 import java.io.OutputStream;
+import java.util.Arrays;
+import java.util.ArrayList;
 import java.util.Collections;
+import java.util.List;
 import java.util.Map;
 
 /**
@@ -40,6 +44,8 @@
  */
 public class CtsXmlResultReporterTest extends TestCase {
 
+    private static final List<TestSummary> SUMMARY_LIST =
+            new ArrayList<>(Arrays.asList(new TestSummary("TEST_SUMMARY_URL")));
     private CtsXmlResultReporter mResultReporter;
     private ByteArrayOutputStream mOutputStream;
     private File mReportDir;
@@ -116,6 +122,7 @@
         mResultReporter.testEnded(testId, emptyMap);
         mResultReporter.testRunEnded(3000, emptyMap);
         mResultReporter.invocationEnded(1);
+        mResultReporter.putSummary(SUMMARY_LIST);
         String output =  getOutput();
         CLog.d("Actual output: %s", output);
         System.out.println(output);