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 package androidx.camera.camera2.pipe.integration.interop 17 18 import android.hardware.camera2.CaptureRequest 19 import androidx.annotation.RestrictTo 20 import androidx.camera.camera2.pipe.integration.impl.CAPTURE_REQUEST_ID_STEM 21 import androidx.camera.camera2.pipe.integration.impl.createCaptureRequestOption 22 import androidx.camera.core.ExtendableBuilder 23 import androidx.camera.core.impl.Config 24 import androidx.camera.core.impl.MutableConfig 25 import androidx.camera.core.impl.MutableOptionsBundle 26 import androidx.camera.core.impl.OptionsBundle 27 import androidx.camera.core.impl.ReadableConfig 28 29 /** 30 * A bundle of Camera2 capture request options. 31 * 32 * @constructor Creates a CaptureRequestOptions for reading Camera2 capture request options from the 33 * given config. 34 * @property config The config that potentially contains Camera2 capture request options. 35 */ 36 @ExperimentalCamera2Interop 37 public open class CaptureRequestOptions 38 private constructor(private val config: Config, @Suppress("UNUSED_PARAMETER") unused: Boolean) : 39 ReadableConfig { 40 41 internal constructor(config: Config) : this(config, false) 42 43 /** 44 * Returns a value for the given [CaptureRequest.Key] or null if it hasn't been set. 45 * 46 * @param key The key to retrieve. 47 * @param ValueT The type of the value. 48 * @return The stored value or null if the value does not exist in this configuration. 49 */ getCaptureRequestOptionnull50 public open fun <ValueT> getCaptureRequestOption(key: CaptureRequest.Key<ValueT>): ValueT? { 51 // Type should have been only set via Builder#setCaptureRequestOption() 52 @Suppress("UNCHECKED_CAST") 53 val opt = key.createCaptureRequestOption() as Config.Option<ValueT> 54 return config.retrieveOption(opt, null) 55 } 56 57 /** 58 * Returns a value for the given [CaptureRequest.Key]. 59 * 60 * @param key The key to retrieve. 61 * @param valueIfMissing The value to return if this configuration option has not been set. 62 * @param ValueT The type of the value. 63 * @return The stored value or `valueIfMissing` if the value does not exist in this 64 * configuration. 65 */ getCaptureRequestOptionnull66 internal fun <ValueT> getCaptureRequestOption( 67 key: CaptureRequest.Key<ValueT>, 68 valueIfMissing: ValueT? 69 ): ValueT? { 70 // Type should have been only set via Builder#setCaptureRequestOption() 71 @Suppress("UNCHECKED_CAST") 72 val opt = key.createCaptureRequestOption() as Config.Option<ValueT> 73 return config.retrieveOption(opt, valueIfMissing) 74 } 75 76 /** Returns the [Config] object associated with this [CaptureRequestOptions]. */ 77 @RestrictTo(RestrictTo.Scope.LIBRARY) getConfignull78 override fun getConfig(): Config { 79 return config 80 } 81 82 /** Builder for creating [CaptureRequestOptions] instance. */ 83 public class Builder : ExtendableBuilder<CaptureRequestOptions?> { 84 private val mutableOptionsBundle = MutableOptionsBundle.create() 85 86 public companion object { 87 /** 88 * Generates a Builder from another Config object. 89 * 90 * @param config An immutable configuration to pre-populate this builder. 91 * @return The new Builder. 92 */ 93 @JvmStatic 94 @RestrictTo(RestrictTo.Scope.LIBRARY) fromnull95 public fun from(config: Config): Builder { 96 val bundleBuilder = Builder() 97 config.findOptions(CAPTURE_REQUEST_ID_STEM) { 98 // Erase the type of the option. Capture request options should only be 99 // set via Camera2Interop so that the type of the key and value should 100 // always match. 101 @Suppress("UNCHECKED_CAST") val objectOpt = it as Config.Option<Any> 102 bundleBuilder.mutableConfig.insertOption( 103 objectOpt, 104 config.getOptionPriority(objectOpt), 105 config.retrieveOption(objectOpt) 106 ) 107 true 108 } 109 return bundleBuilder 110 } 111 } 112 113 /** {@inheritDoc} */ 114 @RestrictTo(RestrictTo.Scope.LIBRARY) getMutableConfignull115 override fun getMutableConfig(): MutableConfig { 116 return mutableOptionsBundle 117 } 118 119 /** Inserts new capture request option with specific [CaptureRequest.Key] setting. */ setCaptureRequestOptionnull120 public fun <ValueT> setCaptureRequestOption( 121 key: CaptureRequest.Key<ValueT>, 122 value: ValueT 123 ): Builder { 124 val opt = key.createCaptureRequestOption() 125 mutableOptionsBundle.insertOption(opt, value) 126 return this 127 } 128 129 /** Removes a capture request option with specific [CaptureRequest.Key] setting. */ clearCaptureRequestOptionnull130 public fun <ValueT> clearCaptureRequestOption(key: CaptureRequest.Key<ValueT>): Builder { 131 val opt = key.createCaptureRequestOption() 132 mutableOptionsBundle.removeOption(opt) 133 return this 134 } 135 136 /** 137 * Builds an immutable [CaptureRequestOptions] from the current state. 138 * 139 * @return A [CaptureRequestOptions] populated with the current state. 140 */ buildnull141 override fun build(): CaptureRequestOptions { 142 return CaptureRequestOptions(OptionsBundle.from(mutableOptionsBundle)) 143 } 144 } 145 } 146