1 /*
2  * Copyright 2021 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.CameraCharacteristics
20 import android.hardware.camera2.CameraCharacteristics.INFO_SUPPORTED_HARDWARE_LEVEL
21 import android.hardware.camera2.CameraCharacteristics.INFO_SUPPORTED_HARDWARE_LEVEL_LEGACY
22 import android.hardware.camera2.CameraMetadata.INFO_SUPPORTED_HARDWARE_LEVEL_3
23 import android.hardware.camera2.CameraMetadata.INFO_SUPPORTED_HARDWARE_LEVEL_EXTERNAL
24 import android.hardware.camera2.CameraMetadata.INFO_SUPPORTED_HARDWARE_LEVEL_FULL
25 import android.hardware.camera2.CameraMetadata.INFO_SUPPORTED_HARDWARE_LEVEL_LIMITED
26 import android.hardware.camera2.CaptureRequest
27 import android.hardware.camera2.CaptureResult
28 import android.os.Build
29 import androidx.annotation.RestrictTo
30 import androidx.camera.camera2.pipe.compat.Api34Compat
31 import androidx.camera.camera2.pipe.compat.Api35Compat
32 
33 /**
34  * [CameraMetadata] is a compatibility wrapper around [CameraCharacteristics].
35  *
36  * Applications should, in most situations, prefer using this interface to using the unwrapping and
37  * using the underlying [CameraCharacteristics] object directly. Implementation(s) of this interface
38  * provide compatibility guarantees and performance improvements over using [CameraCharacteristics]
39  * directly. This allows code to get reasonable behavior for all properties across all OS levels and
40  * makes behavior that depends on [CameraMetadata] easier to test and reason about.
41  */
42 @RestrictTo(RestrictTo.Scope.LIBRARY_GROUP)
43 public interface CameraMetadata : Metadata, UnsafeWrapper {
getnull44     public operator fun <T> get(key: CameraCharacteristics.Key<T>): T?
45 
46     public fun <T> getOrDefault(key: CameraCharacteristics.Key<T>, default: T): T
47 
48     public val camera: CameraId
49     public val isRedacted: Boolean
50 
51     public val keys: Set<CameraCharacteristics.Key<*>>
52     public val requestKeys: Set<CaptureRequest.Key<*>>
53     public val resultKeys: Set<CaptureResult.Key<*>>
54     public val sessionKeys: Set<CaptureRequest.Key<*>>
55 
56     public val physicalCameraIds: Set<CameraId>
57     public val physicalRequestKeys: Set<CaptureRequest.Key<*>>
58     public val supportedExtensions: Set<Int>
59 
60     public suspend fun getPhysicalMetadata(cameraId: CameraId): CameraMetadata
61 
62     public fun awaitPhysicalMetadata(cameraId: CameraId): CameraMetadata
63 
64     public suspend fun getExtensionMetadata(extension: Int): CameraExtensionMetadata
65 
66     public fun awaitExtensionMetadata(extension: Int): CameraExtensionMetadata
67 
68     public companion object {
69         /**
70          * Extension properties for querying the available capabilities of a camera device across
71          * all API levels.
72          */
73         public var EMPTY_INT_ARRAY: IntArray = IntArray(0)
74 
75         public const val CAPABILITIES_MANUAL_SENSOR: Int = 1
76         public const val CAPABILITIES_MANUAL_POST_PROCESSING: Int = 2
77         public const val CAPABILITIES_RAW: Int = 3
78         public const val CAPABILITIES_PRIVATE_REPROCESSING: Int = 4
79         public const val CAPABILITIES_READ_SENSOR_SETTINGS: Int = 5
80         public const val CAPABILITIES_BURST_CAPTURE: Int = 6
81         public const val CAPABILITIES_YUV_REPROCESSING: Int = 7
82         public const val CAPABILITIES_DEPTH_OUTPUT: Int = 8
83         public const val CAPABILITIES_CONSTRAINED_HIGH_SPEED_VIDEO: Int = 9
84         public const val CAPABILITIES_MOTION_TRACKING: Int = 10
85         public const val CAPABILITIES_LOGICAL_MULTI_CAMERA: Int = 11
86         public const val CAPABILITIES_MONOCHROME: Int = 12
87         public const val CAPABILITIES_SECURE_IMAGE_DATA: Int = 13
88         public const val CAPABILITIES_SYSTEM_CAMERA: Int = 14
89         public const val CAPABILITIES_OFFLINE_REPROCESSING: Int = 15
90 
91         public val CameraMetadata.availableCapabilities: IntArray
92             @JvmStatic
93             get() = this[CameraCharacteristics.REQUEST_AVAILABLE_CAPABILITIES] ?: EMPTY_INT_ARRAY
94 
95         public val CameraMetadata.isHardwareLevelExternal: Boolean
96             @JvmStatic
97             get() = this[INFO_SUPPORTED_HARDWARE_LEVEL] == INFO_SUPPORTED_HARDWARE_LEVEL_EXTERNAL
98 
99         public val CameraMetadata.isHardwareLevelLegacy: Boolean
100             @JvmStatic
101             get() = this[INFO_SUPPORTED_HARDWARE_LEVEL] == INFO_SUPPORTED_HARDWARE_LEVEL_LEGACY
102 
103         public val CameraMetadata.isHardwareLevelLimited: Boolean
104             @JvmStatic
105             get() = this[INFO_SUPPORTED_HARDWARE_LEVEL] == INFO_SUPPORTED_HARDWARE_LEVEL_LIMITED
106 
107         public val CameraMetadata.isHardwareLevelFull: Boolean
108             @JvmStatic
109             get() = this[INFO_SUPPORTED_HARDWARE_LEVEL] == INFO_SUPPORTED_HARDWARE_LEVEL_FULL
110 
111         public val CameraMetadata.isHardwareLevel3: Boolean
112             @JvmStatic
113             get() = this[INFO_SUPPORTED_HARDWARE_LEVEL] == INFO_SUPPORTED_HARDWARE_LEVEL_3
114 
115         public val CameraMetadata.supportsManualSensor: Boolean
116             @JvmStatic get() = this.availableCapabilities.contains(CAPABILITIES_MANUAL_SENSOR)
117 
118         public val CameraMetadata.supportsManualPostProcessing: Boolean
119             @JvmStatic
120             get() = this.availableCapabilities.contains(CAPABILITIES_MANUAL_POST_PROCESSING)
121 
122         public val CameraMetadata.supportsRaw: Boolean
123             @JvmStatic get() = this.availableCapabilities.contains(CAPABILITIES_RAW)
124 
125         public val CameraMetadata.supportsPrivateReprocessing: Boolean
126             @JvmStatic
127             get() = this.availableCapabilities.contains(CAPABILITIES_PRIVATE_REPROCESSING)
128 
129         public val CameraMetadata.supportsSensorSettings: Boolean
130             @JvmStatic
131             get() = this.availableCapabilities.contains(CAPABILITIES_READ_SENSOR_SETTINGS)
132 
133         public val CameraMetadata.supportsBurstCapture: Boolean
134             @JvmStatic get() = this.availableCapabilities.contains(CAPABILITIES_BURST_CAPTURE)
135 
136         public val CameraMetadata.supportsYuvReprocessing: Boolean
137             @JvmStatic get() = this.availableCapabilities.contains(CAPABILITIES_YUV_REPROCESSING)
138 
139         public val CameraMetadata.supportsDepthOutput: Boolean
140             @JvmStatic get() = this.availableCapabilities.contains(CAPABILITIES_DEPTH_OUTPUT)
141 
142         public val CameraMetadata.supportsHighSpeedVideo: Boolean
143             @JvmStatic
144             get() = this.availableCapabilities.contains(CAPABILITIES_CONSTRAINED_HIGH_SPEED_VIDEO)
145 
146         public val CameraMetadata.supportsMotionTracking: Boolean
147             @JvmStatic get() = this.availableCapabilities.contains(CAPABILITIES_MOTION_TRACKING)
148 
149         public val CameraMetadata.supportsLogicalMultiCamera: Boolean
150             @JvmStatic
151             get() = this.availableCapabilities.contains(CAPABILITIES_LOGICAL_MULTI_CAMERA)
152 
153         public val CameraMetadata.supportsMonochrome: Boolean
154             @JvmStatic get() = this.availableCapabilities.contains(CAPABILITIES_MONOCHROME)
155 
156         public val CameraMetadata.supportsSecureImageData: Boolean
157             @JvmStatic get() = this.availableCapabilities.contains(CAPABILITIES_SECURE_IMAGE_DATA)
158 
159         public val CameraMetadata.supportsSystemCamera: Boolean
160             @JvmStatic get() = this.availableCapabilities.contains(CAPABILITIES_SYSTEM_CAMERA)
161 
162         public val CameraMetadata.supportsOfflineReprocessing: Boolean
163             @JvmStatic
164             get() = this.availableCapabilities.contains(CAPABILITIES_OFFLINE_REPROCESSING)
165 
166         public val CameraMetadata.supportsAutoFocusTrigger: Boolean
167             @JvmStatic
168             get() {
169                 val minFocusDistance = this[CameraCharacteristics.LENS_INFO_MINIMUM_FOCUS_DISTANCE]
170                 if (minFocusDistance != null) {
171                     return minFocusDistance > 0
172                 }
173                 val availableAfModes =
174                     this[CameraCharacteristics.CONTROL_AF_AVAILABLE_MODES] ?: return false
175                 return availableAfModes.contains(CaptureRequest.CONTROL_AF_MODE_AUTO) ||
176                     availableAfModes.contains(CaptureRequest.CONTROL_AF_MODE_MACRO) ||
177                     availableAfModes.contains(CaptureRequest.CONTROL_AF_MODE_CONTINUOUS_PICTURE) ||
178                     availableAfModes.contains(CaptureRequest.CONTROL_AF_MODE_CONTINUOUS_VIDEO)
179             }
180 
181         /**
182          * Returns `true` if overriding zoom settings is supported on the device, otherwise `false`.
183          */
184         public val CameraMetadata.supportsZoomOverride: Boolean
185             @JvmStatic
186             get() =
187                 Build.VERSION.SDK_INT >= Build.VERSION_CODES.UPSIDE_DOWN_CAKE &&
188                     Api34Compat.isZoomOverrideSupported(this)
189 
190         /**
191          * Returns `true` if configuring torch strength is supported on the device, otherwise
192          * `false`.
193          */
194         public val CameraMetadata.supportsTorchStrength: Boolean
195             @JvmStatic
196             get() =
197                 Build.VERSION.SDK_INT >= Build.VERSION_CODES.VANILLA_ICE_CREAM &&
198                     Api35Compat.isTorchStrengthSupported(this)
199 
200         /**
201          * Returns the maximum torch strength level supported by the device.
202          *
203          * The torch strength is applied only when [CaptureRequest.CONTROL_AE_MODE] is set to
204          * [CaptureRequest.CONTROL_AE_MODE_ON] and [CaptureRequest.FLASH_MODE] is set to
205          * [CaptureRequest.FLASH_MODE_TORCH].
206          *
207          * Framework returns `1` when configuring torch strength is not supported on the device.
208          * This method also returns `1` when the API level doesn't met to align the behavior.
209          */
210         public val CameraMetadata.maxTorchStrengthLevel: Int
211             @JvmStatic
212             get() =
213                 if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.VANILLA_ICE_CREAM)
214                     Api35Compat.getMaxTorchStrengthLevel(this)
215                 else 1
216 
217         /**
218          * Returns the default torch strength level.
219          *
220          * The torch strength is applied only when [CaptureRequest.CONTROL_AE_MODE] is set to
221          * [CaptureRequest.CONTROL_AE_MODE_ON] and [CaptureRequest.FLASH_MODE] is set to
222          * [CaptureRequest.FLASH_MODE_TORCH].
223          *
224          * Framework returns `1` when configuring torch strength is not supported on the device.
225          * This method also returns `1` when the API level doesn't met to align the behavior.
226          */
227         public val CameraMetadata.defaultTorchStrengthLevel: Int
228             @JvmStatic
229             get() =
230                 if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.VANILLA_ICE_CREAM)
231                     Api35Compat.getDefaultTorchStrengthLevel(this)
232                 else 1
233 
234         public val CameraMetadata.supportsLowLightBoost: Boolean
235             get() {
236                 val availableAeModes =
237                     this[CameraCharacteristics.CONTROL_AE_AVAILABLE_MODES] ?: return false
238                 return availableAeModes.contains(
239                     AeMode.CONTROL_AE_MODE_ON_LOW_LIGHT_BOOST_BRIGHTNESS_PRIORITY
240                 )
241             }
242     }
243 }
244