From: Shuzhen Wang Date: Fri, 11 Aug 2017 16:11:23 +0000 (-0700) Subject: Camera2: Legacy: Add onRequestQueueEmpty callback X-Git-Tag: android-x86-8.1-r1~113^2~20^2 X-Git-Url: http://git.osdn.net/view?a=commitdiff_plain;h=234ba3ef752742e2f87094e67896a8bde5709d12;p=android-x86%2Fframeworks-base.git Camera2: Legacy: Add onRequestQueueEmpty callback onRequestQueueEmpty callback needs to be supported for legacy HAL1 devices. Test: Camera CTS Bug: 64483624 Change-Id: I268a1fe7577788c4e4e13dfecd7bb7abe0d82e6c --- diff --git a/core/java/android/hardware/camera2/legacy/CameraDeviceState.java b/core/java/android/hardware/camera2/legacy/CameraDeviceState.java index e48bce193b52..135d92ba6ea7 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); } @@ -218,6 +219,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. * * @param handler handler on which to call the callbacks. diff --git a/core/java/android/hardware/camera2/legacy/LegacyCameraDevice.java b/core/java/android/hardware/camera2/legacy/LegacyCameraDevice.java index 1a0590491523..621ea8455d1e 100644 --- a/core/java/android/hardware/camera2/legacy/LegacyCameraDevice.java +++ b/core/java/android/hardware/camera2/legacy/LegacyCameraDevice.java @@ -223,6 +223,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 8f252a19b48c..407e5e63e6ac 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 da62f5445daa..527e60e4b80d 100644 --- a/core/java/android/hardware/camera2/legacy/RequestThreadManager.java +++ b/core/java/android/hardware/camera2/legacy/RequestThreadManager.java @@ -713,7 +713,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 @@ -748,11 +748,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(); @@ -918,8 +924,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);