diff --git a/core/java/android/hardware/camera2/legacy/CameraDeviceState.java b/core/java/android/hardware/camera2/legacy/CameraDeviceState.java
index e48bce193b52c..135d92ba6ea77 100644
--- a/core/java/android/hardware/camera2/legacy/CameraDeviceState.java
+++ b/core/java/android/hardware/camera2/legacy/CameraDeviceState.java
@@ -76,6 +76,7 @@ public class CameraDeviceState {
void onBusy();
void onCaptureStarted(RequestHolder holder, long timestamp);
void onCaptureResult(CameraMetadataNative result, RequestHolder holder);
+ void onRequestQueueEmpty();
void onRepeatingRequestError(long lastFrameNumber);
}
@@ -217,6 +218,20 @@ public class CameraDeviceState {
});
}
+ /**
+ * Indicate that request queue (non-repeating) becomes empty.
+ *
+ *
Send notification that all non-repeating requests have been sent to camera device.
+ */
+ public synchronized void setRequestQueueEmpty() {
+ mCurrentHandler.post(new Runnable() {
+ @Override
+ public void run() {
+ mCurrentListener.onRequestQueueEmpty();
+ }
+ });
+ }
+
/**
* Set the listener for state transition callbacks.
*
diff --git a/core/java/android/hardware/camera2/legacy/LegacyCameraDevice.java b/core/java/android/hardware/camera2/legacy/LegacyCameraDevice.java
index 1a05904915235..621ea8455d1e9 100644
--- a/core/java/android/hardware/camera2/legacy/LegacyCameraDevice.java
+++ b/core/java/android/hardware/camera2/legacy/LegacyCameraDevice.java
@@ -222,6 +222,25 @@ public class LegacyCameraDevice implements AutoCloseable {
});
}
+ @Override
+ public void onRequestQueueEmpty() {
+ mResultHandler.post(new Runnable() {
+ @Override
+ public void run() {
+ if (DEBUG) {
+ Log.d(TAG, "doing onRequestQueueEmpty callback");
+ }
+ try {
+ mDeviceCallbacks.onRequestQueueEmpty();
+ } catch (RemoteException e) {
+ throw new IllegalStateException(
+ "Received remote exception during onRequestQueueEmpty callback: ",
+ e);
+ }
+ }
+ });
+ }
+
@Override
public void onCaptureResult(final CameraMetadataNative result, final RequestHolder holder) {
final CaptureResultExtras extras = getExtrasFromRequest(holder);
diff --git a/core/java/android/hardware/camera2/legacy/RequestQueue.java b/core/java/android/hardware/camera2/legacy/RequestQueue.java
index 8f252a19b48cc..407e5e63e6ac5 100644
--- a/core/java/android/hardware/camera2/legacy/RequestQueue.java
+++ b/core/java/android/hardware/camera2/legacy/RequestQueue.java
@@ -18,7 +18,6 @@ package android.hardware.camera2.legacy;
import android.hardware.camera2.CaptureRequest;
import android.hardware.camera2.utils.SubmitInfo;
import android.util.Log;
-import android.util.Pair;
import java.util.ArrayDeque;
import java.util.List;
@@ -41,6 +40,28 @@ public class RequestQueue {
private int mCurrentRequestId = 0;
private final List mJpegSurfaceIds;
+ public final class RequestQueueEntry {
+ private final BurstHolder mBurstHolder;
+ private final Long mFrameNumber;
+ private final boolean mQueueEmpty;
+
+ public BurstHolder getBurstHolder() {
+ return mBurstHolder;
+ }
+ public Long getFrameNumber() {
+ return mFrameNumber;
+ }
+ public boolean isQueueEmpty() {
+ return mQueueEmpty;
+ }
+
+ public RequestQueueEntry(BurstHolder burstHolder, Long frameNumber, boolean queueEmpty) {
+ mBurstHolder = burstHolder;
+ mFrameNumber = frameNumber;
+ mQueueEmpty = queueEmpty;
+ }
+ }
+
public RequestQueue(List jpegSurfaceIds) {
mJpegSurfaceIds = jpegSurfaceIds;
}
@@ -50,10 +71,12 @@ public class RequestQueue {
*
* If a repeating burst is returned, it will not be removed.
*
- * @return a pair containing the next burst and the current frame number, or null if none exist.
+ * @return an entry containing the next burst, the current frame number, and flag about whether
+ * request queue becomes empty. Null if no burst exists.
*/
- public synchronized Pair getNext() {
+ public synchronized RequestQueueEntry getNext() {
BurstHolder next = mRequestQueue.poll();
+ boolean queueEmptied = (next != null && mRequestQueue.size() == 0);
if (next == null && mRepeatingRequest != null) {
next = mRepeatingRequest;
mCurrentRepeatingFrameNumber = mCurrentFrameNumber +
@@ -64,7 +87,7 @@ public class RequestQueue {
return null;
}
- Pair ret = new Pair(next, mCurrentFrameNumber);
+ RequestQueueEntry ret = new RequestQueueEntry(next, mCurrentFrameNumber, queueEmptied);
mCurrentFrameNumber += next.getNumberOfRequests();
return ret;
}
diff --git a/core/java/android/hardware/camera2/legacy/RequestThreadManager.java b/core/java/android/hardware/camera2/legacy/RequestThreadManager.java
index e8f34cc0b593e..565a43e933ce8 100644
--- a/core/java/android/hardware/camera2/legacy/RequestThreadManager.java
+++ b/core/java/android/hardware/camera2/legacy/RequestThreadManager.java
@@ -722,7 +722,7 @@ public class RequestThreadManager {
boolean anyRequestOutputAbandoned = false;
// Get the next burst from the request queue.
- Pair nextBurst = mRequestQueue.getNext();
+ RequestQueue.RequestQueueEntry nextBurst = mRequestQueue.getNext();
if (nextBurst == null) {
// If there are no further requests queued, wait for any currently executing
@@ -757,11 +757,17 @@ public class RequestThreadManager {
if (nextBurst != null) {
// Queue another capture if we did not get the last burst.
handler.sendEmptyMessage(MSG_SUBMIT_CAPTURE_REQUEST);
+
+ // Check whether capture queue becomes empty
+ if (nextBurst.isQueueEmpty()) {
+ mDeviceState.setRequestQueueEmpty();
+ }
}
// Complete each request in the burst
+ BurstHolder burstHolder = nextBurst.getBurstHolder();
List requests =
- nextBurst.first.produceRequestHolders(nextBurst.second);
+ burstHolder.produceRequestHolders(nextBurst.getFrameNumber());
for (RequestHolder holder : requests) {
CaptureRequest request = holder.getRequest();
@@ -927,8 +933,8 @@ public class RequestThreadManager {
}
// Stop the repeating request if any of its output surfaces is abandoned.
- if (anyRequestOutputAbandoned && nextBurst.first.isRepeating()) {
- long lastFrameNumber = cancelRepeating(nextBurst.first.getRequestId());
+ if (anyRequestOutputAbandoned && burstHolder.isRepeating()) {
+ long lastFrameNumber = cancelRepeating(burstHolder.getRequestId());
if (DEBUG) {
Log.d(TAG, "Stopped repeating request. Last frame number is " +
lastFrameNumber);