• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 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 
17 package android.hardware.camera2;
18 
19 import android.annotation.CallbackExecutor;
20 import android.annotation.NonNull;
21 import android.annotation.Nullable;
22 import android.hardware.camera2.params.OutputConfiguration;
23 import android.os.Handler;
24 import android.view.Surface;
25 
26 import java.util.List;
27 import java.util.concurrent.Executor;
28 
29 /**
30  * A configured capture session for a {@link CameraDevice}, used for capturing images from the
31  * camera or reprocessing images captured from the camera in the same session previously.
32  *
33  * <p>A CameraCaptureSession is created by providing a set of target output surfaces to
34  * {@link CameraDevice#createCaptureSession createCaptureSession}, or by providing an
35  * {@link android.hardware.camera2.params.InputConfiguration} and a set of target output surfaces to
36  * {@link CameraDevice#createReprocessableCaptureSession createReprocessableCaptureSession} for a
37  * reprocessable capture session. Once created, the session is active until a new session is
38  * created by the camera device, or the camera device is closed.</p>
39  *
40  * <p>All capture sessions can be used for capturing images from the camera but only reprocessable
41  * capture sessions can reprocess images captured from the camera in the same session previously.
42  * </p>
43  *
44  * <p>Creating a session is an expensive operation and can take several hundred milliseconds, since
45  * it requires configuring the camera device's internal pipelines and allocating memory buffers for
46  * sending images to the desired targets. Therefore the setup is done asynchronously, and
47  * {@link CameraDevice#createCaptureSession createCaptureSession} and
48  * {@link CameraDevice#createReprocessableCaptureSession createReprocessableCaptureSession} will
49  * send the ready-to-use CameraCaptureSession to the provided listener's
50  * {@link CameraCaptureSession.StateCallback#onConfigured onConfigured} callback. If configuration
51  * cannot be completed, then the
52  * {@link CameraCaptureSession.StateCallback#onConfigureFailed onConfigureFailed} is called, and the
53  * session will not become active.</p>
54  *<!--
55  * <p>Any capture requests (repeating or non-repeating) submitted before the session is ready will
56  * be queued up and will begin capture once the session becomes ready. In case the session cannot be
57  * configured and {@link StateCallback#onConfigureFailed onConfigureFailed} is called, all queued
58  * capture requests are discarded.</p>
59  *-->
60  * <p>If a new session is created by the camera device, then the previous session is closed, and its
61  * associated {@link StateCallback#onClosed onClosed} callback will be invoked.  All
62  * of the session methods will throw an IllegalStateException if called once the session is
63  * closed.</p>
64  *
65  * <p>A closed session clears any repeating requests (as if {@link #stopRepeating} had been called),
66  * but will still complete all of its in-progress capture requests as normal, before a newly
67  * created session takes over and reconfigures the camera device.</p>
68  */
69 public abstract class CameraCaptureSession implements AutoCloseable {
70 
71     /**
72      * Used to identify invalid session ID.
73      * @hide
74      */
75     public static final int SESSION_ID_NONE = -1;
76 
77     /**
78      * Get the camera device that this session is created for.
79      */
80     @NonNull
getDevice()81     public abstract CameraDevice getDevice();
82 
83     /**
84      * <p>Pre-allocate all buffers for an output Surface.</p>
85      *
86      * <p>Normally, the image buffers for a given output Surface are allocated on-demand,
87      * to minimize startup latency and memory overhead.</p>
88      *
89      * <p>However, in some cases, it may be desirable for the buffers to be allocated before
90      * any requests targeting the Surface are actually submitted to the device. Large buffers
91      * may take some time to allocate, which can result in delays in submitting requests until
92      * sufficient buffers are allocated to reach steady-state behavior. Such delays can cause
93      * bursts to take longer than desired, or cause skips or stutters in preview output.</p>
94      *
95      * <p>The prepare() method can be used to perform this preallocation. It may only be called for
96      * a given output Surface before that Surface is used as a target for a request. The number of
97      * buffers allocated is the sum of the count needed by the consumer providing the output
98      * Surface, and the maximum number needed by the camera device to fill its pipeline. Since this
99      * may be a larger number than what is actually required for steady-state operation, using
100      * prepare may result in higher memory consumption than the normal on-demand behavior results
101      * in. Prepare() will also delay the time to first output to a given Surface, in exchange for
102      * smoother frame rate once the allocation is complete.</p>
103      *
104      * <p>For example, an application that creates an
105      * {@link android.media.ImageReader#newInstance ImageReader} with a maxImages argument of 10,
106      * but only uses 3 simultaneous Images at once would normally only cause those 3 images to be
107      * allocated (plus what is needed by the camera device for smooth operation).  But using
108      * prepare() on the ImageReader Surface will result in all 10 Images being allocated. So
109      * applications using this method should take care to request only the number of buffers
110      * actually necessary for their application.</p>
111      *
112      * <p>If the same output Surface is used in consecutive sessions (without closing the first
113      * session explicitly), then its already-allocated buffers are carried over, and if it was
114      * used as a target of a capture request in the first session, prepare cannot be called on it
115      * in the second session.</p>
116      *
117      * <p>Once allocation is complete, {@link StateCallback#onSurfacePrepared} will be invoked with
118      * the Surface provided to this method. Between the prepare call and the onSurfacePrepared call,
119      * the Surface provided to prepare must not be used as a target of a CaptureRequest submitted
120      * to this session.</p>
121      *
122      * <p>Note that if 2 surfaces share the same stream via {@link
123      * OutputConfiguration#enableSurfaceSharing} and {@link OutputConfiguration#addSurface},
124      * prepare() only needs to be called on one surface, and {link
125      * StateCallback#onSurfacePrepared} will be triggered for both surfaces.</p>
126      *
127      * <p>{@link android.hardware.camera2.CameraCharacteristics#INFO_SUPPORTED_HARDWARE_LEVEL_LEGACY LEGACY}
128      * devices cannot pre-allocate output buffers; for those devices,
129      * {@link StateCallback#onSurfacePrepared} will be immediately called, and no preallocation is
130      * done.</p>
131      *
132      * @param surface the output Surface for which buffers should be pre-allocated. Must be one of
133      * the output Surfaces used to create this session.
134      *
135      * @throws CameraAccessException if the camera device is no longer connected or has
136      *                               encountered a fatal error
137      * @throws IllegalStateException if this session is no longer active, either because the session
138      *                               was explicitly closed, a new session has been created
139      *                               or the camera device has been closed.
140      * @throws IllegalArgumentException if the Surface is invalid, not part of this Session, or has
141      *                                  already been used as a target of a CaptureRequest in this
142      *                                  session or immediately prior sessions.
143      *
144      * @see StateCallback#onSurfacePrepared
145      */
prepare(@onNull Surface surface)146     public abstract void prepare(@NonNull Surface surface) throws CameraAccessException;
147 
148     /**
149      * <p>Pre-allocate at most maxCount buffers for an output Surface.</p>
150      *
151      * <p>Like the {@link #prepare(Surface)} method, this method can be used to allocate output
152      * buffers for a given Surface.  However, while the {@link #prepare(Surface)} method allocates
153      * the maximum possible buffer count, this method allocates at most maxCount buffers.</p>
154      *
155      * <p>If maxCount is greater than the possible maximum count (which is the sum of the buffer
156      * count requested by the creator of the Surface and the count requested by the camera device),
157      * only the possible maximum count is allocated, in which case the function acts exactly like
158      * {@link #prepare(Surface)}.</p>
159      *
160      * <p>The restrictions on when this method can be called are the same as for
161      * {@link #prepare(Surface)}.</p>
162      *
163      * <p>Repeated calls to this method are allowed, and a mix of {@link #prepare(Surface)} and
164      * this method is also allowed. Note that after the first call to {@link #prepare(Surface)},
165      * subsequent calls to either prepare method are effectively no-ops.  In addition, this method
166      * is not additive in terms of buffer count.  This means calling it twice with maxCount = 2
167      * will only allocate 2 buffers, not 4 (assuming the possible maximum is at least 2); to
168      * allocate two buffers on the first call and two on the second, the application needs to call
169      * prepare with prepare(surface, 2) and prepare(surface, 4).</p>
170      *
171      * @param maxCount the buffer count to try to allocate. If this is greater than the possible
172      *                 maximum for this output, the possible maximum is allocated instead. If
173      *                 maxCount buffers are already allocated, then prepare will do nothing.
174      * @param surface the output Surface for which buffers should be pre-allocated.
175      *
176      * @throws CameraAccessException if the camera device is no longer connected or has
177      *                               encountered a fatal error.
178      * @throws IllegalStateException if this session is no longer active, either because the
179      *                               session was explicitly closed, a new session has been created
180      *                               or the camera device has been closed.
181      * @throws IllegalArgumentException if the Surface is invalid, not part of this Session,
182      *                                  or has already been used as a target of a CaptureRequest in
183      *                                  this session or immediately prior sessions without an
184      *                                  intervening tearDown call.
185      *
186      * @hide
187      */
prepare(int maxCount, @NonNull Surface surface)188     public abstract void prepare(int maxCount, @NonNull Surface surface)
189             throws CameraAccessException;
190 
191     /**
192      * <p>Free all buffers allocated for an output Surface.</p>
193      *
194      * <p>Normally, once allocated, the image buffers for a given output Surface remain allocated
195      * for the lifetime of the capture session, to minimize latency of captures and to reduce
196      * memory allocation overhead.</p>
197      *
198      * <p>However, in some cases, it may be desirable for allocated buffers to be freed to reduce
199      * the application's memory consumption, if the particular output Surface will not be used by
200      * the application for some time.</p>
201      *
202      * <p>The tearDown() method can be used to perform this operation. After the call finishes, all
203      * unfilled image buffers will have been freed. Any future use of the target Surface may require
204      * allocation of additional buffers, as if the session had just been created.  Buffers being
205      * held by the application (either explicitly as Image objects from ImageReader, or implicitly
206      * as the current texture in a SurfaceTexture or the current contents of a RS Allocation, will
207      * remain valid and allocated even when tearDown is invoked.</p>
208      *
209      * <p>A Surface that has had tearDown() called on it is eligible to have prepare() invoked on it
210      * again even if it was used as a request target before the tearDown() call, as long as it
211      * doesn't get used as a target of a request between the tearDown() and prepare() calls.</p>
212      *
213      * @param surface the output Surface for which buffers should be freed. Must be one of the
214      * the output Surfaces used to create this session.
215      *
216      * @throws CameraAccessException if the camera device is no longer connected or has
217      *                               encountered a fatal error.
218      * @throws IllegalStateException if this session is no longer active, either because the session
219      *                               was explicitly closed, a new session has been created
220      *                               or the camera device has been closed.
221      * @throws IllegalArgumentException if the Surface is invalid, not part of this Session, or has
222      *                                  already been used as a target of a CaptureRequest in this
223      *                                  session or immediately prior sessions.
224      *
225      * @hide
226      */
tearDown(@onNull Surface surface)227     public abstract void tearDown(@NonNull Surface surface) throws CameraAccessException;
228 
229     /**
230      * <p>Finalize the output configurations that now have their deferred and/or extra Surfaces
231      * included.</p>
232      *
233      * <p>For camera use cases where a preview and other output configurations need to be
234      * configured, it can take some time for the preview Surface to be ready. For example, if the
235      * preview Surface is obtained from {@link android.view.SurfaceView}, the SurfaceView will only
236      * be ready after the UI layout is done, potentially delaying camera startup.</p>
237      *
238      * <p>To speed up camera startup time, the application can configure the
239      * {@link CameraCaptureSession} with the eventual preview size (via
240      * {@link OutputConfiguration#OutputConfiguration(Size,Class) a deferred OutputConfiguration}),
241      * and defer the preview output configuration until the Surface is ready. After the
242      * {@link CameraCaptureSession} is created successfully with this deferred output and other
243      * normal outputs, the application can start submitting requests as long as they do not include
244      * deferred output Surfaces. Once a deferred Surface is ready, the application can add the
245      * Surface to the deferred output configuration with the
246      * {@link OutputConfiguration#addSurface} method, and then update the deferred output
247      * configuration via this method, before it can submit capture requests with this output
248      * target.</p>
249      *
250      * <p>This function can also be called in case where multiple surfaces share the same
251      * OutputConfiguration, and one of the surfaces becomes available after the {@link
252      * CameraCaptureSession} is created. In that case, the application must first create the
253      * OutputConfiguration with the available Surface, then enable further surface sharing via
254      * {@link OutputConfiguration#enableSurfaceSharing}, before creating the CameraCaptureSession.
255      * After the CameraCaptureSession is created, and once the extra Surface becomes available, the
256      * application must then call {@link OutputConfiguration#addSurface} before finalizing the
257      * configuration with this method.</p>
258      *
259      * <p>If the provided OutputConfigurations are unchanged from session creation, this function
260      * call has no effect. This function must only be called once for a particular output
261      * configuration. </p>
262      *
263      * <p>The output Surfaces included by this list of
264      * {@link OutputConfiguration OutputConfigurations} can be used as {@link CaptureRequest}
265      * targets as soon as this call returns.</p>
266      *
267      * <p>This method is not supported by
268      * {@link CameraCharacteristics#INFO_SUPPORTED_HARDWARE_LEVEL_LEGACY LEGACY}-level devices.</p>
269      *
270      * @param outputConfigs a list of {@link OutputConfiguration OutputConfigurations} that
271      *            have had {@link OutputConfiguration#addSurface addSurface} invoked with a valid
272      *            output Surface after {@link CameraDevice#createCaptureSessionByOutputConfigurations}.
273      * @throws CameraAccessException if the camera device is no longer connected or has encountered
274      *             a fatal error.
275      * @throws IllegalStateException if this session is no longer active, either because the session
276      *             was explicitly closed, a new session has been created, or the camera device has
277      *             been closed.
278      * @throws IllegalArgumentException for invalid output configurations, including ones where the
279      *             source of the Surface is no longer valid or the Surface is from a unsupported
280      *             source. Or if one of the output configuration was already finished with an
281      *             included surface in a prior call.
282      */
finalizeOutputConfigurations( List<OutputConfiguration> outputConfigs)283     public abstract void finalizeOutputConfigurations(
284             List<OutputConfiguration> outputConfigs) throws CameraAccessException;
285 
286     /**
287      * <p>Submit a request for an image to be captured by the camera device.</p>
288      *
289      * <p>The request defines all the parameters for capturing the single image,
290      * including sensor, lens, flash, and post-processing settings.</p>
291      *
292      * <p>Each request will produce one {@link CaptureResult} and produce new frames for one or more
293      * target Surfaces, set with the CaptureRequest builder's
294      * {@link CaptureRequest.Builder#addTarget} method. The target surfaces (set with
295      * {@link CaptureRequest.Builder#addTarget}) must be a subset of the surfaces provided when this
296      * capture session was created.</p>
297      *
298      * <p>Multiple regular and reprocess requests can be in progress at once. If there are only
299      * regular requests or reprocess requests in progress, they are processed in first-in,
300      * first-out order. If there are both regular and reprocess requests in progress, regular
301      * requests are processed in first-in, first-out order and reprocess requests are processed in
302      * first-in, first-out order, respectively. However, the processing order of a regular request
303      * and a reprocess request in progress is not specified. In other words, a regular request
304      * will always be processed before regular requets that are submitted later. A reprocess request
305      * will always be processed before reprocess requests that are submitted later. However, a
306      * regular request may not be processed before reprocess requests that are submitted later.<p>
307      *
308      * <p>Requests submitted through this method have higher priority than
309      * those submitted through {@link #setRepeatingRequest} or
310      * {@link #setRepeatingBurst}, and will be processed as soon as the current
311      * repeat/repeatBurst processing completes.</p>
312      *
313      * <p>All capture sessions can be used for capturing images from the camera but only capture
314      * sessions created by
315      * {@link CameraDevice#createReprocessableCaptureSession createReprocessableCaptureSession}
316      * can submit reprocess capture requests. Submitting a reprocess request to a regular capture
317      * session will result in an {@link IllegalArgumentException}.</p>
318      *
319      * @param request the settings for this capture
320      * @param listener The callback object to notify once this request has been
321      * processed. If null, no metadata will be produced for this capture,
322      * although image data will still be produced.
323      * @param handler the handler on which the listener should be invoked, or
324      * {@code null} to use the current thread's {@link android.os.Looper
325      * looper}.
326      *
327      * @return int A unique capture sequence ID used by
328      *             {@link CaptureCallback#onCaptureSequenceCompleted}.
329      *
330      * @throws CameraAccessException if the camera device is no longer connected or has
331      *                               encountered a fatal error
332      * @throws IllegalStateException if this session is no longer active, either because the session
333      *                               was explicitly closed, a new session has been created
334      *                               or the camera device has been closed.
335      * @throws IllegalArgumentException if the request targets no Surfaces or Surfaces that are not
336      *                                  configured as outputs for this session; or the request
337      *                                  targets a set of Surfaces that cannot be submitted
338      *                                  simultaneously in a reprocessable capture session; or a
339      *                                  reprocess capture request is submitted in a
340      *                                  non-reprocessable capture session; or the reprocess capture
341      *                                  request was created with a {@link TotalCaptureResult} from
342      *                                  a different session; or the capture targets a Surface in
343      *                                  the middle of being {@link #prepare prepared}; or the
344      *                                  handler is null, the listener is not null, and the calling
345      *                                  thread has no looper.
346      *
347      * @see #captureBurst
348      * @see #setRepeatingRequest
349      * @see #setRepeatingBurst
350      * @see #abortCaptures
351      * @see CameraDevice#createReprocessableCaptureSession
352      */
capture(@onNull CaptureRequest request, @Nullable CaptureCallback listener, @Nullable Handler handler)353     public abstract int capture(@NonNull CaptureRequest request,
354             @Nullable CaptureCallback listener, @Nullable Handler handler)
355             throws CameraAccessException;
356 
357     /**
358      * <p>Submit a request for an image to be captured by the camera device.</p>
359      *
360      * <p>The behavior of this method matches that of
361      * {@link #capture(CaptureRequest, CaptureCallback, Handler)},
362      * except that it uses {@link java.util.concurrent.Executor} as an argument
363      * instead of {@link android.os.Handler}.</p>
364      *
365      * @param request the settings for this capture
366      * @param executor the executor which will be used for invoking the listener.
367      * @param listener The callback object to notify once this request has been
368      * processed.
369      *
370      * @return int A unique capture sequence ID used by
371      *             {@link CaptureCallback#onCaptureSequenceCompleted}.
372      *
373      * @throws CameraAccessException if the camera device is no longer connected or has
374      *                               encountered a fatal error
375      * @throws IllegalStateException if this session is no longer active, either because the session
376      *                               was explicitly closed, a new session has been created
377      *                               or the camera device has been closed.
378      * @throws IllegalArgumentException if the request targets no Surfaces or Surfaces that are not
379      *                                  configured as outputs for this session; or the request
380      *                                  targets a set of Surfaces that cannot be submitted
381      *                                  simultaneously in a reprocessable capture session; or a
382      *                                  reprocess capture request is submitted in a
383      *                                  non-reprocessable capture session; or the reprocess capture
384      *                                  request was created with a {@link TotalCaptureResult} from
385      *                                  a different session; or the capture targets a Surface in
386      *                                  the middle of being {@link #prepare prepared}; or the
387      *                                  executor is null, or the listener is not null.
388      *
389      * @see #captureBurst
390      * @see #setRepeatingRequest
391      * @see #setRepeatingBurst
392      * @see #abortCaptures
393      * @see CameraDevice#createReprocessableCaptureSession
394      */
captureSingleRequest(@onNull CaptureRequest request, @NonNull @CallbackExecutor Executor executor, @NonNull CaptureCallback listener)395     public int captureSingleRequest(@NonNull CaptureRequest request,
396             @NonNull @CallbackExecutor Executor executor, @NonNull CaptureCallback listener)
397             throws CameraAccessException {
398         throw new UnsupportedOperationException("Subclasses must override this method");
399     }
400 
401     /**
402      * Submit a list of requests to be captured in sequence as a burst. The
403      * burst will be captured in the minimum amount of time possible, and will
404      * not be interleaved with requests submitted by other capture or repeat
405      * calls.
406      *
407      * <p>Regular and reprocess requests can be mixed together in a single burst. Regular requests
408      * will be captured in order and reprocess requests will be processed in order, respectively.
409      * However, the processing order between a regular request and a reprocess request is not
410      * specified. Each capture produces one {@link CaptureResult} and image buffers for one or more
411      * target {@link android.view.Surface surfaces}. The target surfaces (set with
412      * {@link CaptureRequest.Builder#addTarget}) must be a subset of the surfaces provided when
413      * this capture session was created.</p>
414      *
415      * <p>The main difference between this method and simply calling
416      * {@link #capture} repeatedly is that this method guarantees that no
417      * other requests will be interspersed with the burst.</p>
418      *
419      * <p>All capture sessions can be used for capturing images from the camera but only capture
420      * sessions created by
421      * {@link CameraDevice#createReprocessableCaptureSession createReprocessableCaptureSession}
422      * can submit reprocess capture requests. Submitting a reprocess request to a regular
423      * capture session will result in an {@link IllegalArgumentException}.</p>
424      *
425      * @param requests the list of settings for this burst capture
426      * @param listener The callback object to notify each time one of the
427      * requests in the burst has been processed. If null, no metadata will be
428      * produced for any requests in this burst, although image data will still
429      * be produced.
430      * @param handler the handler on which the listener should be invoked, or
431      * {@code null} to use the current thread's {@link android.os.Looper
432      * looper}.
433      *
434      * @return int A unique capture sequence ID used by
435      *             {@link CaptureCallback#onCaptureSequenceCompleted}.
436      *
437      * @throws CameraAccessException if the camera device is no longer connected or has
438      *                               encountered a fatal error
439      * @throws IllegalStateException if this session is no longer active, either because the session
440      *                               was explicitly closed, a new session has been created
441      *                               or the camera device has been closed.
442      * @throws IllegalArgumentException If the requests target no Surfaces, or the requests target
443      *                                  Surfaces not currently configured as outputs; or one of the
444      *                                  requests targets a set of Surfaces that cannot be submitted
445      *                                  simultaneously in a reprocessable capture session; or a
446      *                                  reprocess capture request is submitted in a
447      *                                  non-reprocessable capture session; or one of the reprocess
448      *                                  capture requests was created with a
449      *                                  {@link TotalCaptureResult} from a different session; or one
450      *                                  of the captures targets a Surface in the middle of being
451      *                                  {@link #prepare prepared}; or if the handler is null, the
452      *                                  listener is not null, and the calling thread has no looper.
453      *
454      * @see #capture
455      * @see #setRepeatingRequest
456      * @see #setRepeatingBurst
457      * @see #abortCaptures
458      */
captureBurst(@onNull List<CaptureRequest> requests, @Nullable CaptureCallback listener, @Nullable Handler handler)459     public abstract int captureBurst(@NonNull List<CaptureRequest> requests,
460             @Nullable CaptureCallback listener, @Nullable Handler handler)
461             throws CameraAccessException;
462 
463     /**
464      * Submit a list of requests to be captured in sequence as a burst. The
465      * burst will be captured in the minimum amount of time possible, and will
466      * not be interleaved with requests submitted by other capture or repeat
467      * calls.
468      *
469      * <p>The behavior of this method matches that of
470      * {@link #captureBurst(List, CaptureCallback, Handler)},
471      * except that it uses {@link java.util.concurrent.Executor} as an argument
472      * instead of {@link android.os.Handler}.</p>
473      *
474      * @param requests the list of settings for this burst capture
475      * @param executor the executor which will be used for invoking the listener.
476      * @param listener The callback object to notify each time one of the
477      * requests in the burst has been processed.
478      *
479      * @return int A unique capture sequence ID used by
480      *             {@link CaptureCallback#onCaptureSequenceCompleted}.
481      *
482      * @throws CameraAccessException if the camera device is no longer connected or has
483      *                               encountered a fatal error
484      * @throws IllegalStateException if this session is no longer active, either because the session
485      *                               was explicitly closed, a new session has been created
486      *                               or the camera device has been closed.
487      * @throws IllegalArgumentException If the requests target no Surfaces, or the requests target
488      *                                  Surfaces not currently configured as outputs; or one of the
489      *                                  requests targets a set of Surfaces that cannot be submitted
490      *                                  simultaneously in a reprocessable capture session; or a
491      *                                  reprocess capture request is submitted in a
492      *                                  non-reprocessable capture session; or one of the reprocess
493      *                                  capture requests was created with a
494      *                                  {@link TotalCaptureResult} from a different session; or one
495      *                                  of the captures targets a Surface in the middle of being
496      *                                  {@link #prepare prepared}; or if the executor is null; or if
497      *                                  the listener is null.
498      *
499      * @see #capture
500      * @see #setRepeatingRequest
501      * @see #setRepeatingBurst
502      * @see #abortCaptures
503      */
captureBurstRequests(@onNull List<CaptureRequest> requests, @NonNull @CallbackExecutor Executor executor, @NonNull CaptureCallback listener)504     public int captureBurstRequests(@NonNull List<CaptureRequest> requests,
505             @NonNull @CallbackExecutor Executor executor, @NonNull CaptureCallback listener)
506             throws CameraAccessException {
507         throw new UnsupportedOperationException("Subclasses must override this method");
508     }
509 
510     /**
511      * Request endlessly repeating capture of images by this capture session.
512      *
513      * <p>With this method, the camera device will continually capture images
514      * using the settings in the provided {@link CaptureRequest}, at the maximum
515      * rate possible.</p>
516      *
517      * <p>Repeating requests are a simple way for an application to maintain a
518      * preview or other continuous stream of frames, without having to
519      * continually submit identical requests through {@link #capture}.</p>
520      *
521      * <p>Repeat requests have lower priority than those submitted
522      * through {@link #capture} or {@link #captureBurst}, so if
523      * {@link #capture} is called when a repeating request is active, the
524      * capture request will be processed before any further repeating
525      * requests are processed.<p>
526      *
527      * <p>To stop the repeating capture, call {@link #stopRepeating}. Calling
528      * {@link #abortCaptures} will also clear the request.</p>
529      *
530      * <p>Calling this method will replace any earlier repeating request or
531      * burst set up by this method or {@link #setRepeatingBurst}, although any
532      * in-progress burst will be completed before the new repeat request will be
533      * used.</p>
534      *
535      * <p>This method does not support reprocess capture requests because each reprocess
536      * {@link CaptureRequest} must be created from the {@link TotalCaptureResult} that matches
537      * the input image to be reprocessed. This is either the {@link TotalCaptureResult} of capture
538      * that is sent for reprocessing, or one of the {@link TotalCaptureResult TotalCaptureResults}
539      * of a set of captures, when data from the whole set is combined by the application into a
540      * single reprocess input image. The request must be capturing images from the camera. If a
541      * reprocess capture request is submitted, this method will throw IllegalArgumentException.</p>
542      *
543      * @param request the request to repeat indefinitely
544      * @param listener The callback object to notify every time the
545      * request finishes processing. If null, no metadata will be
546      * produced for this stream of requests, although image data will
547      * still be produced.
548      * @param handler the handler on which the listener should be invoked, or
549      * {@code null} to use the current thread's {@link android.os.Looper
550      * looper}.
551      *
552      * @return int A unique capture sequence ID used by
553      *             {@link CaptureCallback#onCaptureSequenceCompleted}.
554      *
555      * @throws CameraAccessException if the camera device is no longer connected or has
556      *                               encountered a fatal error
557      * @throws IllegalStateException if this session is no longer active, either because the session
558      *                               was explicitly closed, a new session has been created
559      *                               or the camera device has been closed.
560      * @throws IllegalArgumentException If the request references no Surfaces or references Surfaces
561      *                                  that are not currently configured as outputs; or the request
562      *                                  is a reprocess capture request; or the capture targets a
563      *                                  Surface in the middle of being {@link #prepare prepared}; or
564      *                                  the handler is null, the listener is not null, and the
565      *                                  calling thread has no looper; or no requests were passed in.
566      *
567      * @see #capture
568      * @see #captureBurst
569      * @see #setRepeatingBurst
570      * @see #stopRepeating
571      * @see #abortCaptures
572      */
setRepeatingRequest(@onNull CaptureRequest request, @Nullable CaptureCallback listener, @Nullable Handler handler)573     public abstract int setRepeatingRequest(@NonNull CaptureRequest request,
574             @Nullable CaptureCallback listener, @Nullable Handler handler)
575             throws CameraAccessException;
576 
577     /**
578      * Request endlessly repeating capture of images by this capture session.
579      *
580      * <p>The behavior of this method matches that of
581      * {@link #setRepeatingRequest(CaptureRequest, CaptureCallback, Handler)},
582      * except that it uses {@link java.util.concurrent.Executor} as an argument
583      * instead of {@link android.os.Handler}.</p>
584      *
585      * @param request the request to repeat indefinitely
586      * @param executor the executor which will be used for invoking the listener.
587      * @param listener The callback object to notify every time the
588      * request finishes processing.
589      *
590      * @return int A unique capture sequence ID used by
591      *             {@link CaptureCallback#onCaptureSequenceCompleted}.
592      *
593      * @throws CameraAccessException if the camera device is no longer connected or has
594      *                               encountered a fatal error
595      * @throws IllegalStateException if this session is no longer active, either because the session
596      *                               was explicitly closed, a new session has been created
597      *                               or the camera device has been closed.
598      * @throws IllegalArgumentException If the request references no Surfaces or references Surfaces
599      *                                  that are not currently configured as outputs; or the request
600      *                                  is a reprocess capture request; or the capture targets a
601      *                                  Surface in the middle of being {@link #prepare prepared}; or
602      *                                  the executor is null; or the listener is null.
603      *
604      * @see #capture
605      * @see #captureBurst
606      * @see #setRepeatingBurst
607      * @see #stopRepeating
608      * @see #abortCaptures
609      */
setSingleRepeatingRequest(@onNull CaptureRequest request, @NonNull @CallbackExecutor Executor executor, @NonNull CaptureCallback listener)610     public int setSingleRepeatingRequest(@NonNull CaptureRequest request,
611             @NonNull @CallbackExecutor Executor executor, @NonNull CaptureCallback listener)
612             throws CameraAccessException {
613         throw new UnsupportedOperationException("Subclasses must override this method");
614     }
615 
616     /**
617      * <p>Request endlessly repeating capture of a sequence of images by this
618      * capture session.</p>
619      *
620      * <p>With this method, the camera device will continually capture images,
621      * cycling through the settings in the provided list of
622      * {@link CaptureRequest CaptureRequests}, at the maximum rate possible.</p>
623      *
624      * <p>If a request is submitted through {@link #capture} or
625      * {@link #captureBurst}, the current repetition of the request list will be
626      * completed before the higher-priority request is handled. This guarantees
627      * that the application always receives a complete repeat burst captured in
628      * minimal time, instead of bursts interleaved with higher-priority
629      * captures, or incomplete captures.</p>
630      *
631      * <p>Repeating burst requests are a simple way for an application to
632      * maintain a preview or other continuous stream of frames where each
633      * request is different in a predicatable way, without having to continually
634      * submit requests through {@link #captureBurst}.</p>
635      *
636      * <p>To stop the repeating capture, call {@link #stopRepeating}. Any
637      * ongoing burst will still be completed, however. Calling
638      * {@link #abortCaptures} will also clear the request.</p>
639      *
640      * <p>Calling this method will replace a previously-set repeating request or
641      * burst set up by this method or {@link #setRepeatingRequest}, although any
642      * in-progress burst will be completed before the new repeat burst will be
643      * used.</p>
644      *
645      * <p>This method does not support reprocess capture requests because each reprocess
646      * {@link CaptureRequest} must be created from the {@link TotalCaptureResult} that matches
647      * the input image to be reprocessed. This is either the {@link TotalCaptureResult} of capture
648      * that is sent for reprocessing, or one of the {@link TotalCaptureResult TotalCaptureResults}
649      * of a set of captures, when data from the whole set is combined by the application into a
650      * single reprocess input image. The request must be capturing images from the camera. If a
651      * reprocess capture request is submitted, this method will throw IllegalArgumentException.</p>
652      *
653      * @param requests the list of requests to cycle through indefinitely
654      * @param listener The callback object to notify each time one of the
655      * requests in the repeating bursts has finished processing. If null, no
656      * metadata will be produced for this stream of requests, although image
657      * data will still be produced.
658      * @param handler the handler on which the listener should be invoked, or
659      * {@code null} to use the current thread's {@link android.os.Looper
660      * looper}.
661      *
662      * @return int A unique capture sequence ID used by
663      *             {@link CaptureCallback#onCaptureSequenceCompleted}.
664      *
665      * @throws CameraAccessException if the camera device is no longer connected or has
666      *                               encountered a fatal error
667      * @throws IllegalStateException if this session is no longer active, either because the session
668      *                               was explicitly closed, a new session has been created
669      *                               or the camera device has been closed.
670      * @throws IllegalArgumentException If the requests reference no Surfaces or reference Surfaces
671      *                                  not currently configured as outputs; or one of the requests
672      *                                  is a reprocess capture request; or one of the captures
673      *                                  targets a Surface in the middle of being
674      *                                  {@link #prepare prepared}; or the handler is null, the
675      *                                  listener is not null, and the calling thread has no looper;
676      *                                  or no requests were passed in.
677      *
678      * @see #capture
679      * @see #captureBurst
680      * @see #setRepeatingRequest
681      * @see #stopRepeating
682      * @see #abortCaptures
683      */
setRepeatingBurst(@onNull List<CaptureRequest> requests, @Nullable CaptureCallback listener, @Nullable Handler handler)684     public abstract int setRepeatingBurst(@NonNull List<CaptureRequest> requests,
685             @Nullable CaptureCallback listener, @Nullable Handler handler)
686             throws CameraAccessException;
687 
688     /**
689      * <p>Request endlessly repeating capture of a sequence of images by this
690      * capture session.</p>
691      *
692      * <p>The behavior of this method matches that of
693      * {@link #setRepeatingBurst(List, CaptureCallback, Handler)},
694      * except that it uses {@link java.util.concurrent.Executor} as an argument
695      * instead of {@link android.os.Handler}.</p>
696      *
697      * @param requests the list of requests to cycle through indefinitely
698      * @param executor the executor which will be used for invoking the listener.
699      * @param listener The callback object to notify each time one of the
700      * requests in the repeating bursts has finished processing.
701      *
702      * @return int A unique capture sequence ID used by
703      *             {@link CaptureCallback#onCaptureSequenceCompleted}.
704      *
705      * @throws CameraAccessException if the camera device is no longer connected or has
706      *                               encountered a fatal error
707      * @throws IllegalStateException if this session is no longer active, either because the session
708      *                               was explicitly closed, a new session has been created
709      *                               or the camera device has been closed.
710      * @throws IllegalArgumentException If the requests reference no Surfaces or reference Surfaces
711      *                                  not currently configured as outputs; or one of the requests
712      *                                  is a reprocess capture request; or one of the captures
713      *                                  targets a Surface in the middle of being
714      *                                  {@link #prepare prepared}; or the executor is null; or the
715      *                                  listener is null.
716      *
717      * @see #capture
718      * @see #captureBurst
719      * @see #setRepeatingRequest
720      * @see #stopRepeating
721      * @see #abortCaptures
722      */
setRepeatingBurstRequests(@onNull List<CaptureRequest> requests, @NonNull @CallbackExecutor Executor executor, @NonNull CaptureCallback listener)723     public int setRepeatingBurstRequests(@NonNull List<CaptureRequest> requests,
724             @NonNull @CallbackExecutor Executor executor, @NonNull CaptureCallback listener)
725             throws CameraAccessException {
726         throw new UnsupportedOperationException("Subclasses must override this method");
727     }
728 
729     /**
730      * <p>Cancel any ongoing repeating capture set by either
731      * {@link #setRepeatingRequest setRepeatingRequest} or
732      * {@link #setRepeatingBurst}. Has no effect on requests submitted through
733      * {@link #capture capture} or {@link #captureBurst captureBurst}.</p>
734      *
735      * <p>Any currently in-flight captures will still complete, as will any burst that is
736      * mid-capture. To ensure that the device has finished processing all of its capture requests
737      * and is in ready state, wait for the {@link StateCallback#onReady} callback after
738      * calling this method.</p>
739      *
740      * @throws CameraAccessException if the camera device is no longer connected or has
741      *                               encountered a fatal error
742      * @throws IllegalStateException if this session is no longer active, either because the session
743      *                               was explicitly closed, a new session has been created
744      *                               or the camera device has been closed.
745      *
746      * @see #setRepeatingRequest
747      * @see #setRepeatingBurst
748      * @see StateCallback#onReady
749      */
stopRepeating()750     public abstract void stopRepeating() throws CameraAccessException;
751 
752     /**
753      * Discard all captures currently pending and in-progress as fast as possible.
754      *
755      * <p>The camera device will discard all of its current work as fast as possible. Some in-flight
756      * captures may complete successfully and call {@link CaptureCallback#onCaptureCompleted}, while
757      * others will trigger their {@link CaptureCallback#onCaptureFailed} callbacks. If a repeating
758      * request or a repeating burst is set, it will be cleared.</p>
759      *
760      * <p>This method is the fastest way to switch the camera device to a new session with
761      * {@link CameraDevice#createCaptureSession} or
762      * {@link CameraDevice#createReprocessableCaptureSession}, at the cost of discarding in-progress
763      * work. It must be called before the new session is created. Once all pending requests are
764      * either completed or thrown away, the {@link StateCallback#onReady} callback will be called,
765      * if the session has not been closed. Otherwise, the {@link StateCallback#onClosed}
766      * callback will be fired when a new session is created by the camera device.</p>
767      *
768      * <p>Cancelling will introduce at least a brief pause in the stream of data from the camera
769      * device, since once the camera device is emptied, the first new request has to make it through
770      * the entire camera pipeline before new output buffers are produced.</p>
771      *
772      * <p>This means that using {@code abortCaptures()} to simply remove pending requests is not
773      * recommended; it's best used for quickly switching output configurations, or for cancelling
774      * long in-progress requests (such as a multi-second capture).</p>
775      *
776      * @throws CameraAccessException if the camera device is no longer connected or has
777      *                               encountered a fatal error
778      * @throws IllegalStateException if this session is no longer active, either because the session
779      *                               was explicitly closed, a new session has been created
780      *                               or the camera device has been closed.
781      *
782      * @see #setRepeatingRequest
783      * @see #setRepeatingBurst
784      * @see CameraDevice#createCaptureSession
785      * @see CameraDevice#createReprocessableCaptureSession
786      */
abortCaptures()787     public abstract void abortCaptures() throws CameraAccessException;
788 
789     /**
790      * Return if the application can submit reprocess capture requests with this camera capture
791      * session.
792      *
793      * @return {@code true} if the application can submit reprocess capture requests with this
794      *         camera capture session. {@code false} otherwise.
795      *
796      * @see CameraDevice#createReprocessableCaptureSession
797      */
isReprocessable()798     public abstract boolean isReprocessable();
799 
800     /**
801      * Get the input Surface associated with a reprocessable capture session.
802      *
803      * <p>Each reprocessable capture session has an input {@link Surface} where the reprocess
804      * capture requests get the input images from, rather than the camera device. The application
805      * can create a {@link android.media.ImageWriter ImageWriter} with this input {@link Surface}
806      * and use it to provide input images for reprocess capture requests. When the reprocessable
807      * capture session is closed, the input {@link Surface} is abandoned and becomes invalid.</p>
808      *
809      * @return The {@link Surface} where reprocessing capture requests get the input images from. If
810      *         this is not a reprocess capture session, {@code null} will be returned.
811      *
812      * @see CameraDevice#createReprocessableCaptureSession
813      * @see android.media.ImageWriter
814      * @see android.media.ImageReader
815      */
816     @Nullable
getInputSurface()817     public abstract Surface getInputSurface();
818 
819     /**
820      * Update {@link OutputConfiguration} after configuration finalization see
821      * {@link #finalizeOutputConfigurations}.
822      *
823      * <p>Any {@link OutputConfiguration} that has been modified via calls to
824      * {@link OutputConfiguration#addSurface} or {@link OutputConfiguration#removeSurface} must be
825      * updated. After the update call returns without throwing exceptions any newly added surfaces
826      * can be referenced in subsequent capture requests.</p>
827      *
828      * <p>Surfaces that get removed must not be part of any active repeating or single/burst
829      * request or have any pending results. Consider updating any repeating requests first via
830      * {@link #setRepeatingRequest} or {@link #setRepeatingBurst} and then wait for the last frame
831      * number when the sequence completes {@link CaptureCallback#onCaptureSequenceCompleted}
832      * before calling updateOutputConfiguration to remove a previously active Surface.</p>
833      *
834      * <p>Surfaces that get added must not be part of any other registered
835      * {@link OutputConfiguration}.</p>
836      *
837      * @param config Modified output configuration.
838      *
839      * @throws CameraAccessException if the camera device is no longer connected or has
840      *                               encountered a fatal error.
841      * @throws IllegalArgumentException if an attempt was made to add a {@link Surface} already
842      *                               in use by another buffer-producing API, such as MediaCodec or
843      *                               a different camera device or {@link OutputConfiguration}; or
844      *                               new surfaces are not compatible (see
845      *                               {@link OutputConfiguration#enableSurfaceSharing}); or a
846      *                               {@link Surface} that was removed from the modified
847      *                               {@link OutputConfiguration} still has pending requests.
848      * @throws IllegalStateException if this session is no longer active, either because the session
849      *                               was explicitly closed, a new session has been created
850      *                               or the camera device has been closed.
851      */
updateOutputConfiguration(OutputConfiguration config)852     public void updateOutputConfiguration(OutputConfiguration config)
853         throws CameraAccessException {
854         throw new UnsupportedOperationException("Subclasses must override this method");
855     }
856 
857     /**
858      * Close this capture session asynchronously.
859      *
860      * <p>Closing a session frees up the target output Surfaces of the session for reuse with either
861      * a new session, or to other APIs that can draw to Surfaces.</p>
862      *
863      * <p>Note that creating a new capture session with {@link CameraDevice#createCaptureSession}
864      * will close any existing capture session automatically, and call the older session listener's
865      * {@link StateCallback#onClosed} callback. Using {@link CameraDevice#createCaptureSession}
866      * directly without closing is the recommended approach for quickly switching to a new session,
867      * since unchanged target outputs can be reused more efficiently.</p>
868      *
869      * <p>Once a session is closed, all methods on it will throw an IllegalStateException, and any
870      * repeating requests or bursts are stopped (as if {@link #stopRepeating()} was called).
871      * However, any in-progress capture requests submitted to the session will be completed as
872      * normal; once all captures have completed and the session has been torn down,
873      * {@link StateCallback#onClosed} will be called.</p>
874      *
875      * <p>Closing a session is idempotent; closing more than once has no effect.</p>
876      */
877     @Override
close()878     public abstract void close();
879 
880     /**
881      * A callback object for receiving updates about the state of a camera capture session.
882      *
883      */
884     public static abstract class StateCallback {
885 
886         /**
887          * This method is called when the camera device has finished configuring itself, and the
888          * session can start processing capture requests.
889          *
890          * <p>If there are capture requests already queued with the session, they will start
891          * processing once this callback is invoked, and the session will call {@link #onActive}
892          * right after this callback is invoked.</p>
893          *
894          * <p>If no capture requests have been submitted, then the session will invoke
895          * {@link #onReady} right after this callback.</p>
896          *
897          * <p>If the camera device configuration fails, then {@link #onConfigureFailed} will
898          * be invoked instead of this callback.</p>
899          *
900          * @param session the session returned by {@link CameraDevice#createCaptureSession}
901          */
onConfigured(@onNull CameraCaptureSession session)902         public abstract void onConfigured(@NonNull CameraCaptureSession session);
903 
904         /**
905          * This method is called if the session cannot be configured as requested.
906          *
907          * <p>This can happen if the set of requested outputs contains unsupported sizes,
908          * or too many outputs are requested at once.</p>
909          *
910          * <p>The session is considered to be closed, and all methods called on it after this
911          * callback is invoked will throw an IllegalStateException. Any capture requests submitted
912          * to the session prior to this callback will be discarded and will not produce any
913          * callbacks on their listeners.</p>
914          *
915          * @param session the session returned by {@link CameraDevice#createCaptureSession}
916          */
onConfigureFailed(@onNull CameraCaptureSession session)917         public abstract void onConfigureFailed(@NonNull CameraCaptureSession session);
918 
919         /**
920          * This method is called every time the session has no more capture requests to process.
921          *
922          * <p>During the creation of a new session, this callback is invoked right after
923          * {@link #onConfigured} if no capture requests were submitted to the session prior to it
924          * completing configuration.</p>
925          *
926          * <p>Otherwise, this callback will be invoked any time the session finishes processing
927          * all of its active capture requests, and no repeating request or burst is set up.</p>
928          *
929          * @param session the session returned by {@link CameraDevice#createCaptureSession}
930          *
931          */
onReady(@onNull CameraCaptureSession session)932         public void onReady(@NonNull CameraCaptureSession session) {
933             // default empty implementation
934         }
935 
936         /**
937          * This method is called when the session starts actively processing capture requests.
938          *
939          * <p>If capture requests are submitted prior to {@link #onConfigured} being called,
940          * then the session will start processing those requests immediately after the callback,
941          * and this method will be immediately called after {@link #onConfigured}.
942          *
943          * <p>If the session runs out of capture requests to process and calls {@link #onReady},
944          * then this callback will be invoked again once new requests are submitted for capture.</p>
945          *
946          * @param session the session returned by {@link CameraDevice#createCaptureSession}
947          */
onActive(@onNull CameraCaptureSession session)948         public void onActive(@NonNull CameraCaptureSession session) {
949             // default empty implementation
950         }
951 
952         /**
953          * This method is called when camera device's input capture queue becomes empty,
954          * and is ready to accept the next request.
955          *
956          * <p>Pending capture requests exist in one of two queues: the in-flight queue where requests
957          * are already in different stages of processing pipeline, and an input queue where requests
958          * wait to enter the in-flight queue. The input queue is needed because more requests may be
959          * submitted than the current camera device pipeline depth.</p>
960          *
961          * <p>This callback is fired when the input queue becomes empty, and the camera device may
962          * have to fall back to the repeating request if set, or completely skip the next frame from
963          * the sensor. This can cause glitches to camera preview output, for example. This callback
964          * will only fire after requests queued by capture() or captureBurst(), not after a
965          * repeating request or burst enters the in-flight queue. For example, in the common case
966          * of a repeating request and a single-shot JPEG capture, this callback only fires when the
967          * JPEG request has entered the in-flight queue for capture.</p>
968          *
969          * <p>By only sending a new {@link #capture} or {@link #captureBurst} when the input
970          * queue is empty, pipeline latency can be minimized.</p>
971          *
972          * <p>This callback is not fired when the session is first created. It is different from
973          * {@link #onReady}, which is fired when all requests in both queues have been processed.</p>
974          *
975          * @param session
976          *            The session returned by {@link CameraDevice#createCaptureSession}
977          */
onCaptureQueueEmpty(@onNull CameraCaptureSession session)978         public void onCaptureQueueEmpty(@NonNull CameraCaptureSession session) {
979             // default empty implementation
980         }
981 
982         /**
983          * This method is called when the session is closed.
984          *
985          * <p>A session is closed when a new session is created by the parent camera device,
986          * or when the parent camera device is closed (either by the user closing the device,
987          * or due to a camera device disconnection or fatal error).</p>
988          *
989          * <p>Once a session is closed, all methods on it will throw an IllegalStateException, and
990          * any repeating requests or bursts are stopped (as if {@link #stopRepeating()} was called).
991          * However, any in-progress capture requests submitted to the session will be completed
992          * as normal.</p>
993          *
994          * @param session the session returned by {@link CameraDevice#createCaptureSession}
995          */
onClosed(@onNull CameraCaptureSession session)996         public void onClosed(@NonNull CameraCaptureSession session) {
997             // default empty implementation
998         }
999 
1000         /**
1001          * This method is called when the buffer pre-allocation for an output Surface is complete.
1002          *
1003          * <p>Buffer pre-allocation for an output Surface is started by the {@link #prepare} call.
1004          * While allocation is underway, the Surface must not be used as a capture target.
1005          * Once this callback fires, the output Surface provided can again be used as a target for
1006          * a capture request.</p>
1007          *
1008          * <p>In case of a error during pre-allocation (such as running out of suitable memory),
1009          * this callback is still invoked after the error is encountered, though some buffers may
1010          * not have been successfully pre-allocated.</p>
1011          *
1012          * @param session the session returned by {@link CameraDevice#createCaptureSession}
1013          * @param surface the Surface that was used with the {@link #prepare} call.
1014          */
onSurfacePrepared(@onNull CameraCaptureSession session, @NonNull Surface surface)1015         public void onSurfacePrepared(@NonNull CameraCaptureSession session,
1016                 @NonNull Surface surface) {
1017             // default empty implementation
1018         }
1019     }
1020 
1021     /**
1022      * <p>A callback object for tracking the progress of a {@link CaptureRequest} submitted to the
1023      * camera device.</p>
1024      *
1025      * <p>This callback is invoked when a request triggers a capture to start,
1026      * and when the capture is complete. In case on an error capturing an image,
1027      * the error method is triggered instead of the completion method.</p>
1028      *
1029      * @see #capture
1030      * @see #captureBurst
1031      * @see #setRepeatingRequest
1032      * @see #setRepeatingBurst
1033      */
1034     public static abstract class CaptureCallback {
1035 
1036         /**
1037          * This constant is used to indicate that no images were captured for
1038          * the request.
1039          *
1040          * @hide
1041          */
1042         public static final int NO_FRAMES_CAPTURED = -1;
1043 
1044         /**
1045          * This method is called when the camera device has started capturing
1046          * the output image for the request, at the beginning of image exposure, or
1047          * when the camera device has started processing an input image for a reprocess
1048          * request.
1049          *
1050          * <p>For a regular capture request, this callback is invoked right as
1051          * the capture of a frame begins, so it is the most appropriate time
1052          * for playing a shutter sound, or triggering UI indicators of capture.</p>
1053          *
1054          * <p>The request that is being used for this capture is provided, along
1055          * with the actual timestamp for the start of exposure. For a reprocess
1056          * request, this timestamp will be the input image's start of exposure
1057          * which matches {@link CaptureResult#SENSOR_TIMESTAMP the result timestamp field}
1058          * of the {@link TotalCaptureResult} that was used to
1059          * {@link CameraDevice#createReprocessCaptureRequest create the reprocess request}.
1060          * This timestamp matches the timestamps that will be
1061          * included in {@link CaptureResult#SENSOR_TIMESTAMP the result timestamp field},
1062          * and in the buffers sent to each output Surface. These buffer
1063          * timestamps are accessible through, for example,
1064          * {@link android.media.Image#getTimestamp() Image.getTimestamp()} or
1065          * {@link android.graphics.SurfaceTexture#getTimestamp()}.
1066          * The frame number included is equal to the frame number that will be included in
1067          * {@link CaptureResult#getFrameNumber}.</p>
1068          *
1069          * <p>For the simplest way to play a shutter sound camera shutter or a
1070          * video recording start/stop sound, see the
1071          * {@link android.media.MediaActionSound} class.</p>
1072          *
1073          * <p>The default implementation of this method does nothing.</p>
1074          *
1075          * @param session the session returned by {@link CameraDevice#createCaptureSession}
1076          * @param request the request for the capture that just begun
1077          * @param timestamp the timestamp at start of capture for a regular request, or
1078          *                  the timestamp at the input image's start of capture for a
1079          *                  reprocess request, in nanoseconds.
1080          * @param frameNumber the frame number for this capture
1081          *
1082          * @see android.media.MediaActionSound
1083          */
onCaptureStarted(@onNull CameraCaptureSession session, @NonNull CaptureRequest request, long timestamp, long frameNumber)1084         public void onCaptureStarted(@NonNull CameraCaptureSession session,
1085                 @NonNull CaptureRequest request, long timestamp, long frameNumber) {
1086             // default empty implementation
1087         }
1088 
1089         /**
1090          * This method is called when some results from an image capture are
1091          * available.
1092          *
1093          * <p>The result provided here will contain some subset of the fields of
1094          * a full result. Multiple onCapturePartial calls may happen per
1095          * capture; a given result field will only be present in one partial
1096          * capture at most. The final onCaptureCompleted call will always
1097          * contain all the fields, whether onCapturePartial was called or
1098          * not.</p>
1099          *
1100          * <p>The default implementation of this method does nothing.</p>
1101          *
1102          * @param session the session returned by {@link CameraDevice#createCaptureSession}
1103          * @param request The request that was given to the CameraDevice
1104          * @param result The partial output metadata from the capture, which
1105          * includes a subset of the CaptureResult fields.
1106          *
1107          * @see #capture
1108          * @see #captureBurst
1109          * @see #setRepeatingRequest
1110          * @see #setRepeatingBurst
1111          *
1112          * @hide
1113          */
onCapturePartial(CameraCaptureSession session, CaptureRequest request, CaptureResult result)1114         public void onCapturePartial(CameraCaptureSession session,
1115                 CaptureRequest request, CaptureResult result) {
1116             // default empty implementation
1117         }
1118 
1119         /**
1120          * This method is called when an image capture makes partial forward progress; some
1121          * (but not all) results from an image capture are available.
1122          *
1123          * <p>The result provided here will contain some subset of the fields of
1124          * a full result. Multiple {@link #onCaptureProgressed} calls may happen per
1125          * capture; a given result field will only be present in one partial
1126          * capture at most. The final {@link #onCaptureCompleted} call will always
1127          * contain all the fields (in particular, the union of all the fields of all
1128          * the partial results composing the total result).</p>
1129          *
1130          * <p>For each request, some result data might be available earlier than others. The typical
1131          * delay between each partial result (per request) is a single frame interval.
1132          * For performance-oriented use-cases, applications should query the metadata they need
1133          * to make forward progress from the partial results and avoid waiting for the completed
1134          * result.</p>
1135          *
1136          * <p>For a particular request, {@link #onCaptureProgressed} may happen before or after
1137          * {@link #onCaptureStarted}.</p>
1138          *
1139          * <p>Each request will generate at least {@code 1} partial results, and at most
1140          * {@link CameraCharacteristics#REQUEST_PARTIAL_RESULT_COUNT} partial results.</p>
1141          *
1142          * <p>Depending on the request settings, the number of partial results per request
1143          * will vary, although typically the partial count could be the same as long as the
1144          * camera device subsystems enabled stay the same.</p>
1145          *
1146          * <p>The default implementation of this method does nothing.</p>
1147          *
1148          * @param session the session returned by {@link CameraDevice#createCaptureSession}
1149          * @param request The request that was given to the CameraDevice
1150          * @param partialResult The partial output metadata from the capture, which
1151          * includes a subset of the {@link TotalCaptureResult} fields.
1152          *
1153          * @see #capture
1154          * @see #captureBurst
1155          * @see #setRepeatingRequest
1156          * @see #setRepeatingBurst
1157          */
onCaptureProgressed(@onNull CameraCaptureSession session, @NonNull CaptureRequest request, @NonNull CaptureResult partialResult)1158         public void onCaptureProgressed(@NonNull CameraCaptureSession session,
1159                 @NonNull CaptureRequest request, @NonNull CaptureResult partialResult) {
1160             // default empty implementation
1161         }
1162 
1163         /**
1164          * This method is called when an image capture has fully completed and all the
1165          * result metadata is available.
1166          *
1167          * <p>This callback will always fire after the last {@link #onCaptureProgressed};
1168          * in other words, no more partial results will be delivered once the completed result
1169          * is available.</p>
1170          *
1171          * <p>For performance-intensive use-cases where latency is a factor, consider
1172          * using {@link #onCaptureProgressed} instead.</p>
1173          *
1174          * <p>The default implementation of this method does nothing.</p>
1175          *
1176          * @param session the session returned by {@link CameraDevice#createCaptureSession}
1177          * @param request The request that was given to the CameraDevice
1178          * @param result The total output metadata from the capture, including the
1179          * final capture parameters and the state of the camera system during
1180          * capture.
1181          *
1182          * @see #capture
1183          * @see #captureBurst
1184          * @see #setRepeatingRequest
1185          * @see #setRepeatingBurst
1186          */
onCaptureCompleted(@onNull CameraCaptureSession session, @NonNull CaptureRequest request, @NonNull TotalCaptureResult result)1187         public void onCaptureCompleted(@NonNull CameraCaptureSession session,
1188                 @NonNull CaptureRequest request, @NonNull TotalCaptureResult result) {
1189             // default empty implementation
1190         }
1191 
1192         /**
1193          * This method is called instead of {@link #onCaptureCompleted} when the
1194          * camera device failed to produce a {@link CaptureResult} for the
1195          * request.
1196          *
1197          * <p>Other requests are unaffected, and some or all image buffers from
1198          * the capture may have been pushed to their respective output
1199          * streams.</p>
1200          *
1201          * <p>The default implementation of this method does nothing.</p>
1202          *
1203          * @param session
1204          *            The session returned by {@link CameraDevice#createCaptureSession}
1205          * @param request
1206          *            The request that was given to the CameraDevice
1207          * @param failure
1208          *            The output failure from the capture, including the failure reason
1209          *            and the frame number.
1210          *
1211          * @see #capture
1212          * @see #captureBurst
1213          * @see #setRepeatingRequest
1214          * @see #setRepeatingBurst
1215          */
onCaptureFailed(@onNull CameraCaptureSession session, @NonNull CaptureRequest request, @NonNull CaptureFailure failure)1216         public void onCaptureFailed(@NonNull CameraCaptureSession session,
1217                 @NonNull CaptureRequest request, @NonNull CaptureFailure failure) {
1218             // default empty implementation
1219         }
1220 
1221         /**
1222          * This method is called independently of the others in CaptureCallback,
1223          * when a capture sequence finishes and all {@link CaptureResult}
1224          * or {@link CaptureFailure} for it have been returned via this listener.
1225          *
1226          * <p>In total, there will be at least one result/failure returned by this listener
1227          * before this callback is invoked. If the capture sequence is aborted before any
1228          * requests have been processed, {@link #onCaptureSequenceAborted} is invoked instead.</p>
1229          *
1230          * <p>The default implementation does nothing.</p>
1231          *
1232          * @param session
1233          *            The session returned by {@link CameraDevice#createCaptureSession}
1234          * @param sequenceId
1235          *            A sequence ID returned by the {@link #capture} family of functions.
1236          * @param frameNumber
1237          *            The last frame number (returned by {@link CaptureResult#getFrameNumber}
1238          *            or {@link CaptureFailure#getFrameNumber}) in the capture sequence.
1239          *
1240          * @see CaptureResult#getFrameNumber()
1241          * @see CaptureFailure#getFrameNumber()
1242          * @see CaptureResult#getSequenceId()
1243          * @see CaptureFailure#getSequenceId()
1244          * @see #onCaptureSequenceAborted
1245          */
onCaptureSequenceCompleted(@onNull CameraCaptureSession session, int sequenceId, long frameNumber)1246         public void onCaptureSequenceCompleted(@NonNull CameraCaptureSession session,
1247                 int sequenceId, long frameNumber) {
1248             // default empty implementation
1249         }
1250 
1251         /**
1252          * This method is called independently of the others in CaptureCallback,
1253          * when a capture sequence aborts before any {@link CaptureResult}
1254          * or {@link CaptureFailure} for it have been returned via this listener.
1255          *
1256          * <p>Due to the asynchronous nature of the camera device, not all submitted captures
1257          * are immediately processed. It is possible to clear out the pending requests
1258          * by a variety of operations such as {@link CameraCaptureSession#stopRepeating} or
1259          * {@link CameraCaptureSession#abortCaptures}. When such an event happens,
1260          * {@link #onCaptureSequenceCompleted} will not be called.</p>
1261          *
1262          * <p>The default implementation does nothing.</p>
1263          *
1264          * @param session
1265          *            The session returned by {@link CameraDevice#createCaptureSession}
1266          * @param sequenceId
1267          *            A sequence ID returned by the {@link #capture} family of functions.
1268          *
1269          * @see CaptureResult#getFrameNumber()
1270          * @see CaptureFailure#getFrameNumber()
1271          * @see CaptureResult#getSequenceId()
1272          * @see CaptureFailure#getSequenceId()
1273          * @see #onCaptureSequenceCompleted
1274          */
onCaptureSequenceAborted(@onNull CameraCaptureSession session, int sequenceId)1275         public void onCaptureSequenceAborted(@NonNull CameraCaptureSession session,
1276                 int sequenceId) {
1277             // default empty implementation
1278         }
1279 
1280         /**
1281          * <p>This method is called if a single buffer for a capture could not be sent to its
1282          * destination surface.</p>
1283          *
1284          * <p>If the whole capture failed, then {@link #onCaptureFailed} will be called instead. If
1285          * some but not all buffers were captured but the result metadata will not be available,
1286          * then onCaptureFailed will be invoked with {@link CaptureFailure#wasImageCaptured}
1287          * returning true, along with one or more calls to {@link #onCaptureBufferLost} for the
1288          * failed outputs.</p>
1289          *
1290          * @param session
1291          *            The session returned by {@link CameraDevice#createCaptureSession}
1292          * @param request
1293          *            The request that was given to the CameraDevice
1294          * @param target
1295          *            The target Surface that the buffer will not be produced for
1296          * @param frameNumber
1297          *            The frame number for the request
1298          */
onCaptureBufferLost(@onNull CameraCaptureSession session, @NonNull CaptureRequest request, @NonNull Surface target, long frameNumber)1299         public void onCaptureBufferLost(@NonNull CameraCaptureSession session,
1300                 @NonNull CaptureRequest request, @NonNull Surface target, long frameNumber) {
1301             // default empty implementation
1302         }
1303     }
1304 
1305 }
1306