1/*
2 * Copyright 2014 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *      http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16package com.android.ex.camera2.blocking;
17
18import android.hardware.camera2.CameraCaptureSession;
19import android.hardware.camera2.CaptureFailure;
20import android.hardware.camera2.CaptureRequest;
21import android.hardware.camera2.CaptureResult;
22import android.hardware.camera2.TotalCaptureResult;
23import android.util.Log;
24
25import com.android.ex.camera2.utils.StateChangeListener;
26import com.android.ex.camera2.utils.StateWaiter;
27
28/**
29 * A camera capture listener that implements blocking operations on state changes for a
30 * particular capture request.
31 *
32 * <p>Provides a waiter that can be used to block until the next unobserved state of the
33 * requested type arrives.</p>
34 *
35 * <p>Pass-through all StateListener changes to the proxy.</p>
36 *
37 * @see #getStateWaiter
38 */
39public class BlockingCaptureCallback extends CameraCaptureSession.CaptureCallback {
40
41    /**
42     * {@link #onCaptureStarted} has been called.
43     */
44    public static final int CAPTURE_STARTED = 0;
45
46    /**
47     * {@link #onCaptureProgressed} has been
48     * called.
49     */
50    public static final int CAPTURE_PROGRESSED = 1;
51
52    /**
53     * {@link #onCaptureCompleted} has
54     * been called.
55     */
56    public static final int CAPTURE_COMPLETED = 2;
57
58    /**
59     * {@link #onCaptureFailed} has been
60     * called.
61     */
62    public static final int CAPTURE_FAILED = 3;
63
64    /**
65     * {@link #onCaptureSequenceCompleted} has been called.
66     */
67    public static final int CAPTURE_SEQUENCE_COMPLETED = 4;
68
69    /**
70     * {@link #onCaptureSequenceAborted} has been called.
71     */
72    public static final int CAPTURE_SEQUENCE_ABORTED = 5;
73
74    private static final String[] sStateNames = {
75            "CAPTURE_STARTED",
76            "CAPTURE_PROGRESSED",
77            "CAPTURE_COMPLETED",
78            "CAPTURE_FAILED",
79            "CAPTURE_SEQUENCE_COMPLETED",
80            "CAPTURE_SEQUENCE_ABORTED"
81    };
82
83    private static final String TAG = "BlockingCaptureCallback";
84    private static final boolean VERBOSE = Log.isLoggable(TAG, Log.VERBOSE);
85
86    private final CameraCaptureSession.CaptureCallback mProxy;
87
88    private final StateWaiter mStateWaiter = new StateWaiter(sStateNames);
89    private final StateChangeListener mStateChangeListener = mStateWaiter.getListener();
90
91    /**
92     * Create a blocking capture listener without forwarding the capture listener invocations
93     * to another capture listener.
94     */
95    public BlockingCaptureCallback() {
96        mProxy = null;
97    }
98
99    /**
100     * Create a blocking capture listener; forward original listener invocations
101     * into {@code listener}.
102     *
103     * @param listener a non-{@code null} listener to forward invocations into
104     *
105     * @throws NullPointerException if {@code listener} was {@code null}
106     */
107    public BlockingCaptureCallback(CameraCaptureSession.CaptureCallback listener) {
108        if (listener == null) {
109            throw new NullPointerException("listener must not be null");
110        }
111        mProxy = listener;
112    }
113
114    /**
115     * Acquire the state waiter; can be used to block until a set of state transitions have
116     * been reached.
117     *
118     * <p>Only one thread should wait at a time.</p>
119     */
120    public StateWaiter getStateWaiter() {
121        return mStateWaiter;
122    }
123
124    @Override
125    public void onCaptureStarted(CameraCaptureSession session, CaptureRequest request,
126                                 long timestamp, long frameNumber) {
127        if (mProxy != null) mProxy.onCaptureStarted(session, request, timestamp, frameNumber);
128        mStateChangeListener.onStateChanged(CAPTURE_STARTED);
129    }
130
131    @Override
132    public void onCaptureProgressed(CameraCaptureSession session, CaptureRequest request,
133                                    CaptureResult partialResult) {
134        if (mProxy != null) mProxy.onCaptureProgressed(session, request, partialResult);
135        mStateChangeListener.onStateChanged(CAPTURE_PROGRESSED);
136    }
137
138    @Override
139    public void onCaptureCompleted(CameraCaptureSession session, CaptureRequest request,
140                                   TotalCaptureResult result) {
141        if (mProxy != null) mProxy.onCaptureCompleted(session, request, result);
142        mStateChangeListener.onStateChanged(CAPTURE_COMPLETED);
143    }
144
145    @Override
146    public void onCaptureFailed(CameraCaptureSession session, CaptureRequest request,
147                                CaptureFailure failure) {
148        if (mProxy != null) mProxy.onCaptureFailed(session, request, failure);
149        mStateChangeListener.onStateChanged(CAPTURE_FAILED);
150    }
151
152    @Override
153    public void onCaptureSequenceCompleted(CameraCaptureSession session, int sequenceId,
154                                           long frameNumber) {
155        if (mProxy != null) mProxy.onCaptureSequenceCompleted(session, sequenceId, frameNumber);
156        mStateChangeListener.onStateChanged(CAPTURE_SEQUENCE_COMPLETED);
157    }
158
159    @Override
160    public void onCaptureSequenceAborted(CameraCaptureSession session, int sequenceId) {
161        if (mProxy != null) mProxy.onCaptureSequenceAborted(session, sequenceId);
162        mStateChangeListener.onStateChanged(CAPTURE_SEQUENCE_ABORTED);
163    }
164}
165