From 3b7da912d573f358fd217f6d9b569cca648efe02 Mon Sep 17 00:00:00 2001
From: Ruben Brunk
Throws {@link BlockingOpenException} when the open fails asynchronously (due to - * {@link CameraDevice.StateListener#onDisconnected(CameraDevice)} or - * ({@link CameraDevice.StateListener#onError(CameraDevice)}.
+ * {@link CameraDevice.StateCallback#onDisconnected(CameraDevice)} or + * ({@link CameraDevice.StateCallback#onError(CameraDevice)}. * *Throws {@link TimeoutRuntimeException} if opening times out. This is usually * highly unrecoverable, and all future calls to opening that camera will fail since the @@ -142,7 +142,7 @@ public class BlockingCameraManager { * @throws TimeoutRuntimeException * If opening times out. Typically unrecoverable. */ - public CameraDevice openCamera(String cameraId, CameraDevice.StateListener listener, + public CameraDevice openCamera(String cameraId, CameraDevice.StateCallback listener, Handler handler) throws CameraAccessException, BlockingOpenException { if (handler == null) { @@ -163,17 +163,17 @@ public class BlockingCameraManager { /** * Block until CameraManager#openCamera finishes with onOpened/onError/onDisconnected * - *
Pass-through all StateListener changes to the proxy.
+ *Pass-through all StateCallback changes to the proxy.
* *Time out after {@link #OPEN_TIME_OUT} and unblock. Clean up camera if it arrives * later.
*/ - private class OpenListener extends CameraDevice.StateListener { + private class OpenListener extends CameraDevice.StateCallback { private static final int ERROR_UNINITIALIZED = -1; private final String mCameraId; - private final CameraDevice.StateListener mProxy; + private final CameraDevice.StateCallback mProxy; private final Object mLock = new Object(); private final ConditionVariable mDeviceReady = new ConditionVariable(); @@ -187,7 +187,7 @@ public class BlockingCameraManager { private boolean mTimedOut = false; OpenListener(CameraManager manager, String cameraId, - CameraDevice.StateListener listener, Handler handler) + CameraDevice.StateCallback listener, Handler handler) throws CameraAccessException { mCameraId = cameraId; mProxy = listener; diff --git a/camera2/public/src/com/android/ex/camera2/blocking/BlockingCaptureCallback.java b/camera2/public/src/com/android/ex/camera2/blocking/BlockingCaptureCallback.java new file mode 100644 index 0000000..4fb2c43 --- /dev/null +++ b/camera2/public/src/com/android/ex/camera2/blocking/BlockingCaptureCallback.java @@ -0,0 +1,164 @@ +/* + * Copyright 2014 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.android.ex.camera2.blocking; + +import android.hardware.camera2.CameraCaptureSession; +import android.hardware.camera2.CaptureFailure; +import android.hardware.camera2.CaptureRequest; +import android.hardware.camera2.CaptureResult; +import android.hardware.camera2.TotalCaptureResult; +import android.util.Log; + +import com.android.ex.camera2.utils.StateChangeListener; +import com.android.ex.camera2.utils.StateWaiter; + +/** + * A camera capture listener that implements blocking operations on state changes for a + * particular capture request. + * + *Provides a waiter that can be used to block until the next unobserved state of the + * requested type arrives.
+ * + *Pass-through all StateListener changes to the proxy.
+ * + * @see #getStateWaiter + */ +public class BlockingCaptureCallback extends CameraCaptureSession.CaptureCallback { + + /** + * {@link #onCaptureStarted} has been called. + */ + public static final int CAPTURE_STARTED = 0; + + /** + * {@link #onCaptureProgressed} has been + * called. + */ + public static final int CAPTURE_PROGRESSED = 1; + + /** + * {@link #onCaptureCompleted} has + * been called. + */ + public static final int CAPTURE_COMPLETED = 2; + + /** + * {@link #onCaptureFailed} has been + * called. + */ + public static final int CAPTURE_FAILED = 3; + + /** + * {@link #onCaptureSequenceCompleted} has been called. + */ + public static final int CAPTURE_SEQUENCE_COMPLETED = 4; + + /** + * {@link #onCaptureSequenceAborted} has been called. + */ + public static final int CAPTURE_SEQUENCE_ABORTED = 5; + + private static final String[] sStateNames = { + "CAPTURE_STARTED", + "CAPTURE_PROGRESSED", + "CAPTURE_COMPLETED", + "CAPTURE_FAILED", + "CAPTURE_SEQUENCE_COMPLETED", + "CAPTURE_SEQUENCE_ABORTED" + }; + + private static final String TAG = "BlockingCaptureCallback"; + private static final boolean VERBOSE = Log.isLoggable(TAG, Log.VERBOSE); + + private final CameraCaptureSession.CaptureCallback mProxy; + + private final StateWaiter mStateWaiter = new StateWaiter(sStateNames); + private final StateChangeListener mStateChangeListener = mStateWaiter.getListener(); + + /** + * Create a blocking capture listener without forwarding the capture listener invocations + * to another capture listener. + */ + public BlockingCaptureCallback() { + mProxy = null; + } + + /** + * Create a blocking capture listener; forward original listener invocations + * into {@code listener}. + * + * @param listener a non-{@code null} listener to forward invocations into + * + * @throws NullPointerException if {@code listener} was {@code null} + */ + public BlockingCaptureCallback(CameraCaptureSession.CaptureCallback listener) { + if (listener == null) { + throw new NullPointerException("listener must not be null"); + } + mProxy = listener; + } + + /** + * Acquire the state waiter; can be used to block until a set of state transitions have + * been reached. + * + *Only one thread should wait at a time.
+ */ + public StateWaiter getStateWaiter() { + return mStateWaiter; + } + + @Override + public void onCaptureStarted(CameraCaptureSession session, CaptureRequest request, + long timestamp) { + if (mProxy != null) mProxy.onCaptureStarted(session, request, timestamp); + mStateChangeListener.onStateChanged(CAPTURE_STARTED); + } + + @Override + public void onCaptureProgressed(CameraCaptureSession session, CaptureRequest request, + CaptureResult partialResult) { + if (mProxy != null) mProxy.onCaptureProgressed(session, request, partialResult); + mStateChangeListener.onStateChanged(CAPTURE_PROGRESSED); + } + + @Override + public void onCaptureCompleted(CameraCaptureSession session, CaptureRequest request, + TotalCaptureResult result) { + if (mProxy != null) mProxy.onCaptureCompleted(session, request, result); + mStateChangeListener.onStateChanged(CAPTURE_COMPLETED); + } + + @Override + public void onCaptureFailed(CameraCaptureSession session, CaptureRequest request, + CaptureFailure failure) { + if (mProxy != null) mProxy.onCaptureFailed(session, request, failure); + mStateChangeListener.onStateChanged(CAPTURE_FAILED); + } + + @Override + public void onCaptureSequenceCompleted(CameraCaptureSession session, int sequenceId, + long frameNumber) { + if (mProxy != null) mProxy.onCaptureSequenceCompleted(session, sequenceId, frameNumber); + mStateChangeListener.onStateChanged(CAPTURE_SEQUENCE_COMPLETED); + } + + @Override + public void onCaptureSequenceAborted(CameraCaptureSession session, int sequenceId) { + if (mProxy != null) mProxy.onCaptureSequenceAborted(session, sequenceId); + mStateChangeListener.onStateChanged(CAPTURE_SEQUENCE_ABORTED); + } +} diff --git a/camera2/public/src/com/android/ex/camera2/blocking/BlockingCaptureListener.java b/camera2/public/src/com/android/ex/camera2/blocking/BlockingCaptureListener.java deleted file mode 100644 index eae85d1..0000000 --- a/camera2/public/src/com/android/ex/camera2/blocking/BlockingCaptureListener.java +++ /dev/null @@ -1,164 +0,0 @@ -/* - * Copyright 2014 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.android.ex.camera2.blocking; - -import android.hardware.camera2.CameraCaptureSession; -import android.hardware.camera2.CaptureFailure; -import android.hardware.camera2.CaptureRequest; -import android.hardware.camera2.CaptureResult; -import android.hardware.camera2.TotalCaptureResult; -import android.util.Log; - -import com.android.ex.camera2.utils.StateChangeListener; -import com.android.ex.camera2.utils.StateWaiter; - -/** - * A camera capture listener that implements blocking operations on state changes for a - * particular capture request. - * - *Provides a waiter that can be used to block until the next unobserved state of the - * requested type arrives.
- * - *Pass-through all StateListener changes to the proxy.
- * - * @see #getStateWaiter - */ -public class BlockingCaptureListener extends CameraCaptureSession.CaptureListener { - - /** - * {@link #onCaptureStarted} has been called. - */ - public static final int CAPTURE_STARTED = 0; - - /** - * {@link #onCaptureProgressed} has been - * called. - */ - public static final int CAPTURE_PROGRESSED = 1; - - /** - * {@link #onCaptureCompleted} has - * been called. - */ - public static final int CAPTURE_COMPLETED = 2; - - /** - * {@link #onCaptureFailed} has been - * called. - */ - public static final int CAPTURE_FAILED = 3; - - /** - * {@link #onCaptureSequenceCompleted} has been called. - */ - public static final int CAPTURE_SEQUENCE_COMPLETED = 4; - - /** - * {@link #onCaptureSequenceAborted} has been called. - */ - public static final int CAPTURE_SEQUENCE_ABORTED = 5; - - private static final String[] sStateNames = { - "CAPTURE_STARTED", - "CAPTURE_PROGRESSED", - "CAPTURE_COMPLETED", - "CAPTURE_FAILED", - "CAPTURE_SEQUENCE_COMPLETED", - "CAPTURE_SEQUENCE_ABORTED" - }; - - private static final String TAG = "BlockingCaptureListener"; - private static final boolean VERBOSE = Log.isLoggable(TAG, Log.VERBOSE); - - private final CameraCaptureSession.CaptureListener mProxy; - - private final StateWaiter mStateWaiter = new StateWaiter(sStateNames); - private final StateChangeListener mStateChangeListener = mStateWaiter.getListener(); - - /** - * Create a blocking capture listener without forwarding the capture listener invocations - * to another capture listener. - */ - public BlockingCaptureListener() { - mProxy = null; - } - - /** - * Create a blocking capture listener; forward original listener invocations - * into {@code listener}. - * - * @param listener a non-{@code null} listener to forward invocations into - * - * @throws NullPointerException if {@code listener} was {@code null} - */ - public BlockingCaptureListener(CameraCaptureSession.CaptureListener listener) { - if (listener == null) { - throw new NullPointerException("listener must not be null"); - } - mProxy = listener; - } - - /** - * Acquire the state waiter; can be used to block until a set of state transitions have - * been reached. - * - *Only one thread should wait at a time.
- */ - public StateWaiter getStateWaiter() { - return mStateWaiter; - } - - @Override - public void onCaptureStarted(CameraCaptureSession session, CaptureRequest request, - long timestamp) { - if (mProxy != null) mProxy.onCaptureStarted(session, request, timestamp); - mStateChangeListener.onStateChanged(CAPTURE_STARTED); - } - - @Override - public void onCaptureProgressed(CameraCaptureSession session, CaptureRequest request, - CaptureResult partialResult) { - if (mProxy != null) mProxy.onCaptureProgressed(session, request, partialResult); - mStateChangeListener.onStateChanged(CAPTURE_PROGRESSED); - } - - @Override - public void onCaptureCompleted(CameraCaptureSession session, CaptureRequest request, - TotalCaptureResult result) { - if (mProxy != null) mProxy.onCaptureCompleted(session, request, result); - mStateChangeListener.onStateChanged(CAPTURE_COMPLETED); - } - - @Override - public void onCaptureFailed(CameraCaptureSession session, CaptureRequest request, - CaptureFailure failure) { - if (mProxy != null) mProxy.onCaptureFailed(session, request, failure); - mStateChangeListener.onStateChanged(CAPTURE_FAILED); - } - - @Override - public void onCaptureSequenceCompleted(CameraCaptureSession session, int sequenceId, - long frameNumber) { - if (mProxy != null) mProxy.onCaptureSequenceCompleted(session, sequenceId, frameNumber); - mStateChangeListener.onStateChanged(CAPTURE_SEQUENCE_COMPLETED); - } - - @Override - public void onCaptureSequenceAborted(CameraCaptureSession session, int sequenceId) { - if (mProxy != null) mProxy.onCaptureSequenceAborted(session, sequenceId); - mStateChangeListener.onStateChanged(CAPTURE_SEQUENCE_ABORTED); - } -} diff --git a/camera2/public/src/com/android/ex/camera2/blocking/BlockingSessionCallback.java b/camera2/public/src/com/android/ex/camera2/blocking/BlockingSessionCallback.java new file mode 100644 index 0000000..e041d27 --- /dev/null +++ b/camera2/public/src/com/android/ex/camera2/blocking/BlockingSessionCallback.java @@ -0,0 +1,228 @@ +/* + * Copyright 2014 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.android.ex.camera2.blocking; + +import android.hardware.camera2.CameraCaptureSession; +import android.os.ConditionVariable; +import android.util.Log; + +import com.android.ex.camera2.exceptions.TimeoutRuntimeException; +import com.android.ex.camera2.utils.StateChangeListener; +import com.android.ex.camera2.utils.StateWaiter; + +import java.util.ArrayList; +import java.util.concurrent.ExecutionException; +import java.util.concurrent.Future; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.TimeoutException; + + +/** + * A camera session listener that implements blocking operations on session state changes. + * + *Provides a waiter that can be used to block until the next unobserved state of the + * requested type arrives.
+ * + *Pass-through all StateCallback changes to the proxy.
+ * + * @see #getStateWaiter + */ +public class BlockingSessionCallback extends CameraCaptureSession.StateCallback { + /** + * Session is configured, ready for captures + */ + public static final int SESSION_CONFIGURED = 0; + + /** + * Session has failed to configure, can't do any captures + */ + public static final int SESSION_CONFIGURE_FAILED = 1; + + /** + * Session is ready + */ + public static final int SESSION_READY = 2; + + /** + * Session is active (transitory) + */ + public static final int SESSION_ACTIVE = 3; + + /** + * Session is closed + */ + public static final int SESSION_CLOSED = 4; + + private final int NUM_STATES = 5; + + /* + * Private fields + */ + private static final String TAG = "BlockingSessionCallback"; + private static final boolean VERBOSE = Log.isLoggable(TAG, Log.VERBOSE); + + private final CameraCaptureSession.StateCallback mProxy; + private final SessionFuture mSessionFuture = new SessionFuture(); + + private final StateWaiter mStateWaiter = new StateWaiter(sStateNames); + private final StateChangeListener mStateChangeListener = mStateWaiter.getListener(); + + private static final String[] sStateNames = { + "SESSION_CONFIGURED", + "SESSION_CONFIGURE_FAILED", + "SESSION_READY", + "SESSION_ACTIVE", + "SESSION_CLOSED" + }; + + /** + * Create a blocking session listener without forwarding the session listener invocations + * to another session listener. + */ + public BlockingSessionCallback() { + mProxy = null; + } + + /** + * Create a blocking session listener; forward original listener invocations + * into {@code listener}. + * + * @param listener a non-{@code null} listener to forward invocations into + * + * @throws NullPointerException if {@code listener} was {@code null} + */ + public BlockingSessionCallback(CameraCaptureSession.StateCallback listener) { + if (listener == null) { + throw new NullPointerException("listener must not be null"); + } + mProxy = listener; + } + + /** + * Acquire the state waiter; can be used to block until a set of state transitions have + * been reached. + * + *Only one thread should wait at a time.
+ */ + public StateWaiter getStateWaiter() { + return mStateWaiter; + } + + /** + * Return session if already have it; otherwise wait until any of the session listener + * invocations fire and the session is available. + * + *Does not consume any of the states from the state waiter.
+ * + * @param timeoutMs how many milliseconds to wait for + * @return a non-{@code null} {@link CameraCaptureSession} instance + * + * @throws TimeoutRuntimeException if waiting for more than {@long timeoutMs} + */ + public CameraCaptureSession waitAndGetSession(long timeoutMs) { + try { + return mSessionFuture.get(timeoutMs, TimeUnit.MILLISECONDS); + } catch (TimeoutException e) { + throw new TimeoutRuntimeException( + String.format("Failed to get session after %s milliseconds", timeoutMs), e); + } + } + + /* + * CameraCaptureSession.StateCallback implementation + */ + + @Override + public void onActive(CameraCaptureSession session) { + mSessionFuture.setSession(session); + if (mProxy != null) mProxy.onActive(session); + mStateChangeListener.onStateChanged(SESSION_ACTIVE); + } + + @Override + public void onClosed(CameraCaptureSession session) { + mSessionFuture.setSession(session); + if (mProxy != null) mProxy.onClosed(session); + mStateChangeListener.onStateChanged(SESSION_CLOSED); + } + + @Override + public void onConfigured(CameraCaptureSession session) { + mSessionFuture.setSession(session); + if (mProxy != null) mProxy.onConfigured(session); + mStateChangeListener.onStateChanged(SESSION_CONFIGURED); + } + + @Override + public void onConfigureFailed(CameraCaptureSession session) { + mSessionFuture.setSession(session); + if (mProxy != null) mProxy.onConfigureFailed(session); + mStateChangeListener.onStateChanged(SESSION_CONFIGURE_FAILED); + } + + @Override + public void onReady(CameraCaptureSession session) { + mSessionFuture.setSession(session); + if (mProxy != null) mProxy.onReady(session); + mStateChangeListener.onStateChanged(SESSION_READY); + } + + private static class SessionFuture implements FutureProvides a waiter that can be used to block until the next unobserved state of the - * requested type arrives.
- * - *Pass-through all StateListener changes to the proxy.
- * - * @see #getStateWaiter - */ -public class BlockingSessionListener extends CameraCaptureSession.StateListener { - /** - * Session is configured, ready for captures - */ - public static final int SESSION_CONFIGURED = 0; - - /** - * Session has failed to configure, can't do any captures - */ - public static final int SESSION_CONFIGURE_FAILED = 1; - - /** - * Session is ready - */ - public static final int SESSION_READY = 2; - - /** - * Session is active (transitory) - */ - public static final int SESSION_ACTIVE = 3; - - /** - * Session is closed - */ - public static final int SESSION_CLOSED = 4; - - private final int NUM_STATES = 5; - - /* - * Private fields - */ - private static final String TAG = "BlockingSessionListener"; - private static final boolean VERBOSE = Log.isLoggable(TAG, Log.VERBOSE); - - private final CameraCaptureSession.StateListener mProxy; - private final SessionFuture mSessionFuture = new SessionFuture(); - - private final StateWaiter mStateWaiter = new StateWaiter(sStateNames); - private final StateChangeListener mStateChangeListener = mStateWaiter.getListener(); - - private static final String[] sStateNames = { - "SESSION_CONFIGURED", - "SESSION_CONFIGURE_FAILED", - "SESSION_READY", - "SESSION_ACTIVE", - "SESSION_CLOSED" - }; - - /** - * Create a blocking session listener without forwarding the session listener invocations - * to another session listener. - */ - public BlockingSessionListener() { - mProxy = null; - } - - /** - * Create a blocking session listener; forward original listener invocations - * into {@code listener}. - * - * @param listener a non-{@code null} listener to forward invocations into - * - * @throws NullPointerException if {@code listener} was {@code null} - */ - public BlockingSessionListener(CameraCaptureSession.StateListener listener) { - if (listener == null) { - throw new NullPointerException("listener must not be null"); - } - mProxy = listener; - } - - /** - * Acquire the state waiter; can be used to block until a set of state transitions have - * been reached. - * - *Only one thread should wait at a time.
- */ - public StateWaiter getStateWaiter() { - return mStateWaiter; - } - - /** - * Return session if already have it; otherwise wait until any of the session listener - * invocations fire and the session is available. - * - *Does not consume any of the states from the state waiter.
- * - * @param timeoutMs how many milliseconds to wait for - * @return a non-{@code null} {@link CameraCaptureSession} instance - * - * @throws TimeoutRuntimeException if waiting for more than {@long timeoutMs} - */ - public CameraCaptureSession waitAndGetSession(long timeoutMs) { - try { - return mSessionFuture.get(timeoutMs, TimeUnit.MILLISECONDS); - } catch (TimeoutException e) { - throw new TimeoutRuntimeException( - String.format("Failed to get session after %s milliseconds", timeoutMs), e); - } - } - - /* - * CameraCaptureSession.StateListener implementation - */ - - @Override - public void onActive(CameraCaptureSession session) { - mSessionFuture.setSession(session); - if (mProxy != null) mProxy.onActive(session); - mStateChangeListener.onStateChanged(SESSION_ACTIVE); - } - - @Override - public void onClosed(CameraCaptureSession session) { - mSessionFuture.setSession(session); - if (mProxy != null) mProxy.onClosed(session); - mStateChangeListener.onStateChanged(SESSION_CLOSED); - } - - @Override - public void onConfigured(CameraCaptureSession session) { - mSessionFuture.setSession(session); - if (mProxy != null) mProxy.onConfigured(session); - mStateChangeListener.onStateChanged(SESSION_CONFIGURED); - } - - @Override - public void onConfigureFailed(CameraCaptureSession session) { - mSessionFuture.setSession(session); - if (mProxy != null) mProxy.onConfigureFailed(session); - mStateChangeListener.onStateChanged(SESSION_CONFIGURE_FAILED); - } - - @Override - public void onReady(CameraCaptureSession session) { - mSessionFuture.setSession(session); - if (mProxy != null) mProxy.onReady(session); - mStateChangeListener.onStateChanged(SESSION_READY); - } - - private static class SessionFuture implements FutureProvides wait calls that block until the next unobserved state of the + * requested type arrives. Unobserved states are states that have occurred since + * the last wait, or that will be received from the camera device in the + * future.
+ * + *Pass-through all StateCallback changes to the proxy.
+ * + */ +public class BlockingStateCallback extends CameraDevice.StateCallback { + private static final String TAG = "BlockingStateCallback"; + private static final boolean VERBOSE = Log.isLoggable(TAG, Log.VERBOSE); + + private final CameraDevice.StateCallback mProxy; + + // Guards mWaiting + private final Object mLock = new Object(); + private boolean mWaiting = false; + + private final LinkedBlockingQueueNote: Only one waiter allowed at a time!
+ * + * @param desired state to observe a transition to + * @param timeout how long to wait in milliseconds + * + * @throws TimeoutRuntimeException if the desired state is not observed before timeout. + */ + public void waitForState(int state, long timeout) { + Integer[] stateArray = { state }; + + waitForAnyOfStates(Arrays.asList(stateArray), timeout); + } + + /** + * Wait until the one of the desired states is observed, checking all + * state transitions since the last state that was waited on. + * + *Note: Only one waiter allowed at a time!
+ * + * @param states Set of desired states to observe a transition to. + * @param timeout how long to wait in milliseconds + * + * @return the state reached + * @throws TimeoutRuntimeException if none of the states is observed before timeout. + * + */ + public int waitForAnyOfStates(CollectionProvides wait calls that block until the next unobserved state of the - * requested type arrives. Unobserved states are states that have occurred since - * the last wait, or that will be received from the camera device in the - * future.
- * - *Pass-through all StateListener changes to the proxy.
- * - */ -public class BlockingStateListener extends CameraDevice.StateListener { - private static final String TAG = "BlockingStateListener"; - private static final boolean VERBOSE = Log.isLoggable(TAG, Log.VERBOSE); - - private final CameraDevice.StateListener mProxy; - - // Guards mWaiting - private final Object mLock = new Object(); - private boolean mWaiting = false; - - private final LinkedBlockingQueueNote: Only one waiter allowed at a time!
- * - * @param desired state to observe a transition to - * @param timeout how long to wait in milliseconds - * - * @throws TimeoutRuntimeException if the desired state is not observed before timeout. - */ - public void waitForState(int state, long timeout) { - Integer[] stateArray = { state }; - - waitForAnyOfStates(Arrays.asList(stateArray), timeout); - } - - /** - * Wait until the one of the desired states is observed, checking all - * state transitions since the last state that was waited on. - * - *Note: Only one waiter allowed at a time!
- * - * @param states Set of desired states to observe a transition to. - * @param timeout how long to wait in milliseconds - * - * @return the state reached - * @throws TimeoutRuntimeException if none of the states is observed before timeout. - * - */ - public int waitForAnyOfStates(CollectionThis function is responsible for dispatching updates via the
* {@link AutoFocusStateListener} so without calling this on a regular basis, no
diff --git a/camera2/utils/src/com/android/ex/camera2/utils/Camera2CaptureCallbackForwarder.java b/camera2/utils/src/com/android/ex/camera2/utils/Camera2CaptureCallbackForwarder.java
new file mode 100644
index 0000000..97b5b6e
--- /dev/null
+++ b/camera2/utils/src/com/android/ex/camera2/utils/Camera2CaptureCallbackForwarder.java
@@ -0,0 +1,99 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.ex.camera2.utils;
+
+import android.hardware.camera2.CameraCaptureSession;
+import android.hardware.camera2.CameraCaptureSession.CaptureCallback;
+import android.hardware.camera2.CaptureFailure;
+import android.hardware.camera2.CaptureRequest;
+import android.hardware.camera2.CaptureResult;
+import android.hardware.camera2.TotalCaptureResult;
+import android.os.Handler;
+
+/**
+ * Proxy that forwards all updates to another {@link CaptureCallback}, invoking
+ * its callbacks on a separate {@link Handler}.
+ */
+public class Camera2CaptureCallbackForwarder extends CaptureCallback {
+ private CaptureCallback mListener;
+ private Handler mHandler;
+
+ public Camera2CaptureCallbackForwarder(CaptureCallback listener, Handler handler) {
+ mListener = listener;
+ mHandler = handler;
+ }
+
+ @Override
+ public void onCaptureCompleted(final CameraCaptureSession session, final CaptureRequest request,
+ final TotalCaptureResult result) {
+ mHandler.post(new Runnable() {
+ @Override
+ public void run() {
+ mListener.onCaptureCompleted(session, request, result);
+ }});
+ }
+
+ @Override
+ public void onCaptureFailed(final CameraCaptureSession session, final CaptureRequest request,
+ final CaptureFailure failure) {
+ mHandler.post(new Runnable() {
+ @Override
+ public void run() {
+ mListener.onCaptureFailed(session, request, failure);
+ }});
+ }
+
+ @Override
+ public void onCaptureProgressed(final CameraCaptureSession session,
+ final CaptureRequest request,
+ final CaptureResult partialResult) {
+ mHandler.post(new Runnable() {
+ @Override
+ public void run() {
+ mListener.onCaptureProgressed(session, request, partialResult);
+ }});
+ }
+
+ @Override
+ public void onCaptureSequenceAborted(final CameraCaptureSession session, final int sequenceId) {
+ mHandler.post(new Runnable() {
+ @Override
+ public void run() {
+ mListener.onCaptureSequenceAborted(session, sequenceId);
+ }});
+ }
+
+ @Override
+ public void onCaptureSequenceCompleted(final CameraCaptureSession session, final int sequenceId,
+ final long frameNumber) {
+ mHandler.post(new Runnable() {
+ @Override
+ public void run() {
+ mListener.onCaptureSequenceCompleted(session, sequenceId, frameNumber);
+ }});
+ }
+
+ @Override
+ public void onCaptureStarted(final CameraCaptureSession session, final CaptureRequest request,
+ final long timestamp) {
+ mHandler.post(new Runnable() {
+ @Override
+ public void run() {
+ mListener.onCaptureStarted(session, request, timestamp);
+ }});
+ }
+}
diff --git a/camera2/utils/src/com/android/ex/camera2/utils/Camera2CaptureCallbackSplitter.java b/camera2/utils/src/com/android/ex/camera2/utils/Camera2CaptureCallbackSplitter.java
new file mode 100644
index 0000000..f813076
--- /dev/null
+++ b/camera2/utils/src/com/android/ex/camera2/utils/Camera2CaptureCallbackSplitter.java
@@ -0,0 +1,95 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.ex.camera2.utils;
+
+import android.hardware.camera2.CameraCaptureSession;
+import android.hardware.camera2.CameraCaptureSession.CaptureCallback;
+import android.hardware.camera2.CaptureFailure;
+import android.hardware.camera2.CaptureRequest;
+import android.hardware.camera2.CaptureResult;
+import android.hardware.camera2.TotalCaptureResult;
+
+import java.util.Arrays;
+import java.util.LinkedList;
+import java.util.List;
+
+/**
+ * Junction that allows notifying multiple {@link CaptureCallback}s whenever
+ * the {@link CameraCaptureSession} posts a capture-related update.
+ */
+public class Camera2CaptureCallbackSplitter extends CaptureCallback {
+ private final List