| /* |
| * Copyright 2022 The Android Open Source Project |
| * |
| * Licensed under the Apache License, Version 2.0 (the "License"); |
| * you may not use this file except in compliance with the License. |
| * You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| */ |
| package androidx.camera.camera2.pipe |
| |
| import androidx.annotation.RestrictTo |
| import androidx.camera.camera2.pipe.graph.GraphListener |
| import kotlinx.coroutines.Deferred |
| import kotlinx.coroutines.flow.Flow |
| |
| /** This is used to uniquely identify a specific backend implementation. */ |
| @RestrictTo(RestrictTo.Scope.LIBRARY_GROUP) |
| @JvmInline |
| value class CameraBackendId(val value: String) |
| |
| /** |
| * A CameraStatusMonitors monitors the status of the cameras, and emits updates when the status of |
| * cameras changes, for instance when the camera access priorities have changed or when a particular |
| * camera has become available. |
| */ |
| @RestrictTo(RestrictTo.Scope.LIBRARY_GROUP) |
| interface CameraStatusMonitor { |
| val cameraStatus: Flow<CameraStatus> |
| |
| abstract class CameraStatus internal constructor() { |
| object CameraPrioritiesChanged : CameraStatus() { |
| override fun toString(): String = "CameraPrioritiesChanged" |
| } |
| |
| class CameraAvailable(val cameraId: CameraId) : CameraStatus() { |
| override fun toString(): String = "CameraAvailable(camera=$cameraId" |
| } |
| } |
| } |
| |
| /** |
| * A CameraBackend is used by [CameraPipe] to abstract out the lifecycle, state, and interactions |
| * with a set of camera devices in a standard way. |
| * |
| * Each [CameraBackend] is responsible for interacting with all of the individual cameras that are |
| * available through this backend. Since cameras often have complicated lifecycles and expensive |
| * interactions, this object serves as a low level facade that is used to manage access _across_ all |
| * cameras exposed by this backend. |
| * |
| * The lifecycle of an individual camera is managed by [CameraController]s, which may be created via |
| * [CameraBackend.createCameraController]. |
| */ |
| @RestrictTo(RestrictTo.Scope.LIBRARY_GROUP) |
| interface CameraBackend { |
| val id: CameraBackendId |
| |
| /** |
| * A flow of camera statuses that provide camera status updates such as when the camera access |
| * priorities have changed, or a certain camera has become available. |
| */ |
| val cameraStatus: Flow<CameraStatusMonitor.CameraStatus> |
| |
| /** |
| * Read out a list of _openable_ [CameraId]s for this backend. The backend may be able to report |
| * Metadata for non-openable cameras. However, these cameras should not appear the list of |
| * cameras returned by [getCameraIds]. |
| */ |
| suspend fun getCameraIds(): List<CameraId>? = awaitCameraIds() |
| |
| /** Thread-blocking version of [getCameraIds] for compatibility. */ |
| fun awaitCameraIds(): List<CameraId>? |
| |
| /** |
| * Read out a set of [CameraId] sets that can be operated concurrently. When multiple cameras |
| * are open, the number of configurable streams, as well as their sizes, might be considerably |
| * limited. |
| */ |
| suspend fun getConcurrentCameraIds(): Set<Set<CameraId>>? = awaitConcurrentCameraIds() |
| |
| /** Thread-blocking version of [getConcurrentCameraIds] for compatibility. */ |
| fun awaitConcurrentCameraIds(): Set<Set<CameraId>>? |
| |
| /** |
| * Retrieve [CameraMetadata] for this backend. Backends may cache the results of these calls. |
| * |
| * This call should should always succeed if the [CameraId] is in the list of ids returned by |
| * [getCameraIds]. For some backends, it may be possible to retrieve metadata for cameras that |
| * cannot be opened directly. |
| */ |
| suspend fun getCameraMetadata(cameraId: CameraId): CameraMetadata? = |
| awaitCameraMetadata(cameraId) |
| |
| /** Thread-blocking version of [getCameraMetadata] for compatibility. */ |
| fun awaitCameraMetadata(cameraId: CameraId): CameraMetadata? |
| |
| /** |
| * Stops all active [CameraController]s, which may disconnect any cached camera connection(s). |
| * This may be called on the main thread, and any long running background operations should be |
| * executed in the background. Once all connections are fully closed, the returned [Deferred] |
| * should be completed. |
| * |
| * Subsequent [CameraController]s may still be created after invoking [disconnectAllAsync], and |
| * existing [CameraController]s may attempt to restart. |
| */ |
| fun disconnectAllAsync(): Deferred<Unit> |
| |
| /** |
| * Shutdown this backend, closing active [CameraController]s, and clearing any cached resources. |
| * |
| * This method should be used carefully, as it can cause expensive reloading and re-querying of |
| * camera lists, metadata, and state. Once a backend instance has been shut down it should not |
| * be reused, and a new instance must be recreated. |
| */ |
| fun shutdownAsync(): Deferred<Unit> |
| |
| /** |
| * Creates a new [CameraController] instance that can be used to initialize and interact with a |
| * specific Camera that is available from this CameraBackend. Creating a [CameraController] |
| * should _not_ begin opening or interacting with the Camera until [CameraController.start] is |
| * called. |
| */ |
| fun createCameraController( |
| cameraContext: CameraContext, |
| graphConfig: CameraGraph.Config, |
| graphListener: GraphListener, |
| streamGraph: StreamGraph |
| ): CameraController |
| |
| /** Connects and starts the underlying camera */ |
| fun prewarm(cameraId: CameraId) |
| |
| /** Disconnects the underlying camera. */ |
| fun disconnect(cameraId: CameraId) |
| |
| /** |
| * Disconnects the underlying camera. Once the connection is closed, the returned [Deferred] |
| * should be completed. |
| */ |
| fun disconnectAsync(cameraId: CameraId): Deferred<Unit> |
| |
| /** Disconnects all active Cameras. */ |
| fun disconnectAll() |
| } |
| |
| /** |
| * Factory for creating a new [CameraBackend]. |
| * |
| * [CameraBackend] instances should not be cached by the factory instance, as the lifecycle of |
| * returned instances is managed by [CameraPipe] unless the application asks [CameraPipe] to close |
| * and release previously created [CameraBackend]s. |
| */ |
| @RestrictTo(RestrictTo.Scope.LIBRARY_GROUP) |
| fun interface CameraBackendFactory { |
| /** Create a new [CameraBackend] instance based on the provided [CameraContext]. */ |
| fun create(cameraContext: CameraContext): CameraBackend |
| } |
| |
| /** |
| * Api for requesting and interacting with [CameraBackend] that are available in the current |
| * [CameraPipe] instance. |
| */ |
| @RestrictTo(RestrictTo.Scope.LIBRARY_GROUP) |
| interface CameraBackends { |
| /** |
| * This provides access to the default [CameraBackend]. Accessing this property will create the |
| * backend if it is not already created. |
| */ |
| val default: CameraBackend |
| |
| /** |
| * This provides a list of all available [CameraBackend] instances, including the default one. |
| * Accessing this set will not create or initialize [CameraBackend] instances. |
| */ |
| val allIds: Set<CameraBackendId> |
| |
| /** |
| * This provides a list of [CameraBackend] instances that have been loaded, including the |
| * default camera backend. Accessing this set will not create or initialize [CameraBackend] |
| * instances. |
| */ |
| val activeIds: Set<CameraBackendId> |
| |
| /** |
| * Get a previously created [CameraBackend] instance, or create a new one. If the backend fails |
| * to load or is not available, this method will return null. |
| */ |
| operator fun get(backendId: CameraBackendId): CameraBackend? |
| } |