Camera2: Add flush test
Change-Id: Icf55e22e4b23fbf9fd98d35fa4d65bb5615b17a7
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 0118431..8d2a998 100644
--- a/tests/tests/hardware/src/android/hardware/camera2/cts/CameraDeviceTest.java
+++ b/tests/tests/hardware/src/android/hardware/camera2/cts/CameraDeviceTest.java
@@ -95,7 +95,7 @@
.onDisconnected(
any(CameraDevice.class));
-
+ mCameraListener = mCameraMockListener;
createImageReader(DEFAULT_CAPTURE_SIZE, ImageFormat.YUV_420_888, MAX_NUM_IMAGES,
new ImageDropperListener());
}
@@ -273,19 +273,48 @@
}
public void testCameraDeviceCapture() throws Exception {
- runCaptureTest(false, false);
+ runCaptureTest(/*burst*/false, /*repeating*/false, /*flush*/false);
}
public void testCameraDeviceCaptureBurst() throws Exception {
- runCaptureTest(true, false);
+ runCaptureTest(/*burst*/true, /*repeating*/false, /*flush*/false);
}
public void testCameraDeviceRepeatingRequest() throws Exception {
- runCaptureTest(false, true);
+ runCaptureTest(/*burst*/false, /*repeating*/true, /*flush*/false);
}
public void testCameraDeviceRepeatingBurst() throws Exception {
- runCaptureTest(true, true);
+ runCaptureTest(/*burst*/true, /*repeating*/true, /*flush*/false);
+ }
+
+ /**
+ * Test {@link CameraDevice#flush} 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>
+ */
+ public void testCameraDeviceFlush() throws Exception {
+ runCaptureTest(/*burst*/false, /*repeating*/true, /*flush*/true);
+ runCaptureTest(/*burst*/true, /*repeating*/true, /*flush*/true);
+ /**
+ * TODO: this is only basic test of flush. 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.
+ *
+ * 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
+ * request back quickly.
+ *
+ * 3. Also need check onCaptureSequenceCompleted for repeating burst after flush().
+ */
}
private class IsCameraMetadataNotEmpty<T extends CameraMetadata>
@@ -305,7 +334,17 @@
}
}
- private void runCaptureTest(boolean burst, boolean repeating) throws Exception {
+ /**
+ * 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.
+ */
+ private void runCaptureTest(boolean burst, boolean repeating, boolean flush) throws Exception {
for (int i = 0; i < mCameraIds.length; i++) {
try {
openDevice(mCameraIds[i], mCameraMockListener);
@@ -316,15 +355,15 @@
if (!burst) {
// Test: that a single capture of each template type succeeds.
for (int j = 0; j < mTemplates.length; j++) {
- captureSingleShot(mCameraIds[i], mTemplates[j], repeating);
+ captureSingleShot(mCameraIds[i], mTemplates[j], repeating, flush);
}
}
else {
// Test: burst of zero shots
- captureBurstShot(mCameraIds[i], mTemplates, 0, repeating);
+ captureBurstShot(mCameraIds[i], mTemplates, 0, repeating, flush);
// Test: burst of one shot
- captureBurstShot(mCameraIds[i], mTemplates, 1, repeating);
+ captureBurstShot(mCameraIds[i], mTemplates, 1, repeating, flush);
int[] templates = new int[] {
CameraDevice.TEMPLATE_STILL_CAPTURE,
@@ -335,10 +374,11 @@
};
// Test: burst of 5 shots of the same template type
- captureBurstShot(mCameraIds[i], templates, templates.length, repeating);
+ captureBurstShot(mCameraIds[i], templates, templates.length, repeating, flush);
// Test: burst of 5 shots of different template types
- captureBurstShot(mCameraIds[i], mTemplates, mTemplates.length, repeating);
+ captureBurstShot(
+ mCameraIds[i], mTemplates, mTemplates.length, repeating, flush);
}
verify(mCameraMockListener, never())
.onError(
@@ -354,7 +394,7 @@
private void captureSingleShot(
String id,
int template,
- boolean repeating) throws Exception {
+ boolean repeating, boolean flush) throws Exception {
assertEquals("Bad initial state for preparing to capture",
mLatestState, STATE_IDLE);
@@ -377,7 +417,11 @@
verifyCaptureResults(mockCaptureListener, expectedCaptureResultCount);
if (repeating) {
- mCamera.stopRepeating();
+ if (flush) {
+ mCamera.flush();
+ } else {
+ mCamera.stopRepeating();
+ }
}
waitForState(STATE_IDLE, CAMERA_CONFIGURE_TIMEOUT_MS);
}
@@ -386,7 +430,8 @@
String id,
int[] templates,
int len,
- boolean repeating) throws Exception {
+ boolean repeating,
+ boolean flush) throws Exception {
assertEquals("Bad initial state for preparing to capture",
mLatestState, STATE_IDLE);
@@ -422,7 +467,11 @@
verifyCaptureResults(mockCaptureListener, expectedResultCount);
if (repeating) {
- mCamera.stopRepeating();
+ if (flush) {
+ mCamera.flush();
+ } else {
+ mCamera.stopRepeating();
+ }
}
waitForState(STATE_IDLE, CAMERA_CONFIGURE_TIMEOUT_MS);
}
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 45e5242..bcffdf9 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
@@ -134,7 +134,7 @@
* to make the streaming capture stop sooner.
*/
mCamera.flush();
- mCameraListener.waitForState(STATE_UNCONFIGURED, CAMERA_UNCONFIGURED_TIMEOUT_MS);
+ mCameraListener.waitForState(STATE_IDLE, CAMERA_IDLE_TIMEOUT_MS);
} else {
configureCameraOutputs(mCamera, /*outputSurfaces*/null, mCameraListener);
}