From 39c31d49ce38158b7708581df0813b03e32d6eea Mon Sep 17 00:00:00 2001 From: Yin-Chia Yeh Date: Fri, 5 Jun 2015 15:38:48 -0700 Subject: Camera2: Support waitForSurfacePrepared in BlockingSessionCallback Change-Id: I7f6f351092a173fe0b7a567e5240cb5abe8cb2de --- .../camera2/blocking/BlockingSessionCallback.java | 54 +++++++++++++++++++++- 1 file changed, 53 insertions(+), 1 deletion(-) diff --git a/camera2/public/src/com/android/ex/camera2/blocking/BlockingSessionCallback.java b/camera2/public/src/com/android/ex/camera2/blocking/BlockingSessionCallback.java index 0dad0d5..0b4d6c6 100644 --- a/camera2/public/src/com/android/ex/camera2/blocking/BlockingSessionCallback.java +++ b/camera2/public/src/com/android/ex/camera2/blocking/BlockingSessionCallback.java @@ -17,6 +17,7 @@ package com.android.ex.camera2.blocking; import android.hardware.camera2.CameraCaptureSession; import android.os.ConditionVariable; +import android.os.SystemClock; import android.util.Log; import android.view.Surface; @@ -24,8 +25,9 @@ import com.android.ex.camera2.exceptions.TimeoutRuntimeException; import com.android.ex.camera2.utils.StateChangeListener; import com.android.ex.camera2.utils.StateWaiter; +import java.util.List; import java.util.ArrayList; -import java.util.concurrent.ExecutionException; +import java.util.HashMap; import java.util.concurrent.Future; import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeoutException; @@ -80,6 +82,7 @@ public class BlockingSessionCallback extends CameraCaptureSession.StateCallback private final StateWaiter mStateWaiter = new StateWaiter(sStateNames); private final StateChangeListener mStateChangeListener = mStateWaiter.getListener(); + private final HashMap > mPreparedSurfaces = new HashMap<>(); private static final String[] sStateNames = { "SESSION_CONFIGURED", @@ -158,6 +161,9 @@ public class BlockingSessionCallback extends CameraCaptureSession.StateCallback mSessionFuture.setSession(session); if (mProxy != null) mProxy.onClosed(session); mStateChangeListener.onStateChanged(SESSION_CLOSED); + synchronized (mPreparedSurfaces) { + mPreparedSurfaces.remove(session); + } } @Override @@ -195,6 +201,52 @@ public class BlockingSessionCallback extends CameraCaptureSession.StateCallback } // Surface prepared doesn't cause a session state change, so don't trigger the // state change listener + synchronized (mPreparedSurfaces) { + List preparedSurfaces = mPreparedSurfaces.get(session); + if (preparedSurfaces == null) { + preparedSurfaces = new ArrayList(); + } + preparedSurfaces.add(surface); + mPreparedSurfaces.put(session, preparedSurfaces); + mPreparedSurfaces.notifyAll(); + } + } + + /** + * Wait until the designated surface is prepared by the camera capture session. + * + * @param session the input {@link CameraCaptureSession} to wait for + * @param surface the input {@link Surface} to wait for + * @param timeoutMs how many milliseconds to wait for + * + * @throws TimeoutRuntimeException if waiting for more than {@long timeoutMs} + */ + public void waitForSurfacePrepared( + CameraCaptureSession session, Surface surface, long timeoutMs) { + synchronized (mPreparedSurfaces) { + List preparedSurfaces = mPreparedSurfaces.get(session); + if (preparedSurfaces != null && preparedSurfaces.contains(surface)) { + return; + } + try { + long waitTimeRemaining = timeoutMs; + while (waitTimeRemaining > 0) { + long waitStartTime = SystemClock.elapsedRealtime(); + mPreparedSurfaces.wait(timeoutMs); + long waitTime = SystemClock.elapsedRealtime() - waitStartTime; + waitTimeRemaining -= waitTime; + preparedSurfaces = mPreparedSurfaces.get(session); + if (waitTimeRemaining >= 0 && preparedSurfaces != null && + preparedSurfaces.contains(surface)) { + return; + } + } + throw new TimeoutRuntimeException( + "Unable to get Surface prepared in " + timeoutMs + "ms"); + } catch (InterruptedException ie) { + throw new AssertionError(); + } + } } private static class SessionFuture implements Future { -- cgit v1.2.3