/*
* 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.
*
* <p>Provides a waiter that can be used to block until the next unobserved state of the
* requested type arrives.</p>
*
* <p>Pass-through all StateListener changes to the proxy.</p>
*
* @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.
*
* <p>Only one thread should wait at a time.</p>
*/
public StateWaiter getStateWaiter() {
return mStateWaiter;
}
@Override
public void onCaptureStarted(CameraCaptureSession session, CaptureRequest request,
long timestamp, long frameNumber) {
if (mProxy != null) mProxy.onCaptureStarted(session, request, timestamp, frameNumber);
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);
}
}