blob: 26b899c6d0c3e35ecc620acfb9e520f05f957302 [file] [log] [blame]
/*
* Copyright 2020 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.impl
import android.hardware.camera2.CameraCharacteristics
import android.hardware.camera2.CaptureRequest
import android.hardware.camera2.CaptureResult
import android.hardware.camera2.params.StreamConfigurationMap
import android.os.Build
import androidx.camera.camera2.pipe.CameraId
import androidx.camera.camera2.pipe.CameraMetadata
import androidx.camera.camera2.pipe.Metadata
import androidx.camera.camera2.pipe.impl.Timestamps.formatMs
/**
* This implementation provides access to CameraCharacteristics and lazy caching of properties
* that are either expensive to create and access, or that only exist on newer versions of the
* OS.
*/
class CameraMetadataImpl constructor(
override val camera: CameraId,
override val isRedacted: Boolean,
private val characteristics: CameraCharacteristics,
private val metadata: Map<Metadata.Key<*>, Any?>
) : CameraMetadata {
@Suppress("UNCHECKED_CAST")
override fun <T> get(key: Metadata.Key<T>): T? = metadata[key] as T?
@Suppress("UNCHECKED_CAST")
override fun <T> getOrDefault(key: Metadata.Key<T>, default: T): T =
metadata[key] as T? ?: default
override fun <T> get(key: CameraCharacteristics.Key<T>): T? = characteristics[key]
override fun <T> getOrDefault(key: CameraCharacteristics.Key<T>, default: T): T =
characteristics[key] ?: default
override fun unwrap(): CameraCharacteristics? = characteristics
override val keys: Set<CameraCharacteristics.Key<*>> get() = _keys.value
override val requestKeys: Set<CaptureRequest.Key<*>> get() = _requestKeys.value
override val resultKeys: Set<CaptureResult.Key<*>> get() = _resultKeys.value
override val sessionKeys: Set<CaptureRequest.Key<*>> get() = _sessionKeys.value
override val physicalCameraIds: Set<CameraId> get() = _physicalCameraIds.value
override val physicalRequestKeys: Set<CaptureRequest.Key<*>>
get() = _physicalRequestKeys.value
override val streamMap: StreamConfigurationMap get() = _streamMap.value
private val _keys: Lazy<Set<CameraCharacteristics.Key<*>>> =
lazy(LazyThreadSafetyMode.PUBLICATION) {
try {
Debug.trace("Camera-${camera.value}#keys") {
@Suppress("UselessCallOnNotNull")
characteristics.keys.orEmpty().toSet()
}
} catch (ignored: AssertionError) {
emptySet<CameraCharacteristics.Key<*>>()
}
}
private val _requestKeys: Lazy<Set<CaptureRequest.Key<*>>> =
lazy(LazyThreadSafetyMode.PUBLICATION) {
try {
Debug.trace("Camera-${camera.value}#availableCaptureRequestKeys") {
@Suppress("UselessCallOnNotNull")
characteristics.availableCaptureRequestKeys.orEmpty().toSet()
}
} catch (ignored: AssertionError) {
emptySet<CaptureRequest.Key<*>>()
}
}
private val _resultKeys: Lazy<Set<CaptureResult.Key<*>>> =
lazy(LazyThreadSafetyMode.PUBLICATION) {
try {
Debug.trace("Camera-${camera.value}#availableCaptureResultKeys") {
@Suppress("UselessCallOnNotNull")
characteristics.availableCaptureResultKeys.orEmpty().toSet()
}
} catch (ignored: AssertionError) {
emptySet<CaptureResult.Key<*>>()
}
}
private val _physicalCameraIds: Lazy<Set<CameraId>> =
lazy(LazyThreadSafetyMode.PUBLICATION) {
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.P) {
emptySet()
} else {
try {
Debug.trace("Camera-${camera.value}#physicalCameraIds") {
@Suppress("UselessCallOnNotNull")
characteristics.physicalCameraIds.orEmpty().map { CameraId(it) }.toSet()
}
} catch (ignored: AssertionError) {
emptySet<CameraId>()
}
}
}
private val _physicalRequestKeys: Lazy<Set<CaptureRequest.Key<*>>> =
lazy(LazyThreadSafetyMode.PUBLICATION) {
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.P) {
emptySet()
} else {
try {
Debug.trace("Camera-${camera.value}#availablePhysicalCameraRequestKeys") {
@Suppress("UselessCallOnNotNull")
characteristics.availablePhysicalCameraRequestKeys.orEmpty().toSet()
}
} catch (ignored: AssertionError) {
emptySet<CaptureRequest.Key<*>>()
}
}
}
private val _sessionKeys: Lazy<Set<CaptureRequest.Key<*>>> =
lazy(LazyThreadSafetyMode.PUBLICATION) {
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.P) {
emptySet()
} else {
try {
Debug.trace("Camera-${camera.value}#availableSessionKeys") {
@Suppress("UselessCallOnNotNull")
characteristics.availableSessionKeys.orEmpty().toSet()
}
} catch (ignored: AssertionError) {
emptySet<CaptureRequest.Key<*>>()
}
}
}
private val _streamMap: Lazy<StreamConfigurationMap> =
lazy(LazyThreadSafetyMode.PUBLICATION) {
val start = Timestamps.now()
val result =
Debug.trace("Camera-${camera.value}#SCALER_STREAM_CONFIGURATION_MAP") {
get(CameraCharacteristics.SCALER_STREAM_CONFIGURATION_MAP)!!
}
val duration = Timestamps.now() - start
Log.info { "Loaded stream map for ($camera) in ${duration.formatMs()}" }
result
}
}