1 /*
2  * Copyright 2022 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.integration.interop
18 
19 import android.hardware.camera2.CameraCharacteristics
20 import android.util.Pair
21 import androidx.annotation.RestrictTo
22 import androidx.camera.camera2.pipe.integration.adapter.CameraInfoAdapter.Companion.unwrapAs
23 import androidx.camera.camera2.pipe.integration.compat.workaround.getSafely
24 import androidx.camera.camera2.pipe.integration.impl.CameraProperties
25 import androidx.camera.core.CameraInfo
26 import androidx.camera.core.impl.AdapterCameraInfo
27 
28 /** An interface for retrieving Camera2-related camera information. */
29 @ExperimentalCamera2Interop
30 public class Camera2CameraInfo
31 private constructor(
32     private val cameraProperties: CameraProperties,
33     private val extensionsSpecificChars: List<Pair<CameraCharacteristics.Key<*>, Any>>? = null
34 ) {
35     /**
36      * Gets a camera characteristic value.
37      *
38      * The characteristic value is the same as the value in the [CameraCharacteristics] that would
39      * be obtained from [android.hardware.camera2.CameraManager.getCameraCharacteristics].
40      *
41      * @param <T> The type of the characteristic value.
42      * @param key The [CameraCharacteristics.Key] of the characteristic.
43      * @return the value of the characteristic. </T>
44      */
getCameraCharacteristicnull45     public fun <T> getCameraCharacteristic(key: CameraCharacteristics.Key<T>): T? {
46         extensionsSpecificChars?.forEach {
47             if (it.first == key) {
48                 @Suppress("UNCHECKED_CAST") return it.second as T
49             }
50         }
51         return cameraProperties.metadata.getSafely(key)
52     }
53 
54     /**
55      * Gets the string camera ID.
56      *
57      * The camera ID is the same as the camera ID that would be obtained from
58      * [android.hardware.camera2.CameraManager.getCameraIdList]. The ID that is retrieved is not
59      * static and can change depending on the current internal configuration of the
60      * [androidx.camera.core.Camera] from which the CameraInfo was retrieved.
61      *
62      * The Camera is a logical camera which can be backed by multiple
63      * [android.hardware.camera2.CameraDevice]. However, only one CameraDevice is active at one
64      * time. When the CameraDevice changes then the camera id will change.
65      *
66      * @return the camera ID.
67      * @throws IllegalStateException if the camera info does not contain the camera 2 camera ID
68      *   (e.g., if CameraX was not initialized with a [androidx.camera.camera2.Camera2Config]).
69      */
getCameraIdnull70     public fun getCameraId(): String = cameraProperties.cameraId.value
71 
72     public companion object {
73 
74         /**
75          * Gets the [Camera2CameraInfo] from a [CameraInfo].
76          *
77          * If the [CameraInfo] is retrieved by an Extensions-enabled
78          * [androidx.camera.core.CameraSelector], calling [getCameraCharacteristic] will return any
79          * available Extensions-specific characteristics if exists.
80          *
81          * @param cameraInfo The [CameraInfo] to get from.
82          * @return The camera information with Camera2 implementation.
83          * @throws IllegalArgumentException if the camera info does not contain the camera2
84          *   information (e.g., if CameraX was not initialized with a
85          *   [androidx.camera.camera2.Camera2Config]).
86          */
87         @JvmStatic
88         public fun from(cameraInfo: CameraInfo): Camera2CameraInfo {
89             var camera2CameraInfo = cameraInfo.unwrapAs(Camera2CameraInfo::class)
90             requireNotNull(camera2CameraInfo) {
91                 "Could not unwrap $cameraInfo as Camera2CameraInfo!"
92             }
93 
94             if (cameraInfo is AdapterCameraInfo) {
95                 if (cameraInfo.sessionProcessor != null) {
96                     camera2CameraInfo =
97                         Camera2CameraInfo(
98                             camera2CameraInfo.cameraProperties,
99                             cameraInfo.sessionProcessor?.availableCharacteristicsKeyValues
100                         )
101                 }
102             }
103             return camera2CameraInfo
104         }
105 
106         /** This is the workaround to prevent constructor from being added to public API. */
107         @RestrictTo(RestrictTo.Scope.LIBRARY)
108         @JvmStatic
109         public fun create(cameraProperties: CameraProperties): Camera2CameraInfo =
110             Camera2CameraInfo(cameraProperties)
111     }
112 }
113