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