Home | History | Annotate | Download | only in blocking
      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  */
     16 package com.android.ex.camera2.blocking;
     17 
     18 import android.hardware.camera2.CameraCaptureSession;
     19 import android.hardware.camera2.CaptureFailure;
     20 import android.hardware.camera2.CaptureRequest;
     21 import android.hardware.camera2.CaptureResult;
     22 import android.hardware.camera2.TotalCaptureResult;
     23 import android.util.Log;
     24 
     25 import com.android.ex.camera2.utils.StateChangeListener;
     26 import 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  */
     39 public 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