Aperture: Add support for logical cameras
Change-Id: Ied678db241a38bdb8ae0910edd25da5a4bc1aa20
diff --git a/app/src/main/java/org/lineageos/aperture/Camera2CameraInfoExt.kt b/app/src/main/java/org/lineageos/aperture/Camera2CameraInfoExt.kt
new file mode 100644
index 0000000..7f640ce
--- /dev/null
+++ b/app/src/main/java/org/lineageos/aperture/Camera2CameraInfoExt.kt
@@ -0,0 +1,63 @@
+/*
+ * Copyright (C) 2022 The LineageOS Project
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+package org.lineageos.aperture
+
+import android.hardware.camera2.CameraCharacteristics
+import android.os.Build
+import androidx.camera.camera2.interop.Camera2CameraInfo
+
+/**
+ * We're adding this here since it's private. We're supposed to use
+ * CameraCharacteristics.getPhysicalCameraIds() but it's not exposed by CameraX yet.
+ */
+private val LOGICAL_MULTI_CAMERA_PHYSICAL_IDS by lazy {
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
+ CameraCharacteristics.Key(
+ "android.logicalMultiCamera.physicalIds",
+ ByteArray::class.java
+ )
+ } else {
+ throw Exception("Requesting LOGICAL_MULTI_CAMERA_PHYSICAL_IDS on older Android version")
+ }
+}
+
+/**
+ * Return the set of physical camera ids that this logical {@link CameraDevice} is made
+ * up of.
+ *
+ * If the camera device isn't a logical camera, return an empty set.
+ */
+val Camera2CameraInfo.physicalCameraIds: Set<String>
+ @androidx.camera.camera2.interop.ExperimentalCamera2Interop
+ get() {
+ if (Build.VERSION.SDK_INT < Build.VERSION_CODES.P) {
+ return setOf()
+ }
+
+ val availableCapabilities = getCameraCharacteristic(
+ CameraCharacteristics.REQUEST_AVAILABLE_CAPABILITIES
+ ) ?: throw AssertionError(
+ "android.request.availableCapabilities must be non-null in the characteristics"
+ )
+ if (!availableCapabilities.contains(
+ CameraCharacteristics.REQUEST_AVAILABLE_CAPABILITIES_LOGICAL_MULTI_CAMERA
+ )
+ ) {
+ return setOf()
+ }
+
+ val physicalCamIds: ByteArray = getCameraCharacteristic(
+ LOGICAL_MULTI_CAMERA_PHYSICAL_IDS
+ ) ?: throw AssertionError(
+ "android.logicalMultiCamera.physicalIds must be non-null in the characteristics"
+ )
+
+ val physicalCamIdString = String(physicalCamIds, Charsets.UTF_8)
+ val physicalCameraIdArray = physicalCamIdString.split(0.toChar())
+
+ return physicalCameraIdArray.toSet()
+ }
diff --git a/app/src/main/java/org/lineageos/aperture/utils/Camera.kt b/app/src/main/java/org/lineageos/aperture/utils/Camera.kt
index d78e1d0..4e44874 100644
--- a/app/src/main/java/org/lineageos/aperture/utils/Camera.kt
+++ b/app/src/main/java/org/lineageos/aperture/utils/Camera.kt
@@ -12,6 +12,7 @@
import androidx.camera.video.Quality
import androidx.camera.video.QualitySelector
import org.lineageos.aperture.getSupportedModes
+import org.lineageos.aperture.physicalCameraIds
import kotlin.reflect.safeCast
/**
@@ -35,6 +36,9 @@
val exposureCompensationRange = cameraInfo.exposureState.exposureCompensationRange
val hasFlashUnit = cameraInfo.hasFlashUnit()
+ val physicalCameraIds = camera2CameraInfo.physicalCameraIds
+ val isLogical = physicalCameraIds.isNotEmpty()
+
val supportedVideoQualities: MutableList<Quality> =
QualitySelector.getSupportedQualities(cameraInfo)