method public abstract void close() throws java.lang.Exception;
method public abstract void configureOutputs(java.util.List<android.view.Surface>) throws android.hardware.camera2.CameraAccessException;
method public abstract android.hardware.camera2.CaptureRequest createCaptureRequest(int) throws android.hardware.camera2.CameraAccessException;
+ method public abstract void flush() throws android.hardware.camera2.CameraAccessException;
method public abstract android.hardware.camera2.CameraProperties getProperties() throws android.hardware.camera2.CameraAccessException;
method public abstract void setErrorListener(android.hardware.camera2.CameraDevice.ErrorListener);
method public abstract void setRepeatingBurst(java.util.List<android.hardware.camera2.CaptureRequest>, android.hardware.camera2.CameraDevice.CaptureListener) throws android.hardware.camera2.CameraAccessException;
* preview or other continuous stream of frames, without having to submit
* requests through {@link #capture} at video rates.</p>
*
- * <p>To stop the repeating capture, call {@link #stopRepeating}</p>
+ * <p>To stop the repeating capture, call {@link #stopRepeating}. Calling
+ * {@link #flush} will also clear the request.</p>
*
* <p>Calling repeat will replace a burst set up by {@link
* #setRepeatingBurst}, although any in-progress burst will be
* @see #capture
* @see #captureBurst
* @see #setRepeatingBurst
+ * @see #stopRepeating
+ * @see #flush
*/
public void setRepeatingRequest(CaptureRequest request, CaptureListener listener)
throws CameraAccessException;
* requests through {@link #capture} at video rates.</p>
*
* <p>To stop the repeating capture, call {@link #stopRepeating}. Any
- * ongoing burst will still be completed, however.</p>
+ * ongoing burst will still be completed, however. Calling
+ * {@link #flush} will also clear the request.</p>
*
* <p>Calling repeatBurst will replace a repeating request set up by
* {@link #setRepeatingRequest}, although any in-progress capture will be completed
* @see #capture
* @see #captureBurst
* @see #setRepeatingRequest
+ * @see #stopRepeating
+ * @see #flush
*/
public void setRepeatingBurst(List<CaptureRequest> requests, CaptureListener listener)
throws CameraAccessException;
public void setErrorListener(ErrorListener listener);
/**
+ * Flush all captures currently pending and in-progress as fast as
+ * possible.
+ *
+ * <p>The camera device will discard all of its current work as fast as
+ * possible. Some in-flight captures may complete successfully and call
+ * {@link CaptureListener#onCaptureComplete}, while others will trigger
+ * their {@link CaptureListener#onCaptureFailed} callbacks. If a repeating
+ * request or a repeating burst is set, it will be cleared by the flush.</p>
+ *
+ * <p>This method 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>
+ *
+ * <p>Flushing will introduce at least a brief pause in the stream of data
+ * from the camera device, since once the flush is complete, the first new
+ * request has to make it through the entire camera pipeline before new
+ * output buffers are produced.</p>
+ *
+ * <p>This means that using {@code flush()} to simply remove pending
+ * requests is not recommended; it's best used for quickly switching output
+ * configurations, or for cancelling long in-progress requests (such as a
+ * multi-second capture).</p>
+ *
+ * @throws CameraAccessException if the camera device is no longer connected
+ * @see #setRepeatingRequest
+ * @see #setRepeatingBurst
+ * @see #configureOutputs
+ */
+ public void flush() throws CameraAccessException;
+
+ /**
* Close the connection to this camera device. After this call, all calls to
* the camera device interface will throw a {@link IllegalStateException},
* except for calls to close().
argThat(matcher));
request.close();
}
+
+ @SmallTest
+ public void testFlush() throws Exception {
+ int status;
+
+ // Initial flush should work
+ status = mCameraUser.flush();
+ assertEquals(CameraBinderTestUtils.NO_ERROR, status);
+
+ // Then set up a stream
+ CaptureRequest request = createDefaultRequest(/* needStream */true);
+
+ // Flush should still be a no-op, really
+ status = mCameraUser.flush();
+ assertEquals(CameraBinderTestUtils.NO_ERROR, status);
+
+ // Submit a few capture requests
+ int requestId1 = submitCameraRequest(request, /* streaming */false);
+ int requestId2 = submitCameraRequest(request, /* streaming */false);
+ int requestId3 = submitCameraRequest(request, /* streaming */false);
+ int requestId4 = submitCameraRequest(request, /* streaming */false);
+ int requestId5 = submitCameraRequest(request, /* streaming */false);
+
+ // Then flush
+ status = mCameraUser.flush();
+ assertEquals(CameraBinderTestUtils.NO_ERROR, status);
+
+ // TODO: When errors are hooked up, count that errors + successful
+ // requests equal to 5.
+ }
}