1 /* <lambda>null2 * Copyright 2023 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.impl 18 19 import android.hardware.camera2.CameraDevice 20 import android.hardware.camera2.CaptureRequest 21 import androidx.annotation.GuardedBy 22 import androidx.camera.camera2.pipe.core.Log.debug 23 import androidx.camera.camera2.pipe.integration.adapter.SessionConfigAdapter 24 import androidx.camera.camera2.pipe.integration.adapter.propagateTo 25 import androidx.camera.camera2.pipe.integration.compat.workaround.AutoFlashAEModeDisabler 26 import androidx.camera.camera2.pipe.integration.config.CameraScope 27 import androidx.camera.core.CameraControl 28 import androidx.camera.core.ImageCapture 29 import androidx.camera.core.UseCase 30 import androidx.camera.core.impl.CaptureConfig 31 import dagger.Binds 32 import dagger.Module 33 import dagger.multibindings.IntoSet 34 import javax.inject.Inject 35 import kotlin.properties.ObservableProperty 36 import kotlin.reflect.KProperty 37 import kotlinx.coroutines.CompletableDeferred 38 import kotlinx.coroutines.Deferred 39 40 @CameraScope 41 public class State3AControl 42 @Inject 43 constructor( 44 public val cameraProperties: CameraProperties, 45 private val aeModeDisabler: AutoFlashAEModeDisabler, 46 ) : UseCaseCameraControl, UseCaseManager.RunningUseCasesChangeListener { 47 private var _requestControl: UseCaseCameraRequestControl? = null 48 override var requestControl: UseCaseCameraRequestControl? 49 get() = _requestControl 50 set(value) { 51 _requestControl = value 52 value?.let { 53 val previousSignals = 54 synchronized(lock) { 55 updateSignal = null 56 updateSignals.toList() 57 } 58 59 invalidate() // Always apply the settings to the camera. 60 61 synchronized(lock) { updateSignal }?.propagateToAll(previousSignals) 62 ?: run { for (signals in previousSignals) signals.complete(Unit) } 63 } 64 } 65 66 override fun onRunningUseCasesChanged(runningUseCases: Set<UseCase>) { 67 if (runningUseCases.isNotEmpty()) { 68 runningUseCases.updateTemplate() 69 } 70 } 71 72 private fun Deferred<Unit>.propagateToAll(previousSignals: List<CompletableDeferred<Unit>>) { 73 for (previousSignal in previousSignals) { 74 propagateTo(previousSignal) 75 } 76 } 77 78 private val lock = Any() 79 private val invalidateLock = Any() 80 81 @GuardedBy("lock") private val updateSignals = mutableSetOf<CompletableDeferred<Unit>>() 82 83 @GuardedBy("lock") 84 public var updateSignal: Deferred<Unit>? = null 85 private set 86 87 public var flashMode: Int by updateOnPropertyChange(DEFAULT_FLASH_MODE) 88 public var template: Int by updateOnPropertyChange(DEFAULT_REQUEST_TEMPLATE) 89 public var tryExternalFlashAeMode: Boolean by updateOnPropertyChange(false) 90 91 /** 92 * The [CaptureRequest.CONTROL_AE_MODE] that is set to camera if supported. 93 * 94 * If null, a value based on other settings is calculated and available via 95 * [getFinalPreferredAeMode]. If not supported, [getSupportedAeMode] is used to find the next 96 * best option. 97 */ 98 public var preferredAeMode: Int? by updateOnPropertyChange(null) 99 public var preferredFocusMode: Int? by updateOnPropertyChange(null) 100 101 override fun reset() { 102 synchronized(lock) { updateSignals.toList() }.cancelAll() 103 tryExternalFlashAeMode = false 104 preferredAeMode = null 105 preferredFocusMode = null 106 flashMode = DEFAULT_FLASH_MODE 107 template = DEFAULT_REQUEST_TEMPLATE 108 } 109 110 private fun <T> updateOnPropertyChange(initialValue: T) = 111 object : ObservableProperty<T>(initialValue) { 112 override fun setValue(thisRef: Any?, property: KProperty<*>, value: T) { 113 synchronized(invalidateLock) { super.setValue(thisRef, property, value) } 114 } 115 116 override fun afterChange(property: KProperty<*>, oldValue: T, newValue: T) { 117 if (newValue != oldValue) { 118 invalidate() 119 } 120 } 121 } 122 123 /** 124 * Returns the AE mode that is finally set to camera based on all other settings and camera 125 * capabilities. 126 */ 127 public fun getFinalSupportedAeMode(): Int = 128 cameraProperties.metadata.getSupportedAeMode(getFinalPreferredAeMode()) 129 130 /** 131 * Returns the AE mode that is finally set to camera based on all other settings. 132 * 133 * Note that this may not be supported via the camera and should be sanitized with 134 * [getSupportedAeMode]. 135 */ 136 private fun getFinalPreferredAeMode(): Int { 137 var preferAeMode = 138 preferredAeMode 139 ?: when (flashMode) { 140 ImageCapture.FLASH_MODE_OFF -> CaptureRequest.CONTROL_AE_MODE_ON 141 ImageCapture.FLASH_MODE_ON -> CaptureRequest.CONTROL_AE_MODE_ON_ALWAYS_FLASH 142 ImageCapture.FLASH_MODE_AUTO -> 143 aeModeDisabler.getCorrectedAeMode( 144 CaptureRequest.CONTROL_AE_MODE_ON_AUTO_FLASH 145 ) 146 else -> CaptureRequest.CONTROL_AE_MODE_ON 147 } 148 149 // Overwrite AE mode to ON_EXTERNAL_FLASH only if required and explicitly supported 150 if (tryExternalFlashAeMode) { 151 val isSupported = cameraProperties.metadata.isExternalFlashAeModeSupported() 152 debug { 153 "State3AControl.invalidate: trying external flash AE mode" + 154 ", supported = $isSupported" 155 } 156 if (isSupported) { 157 preferAeMode = CaptureRequest.CONTROL_AE_MODE_ON_EXTERNAL_FLASH 158 } 159 } 160 161 debug { "State3AControl.getFinalPreferredAeMode: preferAeMode = $preferAeMode" } 162 163 return preferAeMode 164 } 165 166 public fun invalidate() { 167 // TODO(b/276779600): Refactor and move the setting of these parameter to 168 // CameraGraph.Config(requiredParameters = mapOf(....)). 169 synchronized(invalidateLock) { 170 val preferAeMode = getFinalPreferredAeMode() 171 val preferAfMode = preferredFocusMode ?: getDefaultAfMode() 172 173 val parameters: MutableMap<CaptureRequest.Key<*>, Any> = 174 mutableMapOf( 175 CaptureRequest.CONTROL_AE_MODE to 176 cameraProperties.metadata.getSupportedAeMode(preferAeMode), 177 CaptureRequest.CONTROL_AF_MODE to 178 cameraProperties.metadata.getSupportedAfMode(preferAfMode), 179 CaptureRequest.CONTROL_AWB_MODE to 180 cameraProperties.metadata.getSupportedAwbMode( 181 CaptureRequest.CONTROL_AWB_MODE_AUTO 182 ) 183 ) 184 185 requestControl?.setParametersAsync(values = parameters) 186 } 187 ?.apply { 188 toCompletableDeferred().also { signal -> 189 synchronized(lock) { 190 updateSignals.add(signal) 191 updateSignal = signal 192 signal.invokeOnCompletion { 193 synchronized(lock) { updateSignals.remove(signal) } 194 } 195 } 196 } 197 } ?: run { synchronized(lock) { updateSignal = CompletableDeferred(Unit) } } 198 } 199 200 private fun getDefaultAfMode(): Int = 201 when (template) { 202 CameraDevice.TEMPLATE_RECORD -> CaptureRequest.CONTROL_AF_MODE_CONTINUOUS_VIDEO 203 CameraDevice.TEMPLATE_PREVIEW -> CaptureRequest.CONTROL_AF_MODE_CONTINUOUS_PICTURE 204 else -> CaptureRequest.CONTROL_AF_MODE_CONTINUOUS_PICTURE 205 } 206 207 private fun Collection<UseCase>.updateTemplate() { 208 SessionConfigAdapter(this).getValidSessionConfigOrNull()?.let { 209 val templateType = it.repeatingCaptureConfig.templateType 210 template = 211 if (templateType != CaptureConfig.TEMPLATE_TYPE_NONE) { 212 templateType 213 } else { 214 DEFAULT_REQUEST_TEMPLATE 215 } 216 } 217 } 218 219 private fun <T> Deferred<T>.toCompletableDeferred() = 220 CompletableDeferred<T>().also { propagateTo(it) } 221 222 private fun <T> Collection<CompletableDeferred<T>>.cancelAll() = forEach { 223 it.completeExceptionally(CameraControl.OperationCanceledException("Camera is not active.")) 224 } 225 226 @Module 227 public abstract class Bindings { 228 @Binds 229 @IntoSet 230 public abstract fun provideControls(state3AControl: State3AControl): UseCaseCameraControl 231 } 232 } 233