1 /*
<lambda>null2  * Copyright 2020 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 androidx.camera.camera2.pipe
18 
19 import android.hardware.camera2.CameraCaptureSession
20 import android.hardware.camera2.CameraConstrainedHighSpeedCaptureSession
21 import android.hardware.camera2.CameraDevice
22 import android.hardware.camera2.CaptureRequest
23 import android.hardware.camera2.params.MeteringRectangle
24 import android.hardware.camera2.params.SessionConfiguration
25 import android.os.Build
26 import android.view.Surface
27 import androidx.annotation.RestrictTo
28 import androidx.camera.camera2.pipe.CameraGraph.Constants3A.DEFAULT_FRAME_LIMIT
29 import androidx.camera.camera2.pipe.CameraGraph.Constants3A.DEFAULT_TIME_LIMIT_NS
30 import androidx.camera.camera2.pipe.CameraGraph.Flags.FinalizeSessionOnCloseBehavior.Companion.OFF
31 import androidx.camera.camera2.pipe.CameraGraph.OperatingMode.Companion.EXTENSION
32 import androidx.camera.camera2.pipe.CameraGraph.OperatingMode.Companion.HIGH_SPEED
33 import androidx.camera.camera2.pipe.CameraGraph.OperatingMode.Companion.NORMAL
34 import androidx.camera.camera2.pipe.CameraGraph.RepeatingRequestRequirementsBeforeCapture.CompletionBehavior.AT_LEAST
35 import androidx.camera.camera2.pipe.CameraGraph.RepeatingRequestRequirementsBeforeCapture.CompletionBehavior.EXACT
36 import androidx.camera.camera2.pipe.GraphState.GraphStateStarting
37 import androidx.camera.camera2.pipe.GraphState.GraphStateStopped
38 import androidx.camera.camera2.pipe.GraphState.GraphStateStopping
39 import androidx.camera.camera2.pipe.compat.Camera2Quirks
40 import androidx.camera.camera2.pipe.core.Log
41 import kotlinx.coroutines.CancellationException
42 import kotlinx.coroutines.CoroutineScope
43 import kotlinx.coroutines.Deferred
44 import kotlinx.coroutines.flow.StateFlow
45 
46 /** A [CameraGraph] represents the combined configuration and state of a camera. */
47 @RestrictTo(RestrictTo.Scope.LIBRARY_GROUP)
48 public interface CameraGraph : AutoCloseable {
49     /**
50      * A unique identifier for this CameraGraph instance. This can be used to identify the graph
51      * without holding a hard reference to the CameraGraph itself.
52      */
53     public val id: CameraGraphId
54 
55     /** The [StreamGraph] for this CameraGraph instance. */
56     public val streams: StreamGraph
57 
58     /**
59      * Returns the state flow of [GraphState], which emits the current state of the [CameraGraph],
60      * including when a [CameraGraph] is stopped, starting or started.
61      */
62     public val graphState: StateFlow<GraphState>
63 
64     /**
65      * This is a hint an app can give to a camera graph to indicate whether the camera is being used
66      * in a foreground setting, for example whether the user could see the app itself. This would
67      * inform the underlying implementation to open cameras more actively (e.g., longer timeout).
68      */
69     public var isForeground: Boolean
70 
71     /**
72      * This enables setting parameter values directly without having callers of [CameraGraph] to
73      * acquire sessions manually, but instead session is acquired on callers' behalf when making
74      * changes in [Parameters]. For detailed usage see [Parameters].
75      */
76     public val parameters: Parameters
77 
78     /**
79      * This will cause the [CameraGraph] to start opening the [CameraDevice] and configuring a
80      * [CameraCaptureSession]. While the CameraGraph is alive it will attempt to keep the camera
81      * open, active, and in a configured running state.
82      */
83     public fun start()
84 
85     /**
86      * This will cause the [CameraGraph] to stop executing requests and close the current Camera2
87      * [CameraCaptureSession] (if one is active). The most recent repeating request will be
88      * preserved, and any calls to submit a request to a session will be enqueued. To stop requests
89      * from being enqueued, close the [CameraGraph].
90      */
91     public fun stop()
92 
93     /**
94      * Used exclusively interact with the camera via a [Session] from within an existing suspending
95      * function. This function will suspend until the internal mutex lock can be acquired and
96      * returned. When possible, prefer [useSession] when possible as it will guarantee that the
97      * session will be closed.
98      *
99      * The returned [Session] **must** be closed.
100      */
101     public suspend fun acquireSession(): Session
102 
103     /**
104      * Immediately try to acquire access to the internal mutex lock, and return null if it is not
105      * currently available.
106      *
107      * The returned [Session] **must** be closed.
108      */
109     public fun acquireSessionOrNull(): Session?
110 
111     /**
112      * Used exclusively interact with the camera via a [Session] from within an existing suspending
113      * function. This method will suspend until the internal mutex lock can be acquired. This is
114      * similar to [acquireSession] an [use] with the additional guarantee that all launch and async
115      * calls will complete before the lock is released (unless the [Session] is closed early). The
116      * [action] will always execute unless parent scope has been canceled.
117      *
118      * Example:
119      * ```
120      * suspend fun process(cameraGraph: CameraGraph, analysisStream: CameraStream) {
121      *     cameraGraph.useSession { session ->
122      *         val result = session.capture(
123      *             Request(streams = listOf(jpegStream.id))
124      *         )
125      *         val frame = result.awaitFrame()
126      *         val image = frame?.awaitImage(analysisStream.id)
127      *         // process image if not null
128      *     }
129      * }
130      * ```
131      */
132     public suspend fun <T> useSession(action: suspend CoroutineScope.(Session) -> T): T
133 
134     /**
135      * Used to exclusively interact with the camera from a normal function with a [Session] by
136      * acquiring a lock to the internal mutex and running the [action] in the provided [scope]. This
137      * is similar to [useSession] with the additional guarantee that multiple calls to
138      * [useSessionIn] will be executed in the same order they are invoked in, which is not the case
139      * for `scope.launch` or `scope.async`. When possible, prefer using this function when
140      * interacting with a [CameraGraph.Session] from non-suspending code. The [action] will always
141      * execute unless parent scope has been canceled.
142      *
143      * Example:
144      * ```
145      * fun capture(
146      *     cameraGraph: CameraGraph, jpegStream: CameraStream, scope: CoroutineScope
147      * ) {
148      *     cameraGraph.useSessionIn(scope) { session ->
149      *         val result = session.capture(
150      *             Request(streams = listOf(jpegStream.id))
151      *         )
152      *         val frame = result.awaitFrame()
153      *         val jpeg = frame?.awaitImage(jpegStream.id)
154      *         // Save jpeg
155      *     }
156      * }
157      * ```
158      */
159     public fun <T> useSessionIn(
160         scope: CoroutineScope,
161         action: suspend CoroutineScope.(Session) -> T
162     ): Deferred<T>
163 
164     /**
165      * This configures the camera graph to use a specific Surface for the given stream.
166      *
167      * Changing a surface may cause the camera to stall and/or reconfigure.
168      */
169     public fun setSurface(stream: StreamId, surface: Surface?)
170 
171     /**
172      * CameraPipe allows setting the global audio restriction through [CameraPipe] and audio
173      * restrictions on individual [CameraGraph]s. When multiple settings are present, the highest
174      * level of audio restriction across global and individual [CameraGraph]s is used as the
175      * device's audio restriction.
176      *
177      * Sets the audio restriction of CameraGraph.
178      */
179     public fun updateAudioRestrictionMode(mode: AudioRestrictionMode)
180 
181     /**
182      * This defines the configuration, flags, and pre-defined structure of a [CameraGraph] instance.
183      * Note that for parameters, null is considered a valid value, and unset keys are ignored.
184      *
185      * @param camera The Camera2 [CameraId] that this [CameraGraph] represents.
186      * @param streams A list of [CameraStream]s to use when building the configuration.
187      * @param exclusiveStreamGroups A list of [CameraStream] groups where the [CameraStream]s in a
188      *   group aren't expected to used simultaneously.
189      * @param input A list of input configurations to support Camera2 Reprocessing.
190      * @param sessionTemplate The template id to use when creating the [CaptureRequest] to supply
191      *   the default parameters for a [SessionConfiguration] object.
192      * @param sessionParameters the extra parameters to apply to the [CaptureRequest] used to supply
193      *   the default parameters for a [SessionConfiguration] object. These parameters are *only*
194      *   used to create the [CaptureRequest] for session configuration. Use [defaultParameters] or
195      *   [requiredParameters] to enforce that the key is set for every request.
196      * @param sessionMode defines the [OperatingMode] of the session. May be used to configure a
197      *   [CameraConstrainedHighSpeedCaptureSession] for slow motion capture (If available)
198      * @param defaultTemplate The default template to be used if a [Request] does not specify one.
199      * @param defaultParameters The default parameters to be used for a [Request].
200      * @param defaultListeners A default set of listeners that will be added to every [Request].
201      * @param requiredParameters Will override any other configured parameter, and can be used to
202      *   enforce that specific keys are always set to specific value for every [CaptureRequest].
203      * @param cameraBackendId If defined, this tells the [CameraGraph] to use a specific
204      *   [CameraBackend] to open and operate the camera. The defined [camera] parameter must be a
205      *   camera that can be opened by this [CameraBackend]. If this value is null it will use the
206      *   default backend that has been configured by [CameraPipe].
207      * @param customCameraBackend If defined, this [customCameraBackend] will be created an used for
208      *   _only_ this [CameraGraph]. This cannot be defined if [cameraBackendId] is defined.
209      */
210     @RestrictTo(RestrictTo.Scope.LIBRARY_GROUP)
211     public data class Config(
212         val camera: CameraId,
213         val streams: List<CameraStream.Config>,
214         val exclusiveStreamGroups: List<List<CameraStream.Config>> = listOf(),
215         val input: List<InputStream.Config>? = null,
216         val postviewStream: CameraStream.Config? = null,
217         val sessionTemplate: RequestTemplate = RequestTemplate(1),
218         val sessionParameters: Map<*, Any?> = emptyMap<Any, Any?>(),
219         val sessionMode: OperatingMode = NORMAL,
220         val defaultTemplate: RequestTemplate = RequestTemplate(1),
221         val defaultParameters: Map<*, Any?> = emptyMap<Any, Any?>(),
222         val defaultListeners: List<Request.Listener> = listOf(),
223         val requiredParameters: Map<*, Any?> = emptyMap<Any, Any?>(),
224         val cameraBackendId: CameraBackendId? = null,
225         val customCameraBackend: CameraBackendFactory? = null,
226         val metadataTransform: MetadataTransform = MetadataTransform(),
227         val flags: Flags = Flags(),
228         // TODO: Internal error handling. May be better at the CameraPipe level.
229     ) {
230         internal var sharedCameraIds: List<CameraId> = emptyList()
231 
232         init {
233             check(cameraBackendId == null || customCameraBackend == null) {
234                 "Setting both cameraBackendId and customCameraBackend is not supported."
235             }
236         }
237     }
238 
239     public class ConcurrentConfig(graphConfigs: List<Config>) {
240         public val graphConfigs: List<Config>
241 
242         init {
243             check(graphConfigs.size >= 2) {
244                 "Cannot create ConcurrentGraphConfig without 2 or more CameraGraph.Config(s)"
245             }
246             val firstConfig = graphConfigs.first()
247             check(graphConfigs.all { it.cameraBackendId == firstConfig.cameraBackendId }) {
248                 "Each CameraGraph.Config must use the same camera backend!"
249             }
250 
251             val distinctCameraIds = graphConfigs.map { it.camera }.distinct()
252             check(distinctCameraIds.size == graphConfigs.size) {
253                 "Each CameraGraph.Config must have a distinct camera id!"
254             }
255 
256             this.graphConfigs =
257                 graphConfigs.map { config ->
258                     config.apply {
259                         sharedCameraIds = distinctCameraIds.filter { it != config.camera }
260                     }
261                 }
262         }
263     }
264 
265     /**
266      * Defines the repeating request requirements before a non-repeating capture.
267      *
268      * If `completionBehavior` is [AT_LEAST], repeating frames are completed at least
269      * `repeatingFramesToComplete` number of times before submitting capture. However, CameraPipe
270      * may wait for more repeating capture frames if required.
271      *
272      * If [EXACT] is used, any CameraPipe behavior is overwritten and exactly
273      * `repeatingFramesToComplete` number of frames are completed before submitting capture. This
274      * can be used in conjunction with a `repeatingFramesToComplete` value of zero to disable any
275      * CameraPipe quirky behavior added as a workaround. See
276      * [Camera2Quirks.getRepeatingRequestFrameCountForCapture] for details.
277      *
278      * @param repeatingFramesToComplete Number of repeating frames to complete before submitting a
279      *   capture. A value of zero implies no such requirement.
280      * @param completionBehavior The behavior for how `repeatingFramesToComplete` is handled.
281      */
282     public class RepeatingRequestRequirementsBeforeCapture(
283         public val repeatingFramesToComplete: UInt = 0u,
284         public val completionBehavior: CompletionBehavior = AT_LEAST,
285     ) {
286         /**
287          * Defines the behavior for how [repeatingFramesToComplete] parameter of
288          * `RepeatingRequestRequirementsBeforeCapture` is handled.
289          *
290          * @see RepeatingRequestRequirementsBeforeCapture
291          */
292         public enum class CompletionBehavior {
293             AT_LEAST,
294             EXACT
295         }
296     }
297 
298     /**
299      * Flags define boolean values that are used to adjust the behavior and interactions with
300      * camera2. These flags should default to the ideal behavior and should be overridden on
301      * specific devices to be faster or to work around bad behavior.
302      */
303     @RestrictTo(RestrictTo.Scope.LIBRARY_GROUP)
304     public data class Flags(
305         val configureBlankSessionOnStop: Boolean = false,
306 
307         /**
308          * When creating a new capture session, the camera framework waits for all the inflight
309          * capture requests from the prior session before creating the new session. Calling
310          * abortCaptures() triggers an explicit flush on the camera HAL side. Therefore, aborting
311          * the captures allows us to switch to a new capture session sooner (see the referenced bug
312          * for more info).
313          *
314          * However, there might be cases where we might not want to trigger the flush. For example,
315          * if we're recording a video, we may not want the video recording to be disrupted too
316          * early. Hence, this flag is provided so that we can override this behavior.
317          *
318          * Ideally we should be able to invoke abortCaptures() every time during close. However,
319          * improper flush implementations, which seem to occur largely on older devices, have shown
320          * to cause irregular behaviors, such as NPEs (b/139448807), capture session entering
321          * abnormal states (b/162314023), and (potentially) camera device close stalling based on
322          * testing, etc. Hence, we're enabling this behavior by default on API level >= R (30) for
323          * now.
324          * - Bug(s): b/287020251
325          * - API levels: R (30) and above
326          */
327         val abortCapturesOnStop: Boolean = Build.VERSION.SDK_INT >= Build.VERSION_CODES.R,
328 
329         /**
330          * An override flag for quirk that requires waiting for the last repeating capture request
331          * (if any) to start before submitting a non-repeating capture request in case no repeating
332          * request has started yet.
333          *
334          * The value represents how many repeating request captures need to be completed before a
335          * non-repeating capture. Note that CameraPipe may have its own logic to. When null,
336          * CameraPipe will use its own logic to decide whether such a workaround is required. When
337          * zero or negative, CameraPipe will disable such behavior.
338          *
339          * Please refer to the bugs linked here, or
340          * [Camera2Quirks.getRepeatingRequestFrameCountForCapture] for more information. This flag
341          * provides the overrides for you to enable a workaround to fix such issues.
342          * - Bug(s): b/356792665
343          * - API levels: All
344          */
345         val awaitRepeatingRequestBeforeCapture: RepeatingRequestRequirementsBeforeCapture =
346             RepeatingRequestRequirementsBeforeCapture(),
347 
348         /**
349          * Flag to wait for the last repeating capture request to start before stopping the current
350          * capture session. Please refer to the bugs linked here, or
351          * [Camera2Quirks.shouldWaitForRepeatingRequestStartOnDisconnect] for more information.
352          *
353          * This flag provides the overrides for you to override the default behavior (CameraPipe
354          * would turn on/off the quirk automatically based on device information).
355          * - Bug(s): b/146773463, b/267557892
356          * - Device(s): Camera devices on hardware level LEGACY
357          * - API levels: All
358          */
359         val awaitRepeatingRequestOnDisconnect: Boolean? = null,
360 
361         /**
362          * Flag to finalize [androidx.camera.camera2.pipe.compat.CaptureSessionState] when the
363          * CameraGraph is stopped or closed. When a CameraGraph is started, the app might wait for
364          * the Surfaces to be released before setting the new Surfaces. This creates a potential
365          * deadlock, and this quirk is aimed to mitigate such behavior by releasing the Surfaces
366          * (finalizing the session) when the graph is stopped or closed.
367          * - Bug(s): b/277310425
368          * - Device(s): All (but behaviors might differ across devices)
369          * - API levels: All
370          */
371         val finalizeSessionOnCloseBehavior: FinalizeSessionOnCloseBehavior = OFF,
372 
373         /**
374          * Flag to close the camera capture session when the CameraGraph is stopped or closed. This
375          * is needed in cases where the app that do not wish to receive further frames, or in cases
376          * where not closing the capture session before closing the camera device might cause the
377          * camera close call itself to hang indefinitely.
378          * - Bug(s): b/277310425, b/277310425
379          * - Device(s): Depends on the situation and the use case.
380          * - API levels: All
381          */
382         val closeCaptureSessionOnDisconnect: Boolean = false,
383 
384         /**
385          * Flag to close the camera device when the CameraGraph is closed. This is needed on devices
386          * where not closing the camera device before creating a new capture session can lead to
387          * crashes.
388          * - Bug(s): b/282871038
389          * - Device(s): Exynos7870 platforms.
390          * - API levels: All
391          */
392         val closeCameraDeviceOnClose: Boolean = false,
393 
394         /**
395          * Flag to enable CameraGraph to restart its internal camera controller(s) with a delay. The
396          * delay might be needed during Activity switching, to allow time for the preceding Activity
397          * to close its CameraGraphs to allow for the succeeding Activity to acquire the same
398          * camera.
399          * - Bug(s): b/344752133, b/153714651
400          * - Device(s): CameraX users
401          */
402         val enableRestartDelays: Boolean = false
403     ) {
404 
405         @JvmInline
406         public value class FinalizeSessionOnCloseBehavior
407         private constructor(public val value: Int) {
408             public companion object {
409                 /**
410                  * OFF indicates that the CameraGraph only finalizes capture session under regular
411                  * conditions, i.e., when the camera device is closed, or when a new capture session
412                  * is created.
413                  */
414                 public val OFF: FinalizeSessionOnCloseBehavior = FinalizeSessionOnCloseBehavior(0)
415 
416                 /**
417                  * IMMEDIATE indicates that the CameraGraph will finalize the current session
418                  * immediately when the CameraGraph is stopped or closed. This should be the default
419                  * behavior for devices that allows for immediate Surface reuse.
420                  */
421                 public val IMMEDIATE: FinalizeSessionOnCloseBehavior =
422                     FinalizeSessionOnCloseBehavior(1)
423 
424                 /**
425                  * TIMEOUT indicates that the CameraGraph will finalize the current session on a 2s
426                  * timeout when the CameraGraph is stopped or closed. This should only be enabled
427                  * for devices that require waiting for Surfaces to be released.
428                  */
429                 public val TIMEOUT: FinalizeSessionOnCloseBehavior =
430                     FinalizeSessionOnCloseBehavior(2)
431             }
432         }
433     }
434 
435     /**
436      * Operating mode defines the major categories of how a CameraGraph instance will operate when
437      * not operating a [NORMAL] camera graph.
438      *
439      * @property NORMAL represents standard camera operation and behavior.
440      * @property HIGH_SPEED represents a camera operating at high frame rate, usually used to
441      *   produce slow motion videos.
442      * @property EXTENSION represents device-specific modes that may operate differently or have
443      *   significant limitations in order to produce specific kinds of camera results.
444      */
445     @JvmInline
446     public value class OperatingMode private constructor(internal val mode: Int) {
447         public companion object {
448             public val NORMAL: OperatingMode = OperatingMode(0)
449             public val HIGH_SPEED: OperatingMode = OperatingMode(1)
450             public val EXTENSION: OperatingMode = OperatingMode(2)
451 
452             public fun custom(mode: Int): OperatingMode {
453                 require(mode != NORMAL.mode && mode != HIGH_SPEED.mode) {
454                     Log.error { "Custom operating mode $mode conflicts with standard modes" }
455                 }
456                 return OperatingMode(mode)
457             }
458         }
459     }
460 
461     public object Constants3A {
462         // Constants related to controlling the time or frame budget a 3A operation should get.
463         public const val DEFAULT_FRAME_LIMIT: Int = 60
464         public const val DEFAULT_TIME_LIMIT_MS: Int = 3_000
465         public const val DEFAULT_TIME_LIMIT_NS: Long = 3_000_000_000L
466 
467         // Constants related to metering regions.
468         /** No metering region is specified. */
469         public val METERING_REGIONS_EMPTY: Array<MeteringRectangle> = emptyArray()
470 
471         /**
472          * No-op metering regions, this will tell camera device to pick the right metering region
473          * for us.
474          */
475         public val METERING_REGIONS_DEFAULT: Array<MeteringRectangle> =
476             arrayOf(MeteringRectangle(0, 0, 0, 0, 0))
477 
478         /** Placeholder frame number for [Result3A] when a 3A method encounters an error. */
479         public val FRAME_NUMBER_INVALID: FrameNumber = FrameNumber(-1L)
480     }
481 
482     /**
483      * A [Session] is an interactive lock for [CameraGraph] and allows state to be changed.
484      *
485      * Holding this object prevents other systems from acquiring a [Session] until the currently
486      * held session is released. Because of its exclusive nature, [Session]s are intended for fast,
487      * short-lived state updates, or for interactive capture sequences that must not be altered.
488      * (Flash photo sequences, for example).
489      *
490      * While this object is thread-safe, it should not shared or held for long periods of time.
491      * Example: A [Session] should *not* be held during video recording.
492      */
493     @JvmDefaultWithCompatibility
494     @RestrictTo(RestrictTo.Scope.LIBRARY_GROUP)
495     public interface Session : AutoCloseable {
496         /**
497          * Causes the CameraGraph to start or update the current repeating request with the provided
498          * [Request] object. The [Request] object may be cached, and may be used for other
499          * interactions with the camera (such as updating 3A, or issuing 3A triggers).
500          */
501         public fun startRepeating(request: Request)
502 
503         /** Stop the current repeating request. */
504         public fun stopRepeating()
505 
506         /**
507          * Submit the [Request] to the camera. Requests are issued to the Camera, in order, on a
508          * background queue. Each call to submit will issue the [Request] to the camera exactly once
509          * unless the request is invalid, or unless the requests are aborted via [abort]. The same
510          * request can be submitted multiple times.
511          */
512         public fun submit(request: Request)
513 
514         /**
515          * Submit the [Request]s to the camera. [Request]s are issued to the Camera, in order, on a
516          * background queue. Each call to submit will issue the List of [Request]s to the camera
517          * exactly once unless the one or more of the requests are invalid, or unless the requests
518          * are aborted via [abort]. The same list of [Request]s may be submitted multiple times.
519          */
520         public fun submit(requests: List<Request>)
521 
522         /**
523          * Submit the [Request] to the camera, and aggregate the results into a [FrameCapture],
524          * which can be used to wait for the [Frame] to start using [FrameCapture.awaitFrame].
525          *
526          * The [FrameCapture] **must** be closed, or it will result in a memory leak.
527          */
528         public fun capture(request: Request): FrameCapture
529 
530         /**
531          * Submit the [Request]s to the camera, and aggregate the results into a list of
532          * [FrameCapture]s, which can be used to wait for the associated [Frame] using
533          * [FrameCapture.awaitFrame].
534          *
535          * Each [FrameCapture] **must** be closed, or it will result in a memory leak.
536          */
537         public fun capture(requests: List<Request>): List<FrameCapture>
538 
539         /**
540          * Abort in-flight requests. This will abort *all* requests in the current
541          * CameraCaptureSession as well as any requests that are enqueued, but that have not yet
542          * been submitted to the camera.
543          */
544         public fun abort()
545 
546         /**
547          * Applies the given 3A parameters to the camera device.
548          *
549          * @return A [Deferred] of [Result3A] value which will contain the frame number for which
550          *   these parameters were applied. It may be cancelled with a [CancellationException] if a
551          *   newer request is submitted before completion.
552          */
553         public fun update3A(
554             aeMode: AeMode? = null,
555             afMode: AfMode? = null,
556             awbMode: AwbMode? = null,
557             aeRegions: List<MeteringRectangle>? = null,
558             afRegions: List<MeteringRectangle>? = null,
559             awbRegions: List<MeteringRectangle>? = null
560         ): Deferred<Result3A>
561 
562         /**
563          * Applies the given 3A parameters to the camera device but for only one frame.
564          *
565          * @return the FrameNumber for which these parameters were applied.
566          */
567         public suspend fun submit3A(
568             aeMode: AeMode? = null,
569             afMode: AfMode? = null,
570             awbMode: AwbMode? = null,
571             aeRegions: List<MeteringRectangle>? = null,
572             afRegions: List<MeteringRectangle>? = null,
573             awbRegions: List<MeteringRectangle>? = null
574         ): Deferred<Result3A>
575 
576         /**
577          * Turns the torch to ON.
578          *
579          * This method has a side effect on the currently set AE mode. Ref:
580          * https://developer.android.com/reference/android/hardware/camera2/CaptureRequest#FLASH_MODE
581          * To use the flash control, AE mode must be set to ON or OFF. So if the AE mode is already
582          * not either ON or OFF, we will need to update the AE mode to one of those states, here we
583          * will choose ON. It is the responsibility of the application layer above CameraPipe to
584          * restore the AE mode after the torch control has been used. The [setTorchOff] or
585          * [update3A] method can be used to restore the AE state to a previous value.
586          *
587          * @return the FrameNumber at which the turn was fully turned on if switch was ON, or the
588          *   FrameNumber at which it was completely turned off when the switch was OFF.
589          */
590         public fun setTorchOn(): Deferred<Result3A>
591 
592         /**
593          * Turns the torch to OFF.
594          *
595          * @param aeMode The [AeMode] to set while disabling the torch value. If null which is the
596          *   default value, the current AE mode is used.
597          * @return the FrameNumber at which the turn was fully turned on if switch was ON, or the
598          *   FrameNumber at which it was completely turned off when the switch was OFF.
599          */
600         public fun setTorchOff(aeMode: AeMode? = null): Deferred<Result3A>
601 
602         /**
603          * Locks the auto-exposure, auto-focus and auto-whitebalance as per the given desired
604          * behaviors. This given 3A parameters are applied before the lock is obtained. If 'null'
605          * value is passed for a parameter, that parameter is ignored, and the current value for
606          * that parameter continues to be applied.
607          *
608          * @param afTriggerStartAeMode the AeMode value that should override current AeMode for
609          *   AF_TRIGGER_START request, this value should not be retained for following requests
610          * @param convergedCondition an optional function can be used to identify if the result
611          *   frame with correct 3A converge state is received. Returns true to complete the 3A scan
612          *   and going to lock the 3A state, otherwise it will continue to receive the frame results
613          *   until the [frameLimit] or [convergedTimeLimitNs] is reached.
614          * @param lockedCondition an optional function can be used to identify if the result frame
615          *   with correct 3A lock states are received. Returns true to complete lock 3A task,
616          *   otherwise it will continue to receive the frame results until the [frameLimit] or
617          *   [lockedTimeLimitNs] is reached.
618          * @param frameLimit the maximum number of frames to wait before we give up waiting for this
619          *   operation to complete.
620          * @param convergedTimeLimitNs the maximum time limit in ns we wait before we give up
621          *   waiting for 3A convergence to complete.
622          * @param lockedTimeLimitNs the maximum time limit in ns we wait before we give up waiting
623          *   for 3A locking to complete.
624          * @return [Result3A], which will contain the latest frame number at which the locks were
625          *   applied or the frame number at which the method returned early because either frame
626          *   limit or time limit was reached.
627          *
628          * TODO(sushilnath@): Add support for specifying the AE, AF and AWB modes as well. The
629          *   update of modes require special care if the desired lock behavior is immediate. In that
630          *   case we have to submit a combination of repeating and single requests so that the AF
631          *   skips the initial state of the new mode's state machine and stays locks in the new mode
632          *   as well.
633          */
634         public suspend fun lock3A(
635             aeMode: AeMode? = null,
636             afMode: AfMode? = null,
637             awbMode: AwbMode? = null,
638             aeRegions: List<MeteringRectangle>? = null,
639             afRegions: List<MeteringRectangle>? = null,
640             awbRegions: List<MeteringRectangle>? = null,
641             aeLockBehavior: Lock3ABehavior? = null,
642             afLockBehavior: Lock3ABehavior? = null,
643             awbLockBehavior: Lock3ABehavior? = null,
644             afTriggerStartAeMode: AeMode? = null,
645             convergedCondition: ((FrameMetadata) -> Boolean)? = null,
646             lockedCondition: ((FrameMetadata) -> Boolean)? = null,
647             frameLimit: Int = DEFAULT_FRAME_LIMIT,
648             convergedTimeLimitNs: Long = DEFAULT_TIME_LIMIT_NS,
649             lockedTimeLimitNs: Long = DEFAULT_TIME_LIMIT_NS
650         ): Deferred<Result3A>
651 
652         /**
653          * Unlocks auto-exposure, auto-focus, auto-whitebalance. Once they are unlocked they get
654          * back to their initial state or resume their auto scan depending on the current mode they
655          * are operating in.
656          *
657          * Providing 'true' for a parameter in this method will unlock that component and if 'false'
658          * is provided or the parameter is not specified then it will have no effect on the lock of
659          * that component, i.e. if it was locked earlier it will stay locked and if it was already
660          * unlocked, it will stay unlocked.
661          *
662          * @param unlockedCondition an optional function can be used to identify if the result frame
663          *   with correct ae, af and awb states are received. Returns true to complete the unlock 3A
664          *   task, otherwise it will continue to receive the frame results until the [frameLimit] or
665          *   [timeLimitNs] is reached.
666          * @param frameLimit the maximum number of frames to wait before we give up waiting for this
667          *   operation to complete.
668          * @param timeLimitNs the maximum time limit in ms we wait before we give up waiting for
669          *   this operation to complete.
670          * @return [Result3A], which will contain the latest frame number at which the auto-focus,
671          *   auto-exposure, auto-white balance were unlocked as per the method arguments.
672          */
673         public suspend fun unlock3A(
674             ae: Boolean? = null,
675             af: Boolean? = null,
676             awb: Boolean? = null,
677             unlockedCondition: ((FrameMetadata) -> Boolean)? = null,
678             frameLimit: Int = DEFAULT_FRAME_LIMIT,
679             timeLimitNs: Long = DEFAULT_TIME_LIMIT_NS
680         ): Deferred<Result3A>
681 
682         /**
683          * This methods does pre-capture metering sequence and locks auto-focus. Once the operation
684          * completes, we can proceed to take high-quality pictures.
685          *
686          * Note: Flash will be used during pre-capture metering and during image capture if the AE
687          * mode was set to [AeMode.ON_AUTO_FLASH] or [AeMode.ON_ALWAYS_FLASH], thus firing it for
688          * low light captures or for every capture, respectively.
689          *
690          * @param lockedCondition an optional function can be used to identify if the result frame
691          *   with correct lock states for ae, af and awb is received. Returns true to complete lock
692          *   3A task, otherwise it will continue to receive the frame results until the [frameLimit]
693          *   or [timeLimitNs] is reached.
694          * @param frameLimit the maximum number of frames to wait before we give up waiting for this
695          *   operation to complete.
696          * @param timeLimitNs the maximum time limit in ms we wait before we give up waiting for
697          *   this operation to complete.
698          * @return [Result3A], which will contain the latest frame number at which the locks were
699          *   applied or the frame number at which the method returned early because either frame
700          *   limit or time limit was reached.
701          */
702         public suspend fun lock3AForCapture(
703             lockedCondition: ((FrameMetadata) -> Boolean)? = null,
704             frameLimit: Int = DEFAULT_FRAME_LIMIT,
705             timeLimitNs: Long = DEFAULT_TIME_LIMIT_NS,
706         ): Deferred<Result3A>
707 
708         /**
709          * This methods does pre-capture metering sequence and locks auto-focus. Once the operation
710          * completes, we can proceed to take high-quality pictures.
711          *
712          * Note: Flash will be used during pre-capture metering and during image capture if the AE
713          * mode was set to [AeMode.ON_AUTO_FLASH] or [AeMode.ON_ALWAYS_FLASH], thus firing it for
714          * low light captures or for every capture, respectively.
715          *
716          * @param triggerAf Whether to trigger AF, enabled by default.
717          * @param waitForAwb Whether to wait for AWB to converge/lock, disabled by default.
718          * @param frameLimit the maximum number of frames to wait before we give up waiting for this
719          *   operation to complete.
720          * @param timeLimitNs the maximum time limit in ms we wait before we give up waiting for
721          *   this operation to complete.
722          * @return [Result3A], which will contain the latest frame number at which the locks were
723          *   applied or the frame number at which the method returned early because either frame
724          *   limit or time limit was reached.
725          */
726         public suspend fun lock3AForCapture(
727             triggerAf: Boolean = true,
728             waitForAwb: Boolean = false,
729             frameLimit: Int = DEFAULT_FRAME_LIMIT,
730             timeLimitNs: Long = DEFAULT_TIME_LIMIT_NS,
731         ): Deferred<Result3A>
732 
733         /**
734          * After submitting pre-capture metering sequence needed by [lock3AForCapture] method, the
735          * camera system can internally lock the auto-exposure routine for subsequent still image
736          * capture, and if not image capture request is submitted the auto-exposure may not resume
737          * it's normal scan. This method brings focus and exposure back to normal after high quality
738          * image captures using [lock3AForCapture] method.
739          *
740          * @param cancelAf Whether to trigger AF cancel, enabled by default.
741          */
742         public suspend fun unlock3APostCapture(cancelAf: Boolean = true): Deferred<Result3A>
743     }
744 
745     /**
746      * [Parameters] is a Map-like interface that stores the key-value parameter pairs from
747      * [CaptureRequest] and [Metadata] for each [CameraGraph]. Parameter are read/set directly using
748      * get/set methods in this interface.
749      *
750      * During an active [CameraGraph.Session], changes in [Parameters] may not be applied right
751      * away. Instead, the change will be applied after [CameraGraph.Session] closes. When there is
752      * no active [CameraGraph.Session], the change will be applied without having to wait for the
753      * session to close. When applying parameter changes, it will overwrite parameter values that
754      * were configured when building the request, and overwrite [Config.defaultParameters]. It will
755      * not overwrite [Config.requiredParameters].
756      *
757      * Note that [Parameters] only store values that is a result of methods from this interface. The
758      * parameter values that were set from implicit template values, or from building a request
759      * directly will not be reflected here.
760      */
761     public interface Parameters {
762         /** Get the value correspond to the given [CaptureRequest.Key]. */
763         public operator fun <T> get(key: CaptureRequest.Key<T>): T?
764 
765         /** Get the value correspond to the given [Metadata.Key]. */
766         public operator fun <T> get(key: Metadata.Key<T>): T?
767 
768         /** Store the [CaptureRequest] key value pair in the class. */
769         public operator fun <T : Any> set(key: CaptureRequest.Key<T>, value: T?)
770 
771         /** Store the [Metadata] key value pair in the class. */
772         public operator fun <T : Any> set(key: Metadata.Key<T>, value: T?)
773 
774         /**
775          * Store the key value pairs in the class. The key is either [CaptureRequest.Key] or
776          * [Metadata.Key].
777          */
778         public fun setAll(newParameters: Map<Any, Any?>)
779 
780         /** Clear all [CaptureRequest] and [Metadata] parameters stored in the class. */
781         public fun clear()
782 
783         /**
784          * Remove the [CaptureRequest] key value pair associated with the given key. Returns true if
785          * a key was present and removed.
786          */
787         public fun <T> remove(key: CaptureRequest.Key<T>): Boolean
788 
789         /**
790          * Remove the [Metadata] key value pair associated with the given key. Returns true if a key
791          * was present and removed.
792          */
793         public fun <T> remove(key: Metadata.Key<T>): Boolean
794 
795         /**
796          * Remove all parameters that match the given keys. The key is either [CaptureRequest.Key]
797          * or [Metadata.Key].
798          */
799         public fun removeAll(keys: Set<*>): Boolean
800     }
801 }
802 
803 /**
804  * GraphState represents public the public facing state of a [CameraGraph] instance. When created, a
805  * [CameraGraph] starts in [GraphStateStopped]. Calling [CameraGraph.start] puts the graph into
806  * [GraphStateStarting], and [CameraGraph.stop] puts the graph into [GraphStateStopping]. Remaining
807  * states are produced by the underlying camera as a result of these start/stop calls.
808  */
809 @RestrictTo(RestrictTo.Scope.LIBRARY_GROUP)
810 public abstract class GraphState internal constructor(private val name: String) {
811     /**
812      * When the [CameraGraph] is starting. This means we're in the process of opening a (virtual)
813      * camera and creating a capture session.
814      */
815     public object GraphStateStarting : GraphState("GRAPH_STARTING")
816 
817     /**
818      * When the [CameraGraph] is started. This means a capture session has been successfully created
819      * for the [CameraGraph].
820      */
821     public object GraphStateStarted : GraphState("GRAPH_STARTED")
822 
823     /**
824      * When the [CameraGraph] is stopping. This means we're in the process of stopping the graph.
825      */
826     public object GraphStateStopping : GraphState("GRAPH_STOPPING")
827 
828     /**
829      * When the [CameraGraph] hasn't been started, or stopped. This does not guarantee the closure
830      * of the capture session or the camera device itself.
831      */
832     public object GraphStateStopped : GraphState("GRAPH_STOPPED")
833 
834     /**
835      * When the [CameraGraph] has encountered an error. If [willAttemptRetry] is true, CameraPipe
836      * will retry opening the camera (and creating a capture session).
837      */
838     public class GraphStateError(
839         public val cameraError: CameraError,
840         public val willAttemptRetry: Boolean
841     ) : GraphState("GRAPH_ERROR") {
toStringnull842         override fun toString(): String =
843             super.toString() + "(cameraError=$cameraError, willAttemptRetry=$willAttemptRetry)"
844     }
845 
846     override fun toString(): String = name
847 }
848 
849 /** @see [CameraDevice.AUDIO_RESTRICTION_NONE] and other constants. */
850 @RestrictTo(RestrictTo.Scope.LIBRARY_GROUP)
851 @JvmInline
852 public value class AudioRestrictionMode internal constructor(public val value: Int) {
853     public companion object {
854         public val AUDIO_RESTRICTION_NONE: AudioRestrictionMode = AudioRestrictionMode(0)
855         public val AUDIO_RESTRICTION_VIBRATION: AudioRestrictionMode = AudioRestrictionMode(1)
856         public val AUDIO_RESTRICTION_VIBRATION_SOUND: AudioRestrictionMode = AudioRestrictionMode(3)
857     }
858 }
859