1 /*
<lambda>null2  * Copyright 2022 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.testing
18 
19 import android.hardware.camera2.CaptureRequest
20 import android.view.Surface
21 import androidx.camera.camera2.pipe.CameraId
22 import androidx.camera.camera2.pipe.CaptureSequence
23 import androidx.camera.camera2.pipe.CaptureSequences.invokeOnRequests
24 import androidx.camera.camera2.pipe.FrameNumber
25 import androidx.camera.camera2.pipe.Metadata
26 import androidx.camera.camera2.pipe.Request
27 import androidx.camera.camera2.pipe.RequestMetadata
28 import androidx.camera.camera2.pipe.RequestNumber
29 import androidx.camera.camera2.pipe.RequestTemplate
30 import androidx.camera.camera2.pipe.StreamId
31 import kotlinx.atomicfu.atomic
32 
33 /** A CaptureSequence used for testing interactions with a [FakeCaptureSequenceProcessor] */
34 public data class FakeCaptureSequence(
35     override val repeating: Boolean,
36     override val cameraId: CameraId,
37     override val captureRequestList: List<Request>,
38     override val captureMetadataList: List<RequestMetadata>,
39     val requestMetadata: Map<Request, RequestMetadata>,
40     val defaultParameters: Map<*, Any?>,
41     val requiredParameters: Map<*, Any?>,
42     val graphParameters: Map<*, Any?>,
43     override val listeners: List<Request.Listener>,
44     override val sequenceListener: CaptureSequence.CaptureSequenceListener,
45     override var sequenceNumber: Int,
46 ) : CaptureSequence<Request> {
47     public fun invokeOnSequenceCreated(): Unit = invokeOnRequests { requestMetadata, _, listener ->
48         listener.onRequestSequenceCreated(requestMetadata)
49     }
50 
51     public fun invokeOnSequenceSubmitted(): Unit =
52         invokeOnRequests { requestMetadata, _, listener ->
53             listener.onRequestSequenceSubmitted(requestMetadata)
54         }
55 
56     public fun invokeOnSequenceAborted(): Unit = invokeOnRequests { requestMetadata, _, listener ->
57         listener.onRequestSequenceAborted(requestMetadata)
58     }
59 
60     public fun invokeOnSequenceCompleted(frameNumber: FrameNumber): Unit =
61         invokeOnRequests { requestMetadata, _, listener ->
62             listener.onRequestSequenceCompleted(requestMetadata, frameNumber)
63         }
64 
65     public companion object {
66         private val requestNumbers = atomic(0L)
67         private val fakeCaptureSequenceListener = FakeCaptureSequenceListener()
68 
69         public fun create(
70             cameraId: CameraId,
71             repeating: Boolean,
72             requests: List<Request>,
73             surfaceMap: Map<StreamId, Surface>,
74             defaultTemplate: RequestTemplate = RequestTemplate(1),
75             defaultParameters: Map<*, Any?> = emptyMap<Any, Any?>(),
76             requiredParameters: Map<*, Any?> = emptyMap<Any, Any?>(),
77             graphParameters: Map<*, Any?> = emptyMap<Any, Any?>(),
78             listeners: List<Request.Listener> = emptyList(),
79             sequenceListener: CaptureSequence.CaptureSequenceListener = fakeCaptureSequenceListener
80         ): FakeCaptureSequence? {
81             if (surfaceMap.isEmpty()) {
82                 println(
83                     "No surfaces configured for $this! Cannot build CaptureSequence for $requests"
84                 )
85                 return null
86             }
87 
88             val requestInfoMap = mutableMapOf<Request, RequestMetadata>()
89             val requestInfoList = mutableListOf<RequestMetadata>()
90             for (request in requests) {
91                 val captureParameters = mutableMapOf<CaptureRequest.Key<*>, Any?>()
92                 val metadataParameters = mutableMapOf<Metadata.Key<*>, Any?>()
93                 for ((k, v) in defaultParameters) {
94                     if (k != null) {
95                         if (k is CaptureRequest.Key<*>) {
96                             captureParameters[k] = v
97                         } else if (k is Metadata.Key<*>) {
98                             metadataParameters[k] = v
99                         }
100                     }
101                 }
102                 for ((k, v) in graphParameters) {
103                     if (k is CaptureRequest.Key<*>) {
104                         captureParameters[k] = v
105                     } else if (k is Metadata.Key<*>) {
106                         metadataParameters[k] = v
107                     }
108                 }
109                 for ((k, v) in request.parameters) {
110                     captureParameters[k] = v
111                 }
112                 for ((k, v) in request.extras) {
113                     metadataParameters[k] = v
114                 }
115                 for ((k, v) in requiredParameters) {
116                     if (k != null) {
117                         if (k is CaptureRequest.Key<*>) {
118                             captureParameters[k] = v
119                         } else if (k is Metadata.Key<*>) {
120                             metadataParameters[k] = v
121                         }
122                     }
123                 }
124 
125                 val requestNumber = RequestNumber(requestNumbers.incrementAndGet())
126                 val streamMap = mutableMapOf<StreamId, Surface>()
127                 var hasSurface = false
128                 for (stream in request.streams) {
129                     val surface = surfaceMap[stream]
130                     if (surface == null) {
131                         println("Failed to find surface for $stream on $request")
132                         continue
133                     }
134                     hasSurface = true
135                     streamMap[stream] = surface
136                 }
137 
138                 if (!hasSurface) {
139                     println("No surfaces configured for $request! Cannot build CaptureSequence.")
140                     return null
141                 }
142 
143                 val requestMetadata =
144                     FakeRequestMetadata(
145                         request = request,
146                         requestParameters = captureParameters,
147                         metadata = metadataParameters,
148                         template = request.template ?: defaultTemplate,
149                         streams = streamMap,
150                         repeating = repeating,
151                         requestNumber = requestNumber
152                     )
153                 requestInfoList.add(requestMetadata)
154                 requestInfoMap[request] = requestMetadata
155             }
156 
157             // Copy maps / lists for tests.
158             return FakeCaptureSequence(
159                 repeating = repeating,
160                 cameraId = cameraId,
161                 captureRequestList = requests.toList(),
162                 captureMetadataList = requestInfoList,
163                 requestMetadata = requestInfoMap,
164                 defaultParameters = defaultParameters.toMap(),
165                 requiredParameters = requiredParameters.toMap(),
166                 graphParameters = graphParameters.toMap(),
167                 listeners = listeners.toList(),
168                 sequenceListener = sequenceListener,
169                 sequenceNumber = -1 // Sequence number is not set until it has been submitted.
170             )
171         }
172     }
173 }
174