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.graph 18 19 import android.hardware.camera2.CaptureRequest 20 import android.hardware.camera2.params.MeteringRectangle 21 import androidx.camera.camera2.pipe.AeMode 22 import androidx.camera.camera2.pipe.AfMode 23 import androidx.camera.camera2.pipe.AwbMode 24 import androidx.camera.camera2.pipe.FlashMode 25 import androidx.camera.camera2.pipe.config.CameraGraphScope 26 import javax.inject.Inject 27 28 /** 29 * Holds the most recent 3A state for a single CameraGraph. 30 * 31 * This object is used to maintain the key-value pairs for the most recent 3A state that is used 32 * when building the requests that are sent to a CameraCaptureSession. 33 * 34 * The state is comprised of the modes, metering regions for ae, af and awb, and locks for ae and 35 * awb. We don't track the lock for af since af lock is achieved by setting 'af trigger = start' in 36 * in a request and then omitting the af trigger field in the subsequent requests doesn't disturb 37 * the af state. However for ae and awb, the lock type is boolean and should be explicitly set to 38 * 'true' in the subsequent requests once we have locked ae/awb and want them to stay locked. 39 */ 40 @CameraGraphScope 41 internal class GraphState3A @Inject constructor() { 42 var aeMode: AeMode? = null <lambda>null43 get() = synchronized(this) { field } 44 private set 45 46 var afMode: AfMode? = null <lambda>null47 get() = synchronized(this) { field } 48 private set 49 50 var awbMode: AwbMode? = null <lambda>null51 get() = synchronized(this) { field } 52 private set 53 54 var flashMode: FlashMode? = null <lambda>null55 get() = synchronized(this) { field } 56 private set 57 58 var aeRegions: List<MeteringRectangle>? = null <lambda>null59 get() = synchronized(this) { field } 60 private set 61 62 var afRegions: List<MeteringRectangle>? = null <lambda>null63 get() = synchronized(this) { field } 64 private set 65 66 var awbRegions: List<MeteringRectangle>? = null <lambda>null67 get() = synchronized(this) { field } 68 private set 69 70 var aeLock: Boolean? = null <lambda>null71 get() = synchronized(this) { field } 72 private set 73 74 var awbLock: Boolean? = null <lambda>null75 get() = synchronized(this) { field } 76 private set 77 updatenull78 fun update( 79 aeMode: AeMode? = null, 80 afMode: AfMode? = null, 81 awbMode: AwbMode? = null, 82 flashMode: FlashMode? = null, 83 aeRegions: List<MeteringRectangle>? = null, 84 afRegions: List<MeteringRectangle>? = null, 85 awbRegions: List<MeteringRectangle>? = null, 86 aeLock: Boolean? = null, 87 awbLock: Boolean? = null 88 ) { 89 synchronized(this) { 90 aeMode?.let { this.aeMode = it } 91 afMode?.let { this.afMode = it } 92 awbMode?.let { this.awbMode = it } 93 flashMode?.let { this.flashMode = it } 94 aeRegions?.let { this.aeRegions = it.ifEmpty { null } } 95 afRegions?.let { this.afRegions = it.ifEmpty { null } } 96 awbRegions?.let { this.awbRegions = it.ifEmpty { null } } 97 aeLock?.let { this.aeLock = it } 98 awbLock?.let { this.awbLock = it } 99 } 100 } 101 readStatenull102 fun readState(): Map<CaptureRequest.Key<*>, Any> { 103 synchronized(this) { 104 val map = mutableMapOf<CaptureRequest.Key<*>, Any>() 105 aeMode?.let { map.put(CaptureRequest.CONTROL_AE_MODE, it.value) } 106 afMode?.let { map.put(CaptureRequest.CONTROL_AF_MODE, it.value) } 107 awbMode?.let { map.put(CaptureRequest.CONTROL_AWB_MODE, it.value) } 108 flashMode?.let { map.put(CaptureRequest.FLASH_MODE, it.value) } 109 aeRegions?.let { map.put(CaptureRequest.CONTROL_AE_REGIONS, it.toTypedArray()) } 110 afRegions?.let { map.put(CaptureRequest.CONTROL_AF_REGIONS, it.toTypedArray()) } 111 awbRegions?.let { map.put(CaptureRequest.CONTROL_AWB_REGIONS, it.toTypedArray()) } 112 aeLock?.let { map.put(CaptureRequest.CONTROL_AE_LOCK, it) } 113 awbLock?.let { map.put(CaptureRequest.CONTROL_AWB_LOCK, it) } 114 return map 115 } 116 } 117 writeTonull118 fun writeTo(map: MutableMap<Any, Any?>) { 119 synchronized(this) { 120 aeMode?.let { map[CaptureRequest.CONTROL_AE_MODE] = it.value } 121 afMode?.let { map[CaptureRequest.CONTROL_AF_MODE] = it.value } 122 awbMode?.let { map[CaptureRequest.CONTROL_AWB_MODE] = it.value } 123 flashMode?.let { map[CaptureRequest.FLASH_MODE] = it.value } 124 aeRegions?.let { map[CaptureRequest.CONTROL_AE_REGIONS] = it.toTypedArray() } 125 afRegions?.let { map[CaptureRequest.CONTROL_AF_REGIONS] = it.toTypedArray() } 126 awbRegions?.let { map[CaptureRequest.CONTROL_AWB_REGIONS] = it.toTypedArray() } 127 aeLock?.let { map[CaptureRequest.CONTROL_AE_LOCK] = it } 128 awbLock?.let { map[CaptureRequest.CONTROL_AWB_LOCK] = it } 129 } 130 } 131 } 132