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.params.MeteringRectangle 20 import androidx.camera.camera2.pipe.AeMode 21 import androidx.camera.camera2.pipe.AfMode 22 import androidx.camera.camera2.pipe.AwbMode 23 import androidx.camera.camera2.pipe.CameraGraph 24 import androidx.camera.camera2.pipe.FrameCapture 25 import androidx.camera.camera2.pipe.FrameMetadata 26 import androidx.camera.camera2.pipe.Lock3ABehavior 27 import androidx.camera.camera2.pipe.Request 28 import androidx.camera.camera2.pipe.Result3A 29 import androidx.camera.camera2.pipe.core.Token 30 import androidx.camera.camera2.pipe.internal.CameraGraphParametersImpl 31 import androidx.camera.camera2.pipe.internal.FrameCaptureQueue 32 import kotlinx.atomicfu.atomic 33 import kotlinx.coroutines.Deferred 34 35 internal val cameraGraphSessionIds = atomic(0) 36 37 internal class CameraGraphSessionImpl( 38 private val token: Token, 39 private val graphProcessor: GraphProcessor, 40 private val controller3A: Controller3A, 41 private val frameCaptureQueue: FrameCaptureQueue, 42 private val parameters: CameraGraphParametersImpl 43 ) : CameraGraph.Session { 44 private val debugId = cameraGraphSessionIds.incrementAndGet() 45 submitnull46 override fun submit(request: Request) { 47 check(!token.released) { "Cannot call submit on $this after close." } 48 graphProcessor.submit(request) 49 } 50 submitnull51 override fun submit(requests: List<Request>) { 52 check(!token.released) { "Cannot call submit on $this after close." } 53 check(requests.isNotEmpty()) { "Cannot call submit with an empty list of Requests!" } 54 graphProcessor.submit(requests) 55 } 56 capturenull57 override fun capture(request: Request): FrameCapture { 58 val frameCapture = frameCaptureQueue.enqueue(request) 59 submit(request) 60 return frameCapture 61 } 62 capturenull63 override fun capture(requests: List<Request>): List<FrameCapture> { 64 val frameCaptures = frameCaptureQueue.enqueue(requests) 65 submit(requests) 66 return frameCaptures 67 } 68 startRepeatingnull69 override fun startRepeating(request: Request) { 70 check(!token.released) { "Cannot call startRepeating on $this after close." } 71 graphProcessor.repeatingRequest = request 72 } 73 abortnull74 override fun abort() { 75 check(!token.released) { "Cannot call abort on $this after close." } 76 graphProcessor.abort() 77 } 78 stopRepeatingnull79 override fun stopRepeating() { 80 check(!token.released) { "Cannot call stopRepeating on $this after close." } 81 graphProcessor.repeatingRequest = null 82 } 83 closenull84 override fun close() { 85 val unappliedParameters = parameters.fetchUpdatedParameters() 86 if (unappliedParameters != null) { 87 graphProcessor.updateGraphParameters(unappliedParameters) 88 } 89 token.release() 90 } 91 update3Anull92 override fun update3A( 93 aeMode: AeMode?, 94 afMode: AfMode?, 95 awbMode: AwbMode?, 96 aeRegions: List<MeteringRectangle>?, 97 afRegions: List<MeteringRectangle>?, 98 awbRegions: List<MeteringRectangle>? 99 ): Deferred<Result3A> { 100 check(!token.released) { "Cannot call update3A on $this after close." } 101 return controller3A.update3A( 102 aeMode = aeMode, 103 afMode = afMode, 104 awbMode = awbMode, 105 aeRegions = aeRegions, 106 afRegions = afRegions, 107 awbRegions = awbRegions 108 ) 109 } 110 submit3Anull111 override suspend fun submit3A( 112 aeMode: AeMode?, 113 afMode: AfMode?, 114 awbMode: AwbMode?, 115 aeRegions: List<MeteringRectangle>?, 116 afRegions: List<MeteringRectangle>?, 117 awbRegions: List<MeteringRectangle>? 118 ): Deferred<Result3A> { 119 check(!token.released) { "Cannot call submit3A on $this after close." } 120 return controller3A.submit3A(aeMode, afMode, awbMode, aeRegions, afRegions, awbRegions) 121 } 122 setTorchOnnull123 override fun setTorchOn(): Deferred<Result3A> { 124 check(!token.released) { "Cannot call setTorchOn on $this after close." } 125 // TODO(sushilnath): First check whether the camera device has a flash unit. Ref: 126 // https://developer.android.com/reference/android/hardware/camera2/CameraCharacteristics#FLASH_INFO_AVAILABLE 127 return controller3A.setTorchOn() 128 } 129 setTorchOffnull130 override fun setTorchOff(aeMode: AeMode?): Deferred<Result3A> { 131 check(!token.released) { "Cannot call setTorchOff on $this after close." } 132 return controller3A.setTorchOff(aeMode) 133 } 134 lock3Anull135 override suspend fun lock3A( 136 aeMode: AeMode?, 137 afMode: AfMode?, 138 awbMode: AwbMode?, 139 aeRegions: List<MeteringRectangle>?, 140 afRegions: List<MeteringRectangle>?, 141 awbRegions: List<MeteringRectangle>?, 142 aeLockBehavior: Lock3ABehavior?, 143 afLockBehavior: Lock3ABehavior?, 144 awbLockBehavior: Lock3ABehavior?, 145 afTriggerStartAeMode: AeMode?, 146 convergedCondition: ((FrameMetadata) -> Boolean)?, 147 lockedCondition: ((FrameMetadata) -> Boolean)?, 148 frameLimit: Int, 149 convergedTimeLimitNs: Long, 150 lockedTimeLimitNs: Long 151 ): Deferred<Result3A> { 152 check(!token.released) { "Cannot call lock3A on $this after close." } 153 // TODO(sushilnath): check if the device or the current mode supports lock for each of 154 // ae, af and awb respectively. If not supported return an exception or return early with 155 // the right status code. 156 return controller3A.lock3A( 157 aeRegions, 158 afRegions, 159 awbRegions, 160 aeLockBehavior, 161 afLockBehavior, 162 awbLockBehavior, 163 afTriggerStartAeMode, 164 convergedCondition, 165 lockedCondition, 166 frameLimit, 167 convergedTimeLimitNs, 168 lockedTimeLimitNs 169 ) 170 } 171 unlock3Anull172 override suspend fun unlock3A( 173 ae: Boolean?, 174 af: Boolean?, 175 awb: Boolean?, 176 unlockedCondition: ((FrameMetadata) -> Boolean)?, 177 frameLimit: Int, 178 timeLimitNs: Long 179 ): Deferred<Result3A> { 180 check(!token.released) { "Cannot call unlock3A on $this after close." } 181 return controller3A.unlock3A(ae, af, awb, unlockedCondition, frameLimit, timeLimitNs) 182 } 183 lock3AForCapturenull184 override suspend fun lock3AForCapture( 185 lockedCondition: ((FrameMetadata) -> Boolean)?, 186 frameLimit: Int, 187 timeLimitNs: Long 188 ): Deferred<Result3A> { 189 check(!token.released) { "Cannot call lock3AForCapture on $this after close." } 190 return controller3A.lock3AForCapture(lockedCondition, frameLimit, timeLimitNs) 191 } 192 lock3AForCapturenull193 override suspend fun lock3AForCapture( 194 triggerAf: Boolean, 195 waitForAwb: Boolean, 196 frameLimit: Int, 197 timeLimitNs: Long 198 ): Deferred<Result3A> { 199 check(!token.released) { "Cannot call lock3AForCapture on $this after close." } 200 return controller3A.lock3AForCapture(triggerAf, waitForAwb, frameLimit, timeLimitNs) 201 } 202 unlock3APostCapturenull203 override suspend fun unlock3APostCapture(cancelAf: Boolean): Deferred<Result3A> { 204 check(!token.released) { "Cannot call unlock3APostCapture on $this after close." } 205 return controller3A.unlock3APostCapture(cancelAf) 206 } 207 toStringnull208 override fun toString(): String = "CameraGraph.Session-$debugId" 209 } 210