Camera2 CTS: Remove use of hidden camera2 methods

- Switch to sessions instead of configureOutputs
- Don't wait on device states that are hidden

Change-Id: I581a0a41a8bdaa26a6becf3909be5cfdaf36227b
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 0de810b..3535d5f 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;
     }
 
     /**
@@ -733,7 +739,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) {
@@ -808,14 +814,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) {
@@ -829,9 +835,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 cf70b52..0c054b1 100644
--- a/tests/tests/hardware/src/android/hardware/camera2/cts/CaptureRequestTest.java
+++ b/tests/tests/hardware/src/android/hardware/camera2/cts/CaptureRequestTest.java
@@ -560,7 +560,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,
@@ -591,7 +591,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);
@@ -614,7 +614,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.
@@ -687,7 +687,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,
@@ -742,7 +742,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);
@@ -759,7 +759,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",
@@ -770,7 +770,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",
@@ -827,7 +827,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.
@@ -1060,7 +1060,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);
 
@@ -1129,7 +1129,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);
@@ -1459,7 +1459,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.
@@ -1469,7 +1469,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)) {
@@ -1532,7 +1532,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.
@@ -1574,7 +1574,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);
@@ -1583,7 +1583,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);
@@ -1674,7 +1674,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);
                 }
 
                 /*
@@ -1765,7 +1765,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,
@@ -1788,7 +1788,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,
@@ -2047,7 +2047,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..a44b2551 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..c03cacab9 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);
     }
 
     /**