1 /* <lambda>null2 * 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.compat 18 19 import android.content.Context 20 import android.hardware.camera2.CameraAccessException 21 import android.hardware.camera2.CameraCaptureSession 22 import android.hardware.camera2.CameraCharacteristics 23 import android.hardware.camera2.CameraDevice 24 import android.hardware.camera2.CameraExtensionCharacteristics 25 import android.hardware.camera2.CameraExtensionSession 26 import android.hardware.camera2.CameraManager 27 import android.hardware.camera2.CaptureRequest 28 import android.hardware.camera2.CaptureResult 29 import android.hardware.camera2.TotalCaptureResult 30 import android.hardware.camera2.params.ExtensionSessionConfiguration 31 import android.hardware.camera2.params.InputConfiguration 32 import android.hardware.camera2.params.MultiResolutionStreamInfo 33 import android.hardware.camera2.params.OutputConfiguration 34 import android.hardware.camera2.params.SessionConfiguration 35 import android.media.ImageReader 36 import android.media.ImageWriter 37 import android.os.Handler 38 import android.util.Size 39 import android.view.Surface 40 import androidx.annotation.RequiresApi 41 import androidx.annotation.RequiresPermission 42 import androidx.camera.camera2.pipe.CameraMetadata 43 import java.util.concurrent.Executor 44 45 @RequiresApi(23) 46 internal object Api23Compat { 47 @JvmStatic 48 @Throws(CameraAccessException::class) 49 @Suppress("deprecation") 50 fun createReprocessableCaptureSession( 51 cameraDevice: CameraDevice, 52 inputConfig: InputConfiguration, 53 outputs: List<Surface>, 54 callback: CameraCaptureSession.StateCallback, 55 handler: Handler? 56 ) { 57 cameraDevice.createReprocessableCaptureSession(inputConfig, outputs, callback, handler) 58 } 59 60 @JvmStatic 61 @Throws(CameraAccessException::class) 62 @Suppress("deprecation") 63 fun createConstrainedHighSpeedCaptureSession( 64 cameraDevice: CameraDevice, 65 outputs: List<Surface>, 66 stateCallback: CameraCaptureSession.StateCallback, 67 handler: Handler? 68 ) { 69 cameraDevice.createConstrainedHighSpeedCaptureSession(outputs, stateCallback, handler) 70 } 71 72 @JvmStatic 73 @Throws(CameraAccessException::class) 74 fun createReprocessCaptureRequest( 75 cameraDevice: CameraDevice, 76 inputResult: TotalCaptureResult, 77 ): CaptureRequest.Builder { 78 return cameraDevice.createReprocessCaptureRequest(inputResult) 79 } 80 81 @JvmStatic 82 fun isReprocessable(cameraCaptureSession: CameraCaptureSession): Boolean { 83 return cameraCaptureSession.isReprocessable 84 } 85 86 @JvmStatic 87 fun getInputSurface(cameraCaptureSession: CameraCaptureSession): Surface? { 88 return cameraCaptureSession.inputSurface 89 } 90 91 @JvmStatic 92 fun newInputConfiguration(width: Int, height: Int, format: Int): InputConfiguration { 93 return InputConfiguration(width, height, format) 94 } 95 96 @JvmStatic 97 fun checkSelfPermission(context: Context, permission: String): Int { 98 return context.checkSelfPermission(permission) 99 } 100 } 101 102 @RequiresApi(24) 103 internal object Api24Compat { 104 @JvmStatic 105 @Throws(CameraAccessException::class) 106 @Suppress("deprecation") createCaptureSessionByOutputConfigurationsnull107 fun createCaptureSessionByOutputConfigurations( 108 cameraDevice: CameraDevice, 109 outputConfig: List<OutputConfiguration?>, 110 stateCallback: CameraCaptureSession.StateCallback, 111 handler: Handler? 112 ) { 113 cameraDevice.createCaptureSessionByOutputConfigurations( 114 outputConfig, 115 stateCallback, 116 handler 117 ) 118 } 119 120 @JvmStatic 121 @Throws(CameraAccessException::class) 122 @Suppress("deprecation") createReprocessableCaptureSessionByConfigurationsnull123 fun createReprocessableCaptureSessionByConfigurations( 124 cameraDevice: CameraDevice, 125 inputConfig: InputConfiguration, 126 outputs: List<OutputConfiguration?>, 127 stateCallback: CameraCaptureSession.StateCallback, 128 handler: Handler? 129 ) { 130 cameraDevice.createReprocessableCaptureSessionByConfigurations( 131 inputConfig, 132 outputs, 133 stateCallback, 134 handler 135 ) 136 } 137 138 @JvmStatic getSurfaceGroupIdnull139 fun getSurfaceGroupId(outputConfiguration: OutputConfiguration): Int { 140 return outputConfiguration.surfaceGroupId 141 } 142 } 143 144 @RequiresApi(26) 145 internal object Api26Compat { 146 @JvmStatic 147 @Throws(CameraAccessException::class) finalizeOutputConfigurationsnull148 fun finalizeOutputConfigurations( 149 cameraCaptureSession: CameraCaptureSession, 150 outputConfiguration: List<OutputConfiguration?> 151 ) { 152 return cameraCaptureSession.finalizeOutputConfigurations(outputConfiguration) 153 } 154 155 @JvmStatic newOutputConfigurationnull156 fun newOutputConfiguration(size: Size, klass: Class<*>): OutputConfiguration { 157 return OutputConfiguration(size, klass) 158 } 159 160 @JvmStatic enableSurfaceSharingnull161 fun enableSurfaceSharing(outputConfig: OutputConfiguration) { 162 outputConfig.enableSurfaceSharing() 163 } 164 165 @JvmStatic getSurfacesnull166 fun getSurfaces(outputConfig: OutputConfiguration): List<Surface> { 167 return outputConfig.surfaces 168 } 169 170 @JvmStatic addSurfacesnull171 fun addSurfaces(outputConfig: OutputConfiguration, surface: Surface) { 172 return outputConfig.addSurface(surface) 173 } 174 175 @JvmStatic onCaptureQueueEmptynull176 fun onCaptureQueueEmpty( 177 interopSessionStateCallback: CameraCaptureSession.StateCallback?, 178 session: CameraCaptureSession, 179 ) { 180 interopSessionStateCallback?.onCaptureQueueEmpty(session) 181 } 182 } 183 184 @RequiresApi(28) 185 @Suppress("DEPRECATION") 186 internal object Api28Compat { 187 @JvmStatic 188 @Throws(CameraAccessException::class) createCaptureSessionnull189 fun createCaptureSession( 190 cameraDevice: CameraDevice, 191 sessionConfig: SessionConfiguration, 192 ) { 193 cameraDevice.createCaptureSession(sessionConfig) 194 } 195 196 @JvmStatic getAvailablePhysicalCameraRequestKeysnull197 fun getAvailablePhysicalCameraRequestKeys( 198 cameraCharacteristics: CameraCharacteristics 199 ): List<CaptureRequest.Key<*>>? { 200 return cameraCharacteristics.availablePhysicalCameraRequestKeys 201 } 202 203 @JvmStatic getAvailableSessionKeysnull204 fun getAvailableSessionKeys( 205 cameraCharacteristics: CameraCharacteristics 206 ): List<CaptureRequest.Key<*>>? { 207 return cameraCharacteristics.availableSessionKeys 208 } 209 210 @JvmStatic getPhysicalCameraIdsnull211 fun getPhysicalCameraIds(cameraCharacteristics: CameraCharacteristics): Set<String> { 212 return cameraCharacteristics.physicalCameraIds 213 } 214 215 @JvmStatic getPhysicalCaptureResultsnull216 fun getPhysicalCaptureResults( 217 totalCaptureResult: TotalCaptureResult 218 ): Map<String, CaptureResult>? { 219 return totalCaptureResult.physicalCameraResults 220 } 221 222 @JvmStatic newSessionConfigurationnull223 fun newSessionConfiguration( 224 sessionType: Int, 225 outputs: List<OutputConfiguration?>, 226 executor: Executor, 227 stateCallback: CameraCaptureSession.StateCallback 228 ): SessionConfiguration { 229 return SessionConfiguration(sessionType, outputs, executor, stateCallback) 230 } 231 232 @JvmStatic setInputConfigurationnull233 fun setInputConfiguration( 234 sessionConfig: SessionConfiguration, 235 inputConfig: InputConfiguration 236 ) { 237 sessionConfig.inputConfiguration = inputConfig 238 } 239 240 @JvmStatic setSessionParametersnull241 fun setSessionParameters(sessionConfig: SessionConfiguration, params: CaptureRequest) { 242 sessionConfig.sessionParameters = params 243 } 244 245 @JvmStatic getMaxSharedSurfaceCountnull246 fun getMaxSharedSurfaceCount(outputConfig: OutputConfiguration): Int { 247 return outputConfig.maxSharedSurfaceCount 248 } 249 250 @JvmStatic setPhysicalCameraIdnull251 fun setPhysicalCameraId(outputConfig: OutputConfiguration, cameraId: String?) { 252 outputConfig.setPhysicalCameraId(cameraId) 253 } 254 255 @JvmStatic removeSurfacenull256 fun removeSurface(outputConfig: OutputConfiguration, surface: Surface) { 257 return outputConfig.removeSurface(surface) 258 } 259 260 @JvmStatic 261 @Throws(CameraAccessException::class) 262 @RequiresPermission(android.Manifest.permission.CAMERA) openCameranull263 fun openCamera( 264 cameraManager: CameraManager, 265 cameraId: String, 266 executor: Executor, 267 callback: CameraDevice.StateCallback 268 ) { 269 cameraManager.openCamera(cameraId, executor, callback) 270 } 271 272 @JvmStatic registerAvailabilityCallbacknull273 fun registerAvailabilityCallback( 274 cameraManager: CameraManager, 275 executor: Executor, 276 callback: CameraManager.AvailabilityCallback 277 ) { 278 cameraManager.registerAvailabilityCallback(executor, callback) 279 } 280 281 @JvmStatic discardFreeBuffersnull282 fun discardFreeBuffers(imageReader: ImageReader) { 283 imageReader.discardFreeBuffers() 284 } 285 } 286 287 @RequiresApi(29) 288 internal object Api29Compat { 289 @JvmStatic imageReaderNewInstancenull290 fun imageReaderNewInstance( 291 width: Int, 292 height: Int, 293 format: Int, 294 capacity: Int, 295 usage: Long 296 ): ImageReader { 297 return ImageReader.newInstance(width, height, format, capacity, usage) 298 } 299 300 @JvmStatic imageWriterNewInstancenull301 fun imageWriterNewInstance(surface: Surface, maxImages: Int, format: Int): ImageWriter { 302 return ImageWriter.newInstance(surface, maxImages, format) 303 } 304 } 305 306 @RequiresApi(30) 307 internal object Api30Compat { 308 @JvmStatic getConcurrentCameraIdsnull309 fun getConcurrentCameraIds(cameraManager: CameraManager): Set<Set<String>> { 310 return cameraManager.concurrentCameraIds 311 } 312 313 @JvmStatic getCameraAudioRestrictionnull314 fun getCameraAudioRestriction(cameraDevice: CameraDevice): Int { 315 return cameraDevice.cameraAudioRestriction 316 } 317 318 @JvmStatic setCameraAudioRestrictionnull319 fun setCameraAudioRestriction(cameraDevice: CameraDevice, mode: Int) { 320 cameraDevice.cameraAudioRestriction = mode 321 } 322 } 323 324 @RequiresApi(31) 325 internal object Api31Compat { 326 @JvmStatic newInputConfigurationnull327 fun newInputConfiguration( 328 inputConfigData: List<InputConfigData>, 329 cameraId: String 330 ): InputConfiguration { 331 check(inputConfigData.isNotEmpty()) { 332 "Call to create InputConfiguration but list of InputConfigData is empty." 333 } 334 335 if (inputConfigData.size == 1) { 336 val inputData = inputConfigData.first() 337 return InputConfiguration(inputData.width, inputData.height, inputData.format) 338 } 339 val multiResolutionInput = 340 inputConfigData.map { input -> 341 MultiResolutionStreamInfo(input.width, input.height, cameraId) 342 } 343 return InputConfiguration(multiResolutionInput, inputConfigData.first().format) 344 } 345 346 @JvmStatic newMultiResolutionStreamInfonull347 fun newMultiResolutionStreamInfo( 348 streamWidth: Int, 349 streamHeight: Int, 350 physicalCameraId: String 351 ): MultiResolutionStreamInfo { 352 return MultiResolutionStreamInfo(streamWidth, streamHeight, physicalCameraId) 353 } 354 355 @JvmStatic getPhysicalCameraTotalResultsnull356 fun getPhysicalCameraTotalResults( 357 totalCaptureResult: TotalCaptureResult 358 ): Map<String, CaptureResult>? { 359 return totalCaptureResult.physicalCameraTotalResults 360 } 361 362 @JvmStatic addSensorPixelModeUsednull363 fun addSensorPixelModeUsed( 364 outputConfiguration: OutputConfiguration, 365 sensorPixelMode: Int, 366 ) { 367 outputConfiguration.addSensorPixelModeUsed(sensorPixelMode) 368 } 369 370 @JvmStatic createExtensionCaptureSessionnull371 fun createExtensionCaptureSession( 372 cameraDevice: CameraDevice, 373 extensionConfiguration: ExtensionSessionConfiguration 374 ) { 375 cameraDevice.createExtensionSession(extensionConfiguration) 376 } 377 378 @JvmStatic getCameraExtensionCharacteristicsnull379 fun getCameraExtensionCharacteristics( 380 cameraManager: CameraManager, 381 cameraId: String 382 ): CameraExtensionCharacteristics = cameraManager.getCameraExtensionCharacteristics(cameraId) 383 384 @JvmStatic 385 fun newExtensionSessionConfiguration( 386 extensionMode: Int, 387 outputs: List<OutputConfiguration?>, 388 executor: Executor, 389 stateCallback: CameraExtensionSession.StateCallback 390 ): ExtensionSessionConfiguration { 391 return ExtensionSessionConfiguration(extensionMode, outputs, executor, stateCallback) 392 } 393 394 @JvmStatic getSupportedExtensionsnull395 fun getSupportedExtensions( 396 extensionCharacteristics: CameraExtensionCharacteristics 397 ): List<Int> = extensionCharacteristics.supportedExtensions 398 399 @JvmStatic 400 fun getExtensionSupportedSizes( 401 extensionCharacteristics: CameraExtensionCharacteristics, 402 extension: Int, 403 imageFormat: Int 404 ): List<Size> = extensionCharacteristics.getExtensionSupportedSizes(extension, imageFormat) 405 406 @JvmStatic 407 fun getExtensionSupportedSizes( 408 extensionCharacteristics: CameraExtensionCharacteristics, 409 extension: Int, 410 klass: Class<*> 411 ): List<Size> = extensionCharacteristics.getExtensionSupportedSizes(extension, klass) 412 } 413 414 @RequiresApi(33) 415 internal object Api33Compat { 416 @JvmStatic 417 fun setDynamicRangeProfile(outputConfig: OutputConfiguration, dynamicRangeProfile: Long) { 418 outputConfig.dynamicRangeProfile = dynamicRangeProfile 419 } 420 421 @JvmStatic 422 fun getDynamicRangeProfile(outputConfig: OutputConfiguration): Long { 423 return outputConfig.dynamicRangeProfile 424 } 425 426 @JvmStatic 427 fun setMirrorMode(outputConfig: OutputConfiguration, mirrorMode: Int) { 428 outputConfig.mirrorMode = mirrorMode 429 } 430 431 @JvmStatic 432 fun getMirrorMode(outputConfig: OutputConfiguration): Int { 433 return outputConfig.mirrorMode 434 } 435 436 @JvmStatic 437 fun setStreamUseCase(outputConfig: OutputConfiguration, streamUseCase: Long) { 438 outputConfig.streamUseCase = streamUseCase 439 } 440 441 @JvmStatic 442 fun getAvailableStreamUseCases(cameraMetadata: CameraMetadata): LongArray? { 443 return cameraMetadata[CameraCharacteristics.SCALER_AVAILABLE_STREAM_USE_CASES] 444 } 445 446 @JvmStatic 447 fun getStreamUseCase(outputConfig: OutputConfiguration): Long { 448 return outputConfig.streamUseCase 449 } 450 451 @JvmStatic 452 fun setTimestampBase(outputConfig: OutputConfiguration, timestampBase: Int) { 453 outputConfig.timestampBase = timestampBase 454 } 455 456 @JvmStatic 457 fun getTimestampBase(outputConfig: OutputConfiguration): Int { 458 return outputConfig.timestampBase 459 } 460 461 @JvmStatic 462 fun getAvailableCaptureRequestKeys( 463 extensionCharacteristics: CameraExtensionCharacteristics, 464 extension: Int 465 ): Set<CaptureRequest.Key<Any>> = 466 extensionCharacteristics.getAvailableCaptureRequestKeys(extension) 467 468 @JvmStatic 469 fun getAvailableCaptureResultKeys( 470 extensionCharacteristics: CameraExtensionCharacteristics, 471 extension: Int 472 ): Set<CaptureResult.Key<Any>> = 473 extensionCharacteristics.getAvailableCaptureResultKeys(extension) 474 475 @JvmStatic 476 fun newImageReaderFromImageReaderBuilder( 477 width: Int, 478 height: Int, 479 imageFormat: Int? = null, 480 maxImages: Int? = null, 481 usage: Long? = null, 482 defaultDataSpace: Int? = null, 483 defaultHardwareBufferFormat: Int? = null 484 ): ImageReader { 485 return ImageReader.Builder(width, height) 486 .apply { 487 if (imageFormat != null) setImageFormat(imageFormat) 488 if (maxImages != null) setMaxImages(maxImages) 489 if (usage != null) setUsage(usage) 490 if (defaultDataSpace != null) setDefaultDataSpace(defaultDataSpace) 491 if (defaultHardwareBufferFormat != null) 492 setDefaultHardwareBufferFormat(defaultHardwareBufferFormat) 493 } 494 .build() 495 } 496 } 497 498 @RequiresApi(34) 499 internal object Api34Compat { 500 @JvmStatic isPostviewAvailablenull501 fun isPostviewAvailable( 502 extensionCharacteristics: CameraExtensionCharacteristics, 503 extension: Int 504 ): Boolean = extensionCharacteristics.isPostviewAvailable(extension) 505 506 @JvmStatic 507 fun isCaptureProcessProgressAvailable( 508 extensionCharacteristics: CameraExtensionCharacteristics, 509 extension: Int 510 ): Boolean = extensionCharacteristics.isCaptureProcessProgressAvailable(extension) 511 512 @JvmStatic 513 fun getPostviewSupportedSizes( 514 extensionCharacteristics: CameraExtensionCharacteristics, 515 extension: Int, 516 captureSize: Size, 517 format: Int 518 ): List<Size> = 519 extensionCharacteristics.getPostviewSupportedSizes(extension, captureSize, format) 520 521 @JvmStatic 522 fun setPostviewOutputConfiguration( 523 extensionSessionConfiguration: ExtensionSessionConfiguration, 524 postviewOutputConfiguration: OutputConfiguration 525 ) { 526 extensionSessionConfiguration.postviewOutputConfiguration = postviewOutputConfiguration 527 } 528 529 @JvmStatic isZoomOverrideSupportednull530 fun isZoomOverrideSupported(cameraMetadata: CameraMetadata): Boolean = 531 cameraMetadata[CameraCharacteristics.CONTROL_AVAILABLE_SETTINGS_OVERRIDES]?.contains( 532 android.hardware.camera2.CameraMetadata.CONTROL_SETTINGS_OVERRIDE_ZOOM 533 ) == true 534 } 535 536 @RequiresApi(35) 537 internal object Api35Compat { 538 @JvmStatic 539 fun isTorchStrengthSupported(cameraMetadata: CameraMetadata): Boolean { 540 val maxLevel = cameraMetadata[CameraCharacteristics.FLASH_TORCH_STRENGTH_MAX_LEVEL] 541 return maxLevel != null && maxLevel > 1 542 } 543 544 @JvmStatic 545 fun getDefaultTorchStrengthLevel(cameraMetadata: CameraMetadata): Int { 546 val defaultLevel = cameraMetadata[CameraCharacteristics.FLASH_TORCH_STRENGTH_DEFAULT_LEVEL] 547 return defaultLevel ?: 1 548 } 549 550 @JvmStatic 551 fun getMaxTorchStrengthLevel(cameraMetadata: CameraMetadata): Int { 552 val maxLevel = cameraMetadata[CameraCharacteristics.FLASH_TORCH_STRENGTH_MAX_LEVEL] 553 return maxLevel ?: 1 554 } 555 } 556