1 /*
2  * Copyright 2024 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.internal
18 
19 import android.hardware.camera2.CaptureRequest
20 import androidx.annotation.GuardedBy
21 import androidx.camera.camera2.pipe.CameraGraph
22 import androidx.camera.camera2.pipe.Metadata
23 import androidx.camera.camera2.pipe.config.CameraGraphScope
24 import androidx.camera.camera2.pipe.config.ForCameraGraph
25 import androidx.camera.camera2.pipe.core.Log.warn
26 import androidx.camera.camera2.pipe.graph.GraphProcessor
27 import androidx.camera.camera2.pipe.graph.SessionLock
28 import javax.inject.Inject
29 import kotlinx.coroutines.CoroutineScope
30 
31 @CameraGraphScope
32 public class CameraGraphParametersImpl
33 @Inject
34 internal constructor(
35     private val sessionLock: SessionLock,
36     private val graphProcessor: GraphProcessor,
37     @ForCameraGraph private val graphScope: CoroutineScope
38 ) : CameraGraph.Parameters {
39     private val lock = Any()
40 
41     @GuardedBy("lock") private val parameters = mutableMapOf<Any, Any?>()
42 
43     /**
44      * Set to true when [parameters] is modified. Set to false when the modified [parameters] is
45      * fetched.
46      */
47     @GuardedBy("lock") private var dirty = false
48 
49     @Suppress("UNCHECKED_CAST")
getnull50     public override operator fun <T> get(key: CaptureRequest.Key<T>): T? =
51         synchronized(lock) { parameters[key] as T }
52 
53     @Suppress("UNCHECKED_CAST")
getnull54     public override operator fun <T> get(key: Metadata.Key<T>): T? =
55         synchronized(lock) { parameters[key] as T }
56 
setnull57     public override operator fun <T : Any> set(key: CaptureRequest.Key<T>, value: T?) {
58 
59         setAll(mapOf(key to value))
60     }
61 
setnull62     public override operator fun <T : Any> set(key: Metadata.Key<T>, value: T?) {
63         setAll(mapOf(key to value))
64     }
65 
setAllnull66     public override fun setAll(newParameters: Map<Any, Any?>) {
67         var invokeUpdate = false
68         synchronized(lock) {
69             var modified = false
70             for ((key, value) in newParameters.entries) {
71                 modified = modify(parameters, key, value) || modified
72             }
73             if (modified && !dirty) {
74                 dirty = true
75                 invokeUpdate = true
76             }
77         }
78         applyUpdate(invokeUpdate)
79     }
80 
modifynull81     private fun modify(map: MutableMap<Any, Any?>, key: Any, value: Any?): Boolean {
82         if (key !is CaptureRequest.Key<*> && key !is Metadata.Key<*>) {
83             warn {
84                 "Skipping set parameter (key=$key, value=$value). $key is not a valid parameter type."
85             }
86             return false
87         }
88         var modified = false
89         if (!map.containsKey(key)) {
90             modified = true
91         }
92         if (map[key] != value) {
93             modified = true
94         }
95         map[key] = value
96         return modified
97     }
98 
clearnull99     public override fun clear() {
100         var invokeUpdate = false
101         synchronized(lock) {
102             var modified = false
103             if (parameters.isNotEmpty()) {
104                 parameters.clear()
105                 modified = true
106             }
107             if (modified && !dirty) {
108                 dirty = true
109                 invokeUpdate = true
110             }
111         }
112         applyUpdate(invokeUpdate)
113     }
114 
removenull115     public override fun <T> remove(key: CaptureRequest.Key<T>): Boolean {
116         return removeAll(setOf(key))
117     }
118 
removenull119     public override fun <T> remove(key: Metadata.Key<T>): Boolean {
120         return removeAll(setOf(key))
121     }
122 
removeAllnull123     public override fun removeAll(keys: Set<*>): Boolean {
124         var invokeUpdate = false
125         var modified = false
126         synchronized(lock) {
127             for (key in keys) {
128                 if (parameters.containsKey(key)) {
129                     parameters.remove(key)
130                     modified = true
131                 }
132                 if (key !is CaptureRequest.Key<*> && key !is Metadata.Key<*>) {
133                     warn {
134                         "Skipping removing parameter with key $key. $key is not a valid parameter type."
135                     }
136                 }
137             }
138             if (modified && !dirty) {
139                 dirty = true
140                 invokeUpdate = true
141             }
142         }
143         applyUpdate(invokeUpdate)
144         return modified
145     }
146 
147     /**
148      * Return the latest parameters if the class stored parameters has changed since the last time
149      * this method is called. If there is no parameter changes, return null.
150      */
fetchUpdatedParametersnull151     public fun fetchUpdatedParameters(): Map<Any, Any?>? {
152         synchronized(lock) {
153             if (!dirty) return null
154 
155             dirty = false
156             return parameters
157         }
158     }
159 
applyUpdatenull160     private fun applyUpdate(update: Boolean) {
161         val unappliedParameters = fetchUpdatedParameters() ?: return
162         if (update) {
163             sessionLock.withTokenIn(graphScope) {
164                 graphProcessor.updateGraphParameters(unappliedParameters)
165             }
166         }
167     }
168 }
169