Implement stopRepeating() support and port current camera2 logic
This CL includes several changes meant to align CameraPipe's extensions
implementation with the camera-camera2's implementation. These include:
- Pass the original SessionConfig (not the updated one from
SessionProcessor.initSession) down the stack.
- When setting the session configuration options, build a combined
SessionConfig with setting updates such as zoom to SessionProcessor
and RequestProcessor.
- Implement stopRepeating() by looking at the original SessionConfig,
same as what camera-camera2 does.
- Add a state system in RequestProcessor such that it handles image
capture requests before the capture session is started.
Bug: 320776624
Test: IamgeCaptureTest
Change-Id: Ic215d717c47d9871cd6ca64b298514783ca84537
diff --git a/camera/camera-camera2-pipe-integration/src/androidTest/java/androidx/camera/camera2/pipe/testing/TestUseCaseCamera.kt b/camera/camera-camera2-pipe-integration/src/androidTest/java/androidx/camera/camera2/pipe/testing/TestUseCaseCamera.kt
index dea04ab..da840e51 100644
--- a/camera/camera-camera2-pipe-integration/src/androidTest/java/androidx/camera/camera2/pipe/testing/TestUseCaseCamera.kt
+++ b/camera/camera-camera2-pipe-integration/src/androidTest/java/androidx/camera/camera2/pipe/testing/TestUseCaseCamera.kt
@@ -149,6 +149,7 @@
streams = useCaseCameraGraphConfig.getStreamIdsFromSurfaces(
sessionConfig.repeatingCaptureConfig.surfaces
),
+ sessionConfig = sessionConfig,
)
}
}
diff --git a/camera/camera-camera2-pipe-integration/src/main/java/androidx/camera/camera2/pipe/integration/adapter/RequestProcessorAdapter.kt b/camera/camera-camera2-pipe-integration/src/main/java/androidx/camera/camera2/pipe/integration/adapter/RequestProcessorAdapter.kt
index 86eda1a..8278652 100644
--- a/camera/camera-camera2-pipe-integration/src/main/java/androidx/camera/camera2/pipe/integration/adapter/RequestProcessorAdapter.kt
+++ b/camera/camera-camera2-pipe-integration/src/main/java/androidx/camera/camera2/pipe/integration/adapter/RequestProcessorAdapter.kt
@@ -44,12 +44,12 @@
@RequiresApi(Build.VERSION_CODES.LOLLIPOP)
class RequestProcessorAdapter(
private val useCaseGraphConfig: UseCaseGraphConfig,
- private val sessionConfig: SessionConfig?,
private val processorSurfaces: List<SessionProcessorSurface>,
private val scope: CoroutineScope,
) : RequestProcessor {
private val coroutineMutex = CoroutineMutex()
private val sequenceIds = atomic(0)
+ internal var sessionConfig: SessionConfig? = null
private class RequestProcessorCallbackAdapter(
private val callback: RequestProcessor.Callback,
diff --git a/camera/camera-camera2-pipe-integration/src/main/java/androidx/camera/camera2/pipe/integration/impl/SessionProcessorManager.kt b/camera/camera-camera2-pipe-integration/src/main/java/androidx/camera/camera2/pipe/integration/impl/SessionProcessorManager.kt
index 7ec7ec5..9e7daeb 100644
--- a/camera/camera-camera2-pipe-integration/src/main/java/androidx/camera/camera2/pipe/integration/impl/SessionProcessorManager.kt
+++ b/camera/camera-camera2-pipe-integration/src/main/java/androidx/camera/camera2/pipe/integration/impl/SessionProcessorManager.kt
@@ -20,10 +20,12 @@
import android.hardware.camera2.CaptureRequest
import android.os.Build
import android.view.Surface
+import androidx.annotation.GuardedBy
import androidx.annotation.RequiresApi
import androidx.camera.camera2.pipe.CameraStream
import androidx.camera.camera2.pipe.compat.CameraPipeKeys
import androidx.camera.camera2.pipe.core.Log
+import androidx.camera.camera2.pipe.integration.adapter.RequestProcessorAdapter
import androidx.camera.camera2.pipe.integration.adapter.SessionConfigAdapter
import androidx.camera.camera2.pipe.integration.interop.CaptureRequestOptions
import androidx.camera.camera2.pipe.integration.interop.ExperimentalCamera2Interop
@@ -37,7 +39,6 @@
import androidx.camera.core.impl.DeferrableSurfaces
import androidx.camera.core.impl.OutputSurface
import androidx.camera.core.impl.OutputSurfaceConfiguration
-import androidx.camera.core.impl.RequestProcessor
import androidx.camera.core.impl.SessionConfig
import androidx.camera.core.impl.SessionProcessor
import androidx.camera.core.impl.SessionProcessor.CaptureCallback
@@ -57,11 +58,32 @@
private val cameraInfoInternal: CameraInfoInternal,
private val scope: CoroutineScope,
) {
+ private val lock = Any()
+
+ @GuardedBy("lock")
+ private var captureSessionStarted = false
+
+ @GuardedBy("lock")
private var sessionOptions = CaptureRequestOptions.Builder().build()
+
+ @GuardedBy("lock")
private var stillCaptureOptions = CaptureRequestOptions.Builder().build()
+
+ @GuardedBy("lock")
+ private var requestProcessor: RequestProcessorAdapter? = null
+
+ @GuardedBy("lock")
+ private var pendingCaptureConfigs: List<CaptureConfig>? = null
+
+ @GuardedBy("lock")
+ private var pendingCaptureCallbacks: List<CaptureCallback>? = null
+
+ @GuardedBy("lock")
internal var sessionConfig: SessionConfig? = null
- set(value) {
+ set(value) = synchronized(lock) {
field = checkNotNull(value)
+ if (!captureSessionStarted) return
+ checkNotNull(requestProcessor).sessionConfig = value
sessionOptions =
CaptureRequestOptions.Builder.from(value.implementationOptions).build()
updateOptions()
@@ -170,20 +192,56 @@
useCaseManager.tryResumeUseCaseManager(useCaseManagerConfig)
}
- internal fun onCaptureSessionStart(requestProcessor: RequestProcessor) {
+ internal fun onCaptureSessionStart(requestProcessor: RequestProcessorAdapter) {
+ var captureConfigsToIssue: List<CaptureConfig>?
+ var captureCallbacksToIssue: List<CaptureCallback>?
+ synchronized(lock) {
+ check(!captureSessionStarted)
+ requestProcessor.sessionConfig = sessionConfig
+ this.requestProcessor = requestProcessor
+ captureSessionStarted = true
+
+ captureConfigsToIssue = pendingCaptureConfigs
+ captureCallbacksToIssue = pendingCaptureCallbacks
+ pendingCaptureConfigs = null
+ pendingCaptureCallbacks = null
+ }
+ Log.debug { "Invoking SessionProcessor#onCaptureSessionStart" }
sessionProcessor.onCaptureSessionStart(requestProcessor)
startRepeating(object : CaptureCallback {})
+ captureConfigsToIssue?.let { captureConfigs ->
+ submitCaptureConfigs(captureConfigs, checkNotNull(captureCallbacksToIssue))
+ }
}
internal fun startRepeating(captureCallback: CaptureCallback) {
+ synchronized(lock) {
+ if (!captureSessionStarted) return
+ }
+ Log.debug { "Invoking SessionProcessor#startRepeating" }
sessionProcessor.startRepeating(captureCallback)
}
+ internal fun stopRepeating() {
+ synchronized(lock) {
+ if (!captureSessionStarted) return
+ }
+ Log.debug { "Invoking SessionProcessor#stopRepeating" }
+ sessionProcessor.stopRepeating()
+ }
+
internal fun submitCaptureConfigs(
captureConfigs: List<CaptureConfig>,
captureCallbacks: List<CaptureCallback>,
) {
check(captureConfigs.size == captureCallbacks.size)
+ synchronized(lock) {
+ if (!captureSessionStarted) {
+ pendingCaptureConfigs = captureConfigs
+ pendingCaptureCallbacks = captureCallbacks
+ return
+ }
+ }
for ((config, callback) in captureConfigs.zip(captureCallbacks)) {
if (config.templateType == CameraDevice.TEMPLATE_STILL_CAPTURE) {
val builder = CaptureRequestOptions.Builder.from(config.implementationOptions)
@@ -204,8 +262,10 @@
)!!.toByte()
)
}
- stillCaptureOptions = builder.build()
- updateOptions()
+ synchronized(lock) {
+ stillCaptureOptions = builder.build()
+ updateOptions()
+ }
Log.debug { "Invoking SessionProcessor.startCapture()" }
sessionProcessor.startCapture(config.isPostviewEnabled, callback)
} else {
diff --git a/camera/camera-camera2-pipe-integration/src/main/java/androidx/camera/camera2/pipe/integration/impl/UseCaseCamera.kt b/camera/camera-camera2-pipe-integration/src/main/java/androidx/camera/camera2/pipe/integration/impl/UseCaseCamera.kt
index d43c348..bd284dd 100644
--- a/camera/camera-camera2-pipe-integration/src/main/java/androidx/camera/camera2/pipe/integration/impl/UseCaseCamera.kt
+++ b/camera/camera-camera2-pipe-integration/src/main/java/androidx/camera/camera2/pipe/integration/impl/UseCaseCamera.kt
@@ -104,13 +104,6 @@
set(value) {
field = value
- if (sessionProcessorManager != null) {
- sessionConfigAdapter.getValidSessionConfigOrNull()?.let {
- requestControl.setSessionConfigAsync(it)
- }
- return
- }
-
// Note: This may be called with the same set of values that was previously set. This
// is used as a signal to indicate the properties of the UseCase may have changed.
SessionConfigAdapter(value).getValidSessionConfigOrNull()?.let {
@@ -158,7 +151,6 @@
}
val requestProcessorAdapter = RequestProcessorAdapter(
useCaseGraphConfig,
- sessionConfigAdapter.getValidSessionConfigOrNull(),
sessionProcessorSurfaces,
threads.scope,
)
@@ -225,6 +217,7 @@
streams = useCaseGraphConfig.getStreamIdsFromSurfaces(
sessionConfig.repeatingCaptureConfig.surfaces
),
+ sessionConfig = sessionConfig,
)
} ?: canceledResult
diff --git a/camera/camera-camera2-pipe-integration/src/main/java/androidx/camera/camera2/pipe/integration/impl/UseCaseCameraRequestControl.kt b/camera/camera-camera2-pipe-integration/src/main/java/androidx/camera/camera2/pipe/integration/impl/UseCaseCameraRequestControl.kt
index a0c8e87..abe5af1 100644
--- a/camera/camera-camera2-pipe-integration/src/main/java/androidx/camera/camera2/pipe/integration/impl/UseCaseCameraRequestControl.kt
+++ b/camera/camera-camera2-pipe-integration/src/main/java/androidx/camera/camera2/pipe/integration/impl/UseCaseCameraRequestControl.kt
@@ -41,6 +41,7 @@
import androidx.camera.core.impl.CaptureConfig.TEMPLATE_TYPE_NONE
import androidx.camera.core.impl.Config
import androidx.camera.core.impl.MutableTagBundle
+import androidx.camera.core.impl.SessionConfig
import androidx.camera.core.impl.TagBundle
import dagger.Binds
import dagger.Module
@@ -125,7 +126,8 @@
tags: Map<String, Any> = emptyMap(),
streams: Set<StreamId>? = null,
template: RequestTemplate? = null,
- listeners: Set<Request.Listener> = emptySet()
+ listeners: Set<Request.Listener> = emptySet(),
+ sessionConfig: SessionConfig? = null,
): Deferred<Unit>
// 3A
@@ -200,7 +202,8 @@
tags: Map<String, Any>,
streams: Set<StreamId>?,
template: RequestTemplate?,
- listeners: Set<Request.Listener>
+ listeners: Set<Request.Listener>,
+ sessionConfig: SessionConfig?,
): Deferred<Unit> = runIfNotClosed {
synchronized(lock) {
debug { "[$type] Set config: ${config?.toParameters()}" }
@@ -217,6 +220,7 @@
infoBundleMap.merge()
}.updateCameraStateAsync(
streams = streams,
+ sessionConfig = sessionConfig,
)
} ?: canceledResult
@@ -352,7 +356,10 @@
}
}
- private fun InfoBundle.updateCameraStateAsync(streams: Set<StreamId>? = null): Deferred<Unit> =
+ private fun InfoBundle.updateCameraStateAsync(
+ streams: Set<StreamId>? = null,
+ sessionConfig: SessionConfig? = null,
+ ): Deferred<Unit> =
runIfNotClosed {
capturePipeline.template =
if (template != null && template!!.value != TEMPLATE_TYPE_NONE) {
@@ -369,6 +376,7 @@
streams = streams,
template = template,
listeners = listeners,
+ sessionConfig = sessionConfig,
)
} ?: canceledResult
diff --git a/camera/camera-camera2-pipe-integration/src/main/java/androidx/camera/camera2/pipe/integration/impl/UseCaseCameraState.kt b/camera/camera-camera2-pipe-integration/src/main/java/androidx/camera/camera2/pipe/integration/impl/UseCaseCameraState.kt
index 0737345..2fe0e04 100644
--- a/camera/camera-camera2-pipe-integration/src/main/java/androidx/camera/camera2/pipe/integration/impl/UseCaseCameraState.kt
+++ b/camera/camera-camera2-pipe-integration/src/main/java/androidx/camera/camera2/pipe/integration/impl/UseCaseCameraState.kt
@@ -36,9 +36,11 @@
import androidx.camera.camera2.pipe.core.Log
import androidx.camera.camera2.pipe.integration.config.UseCaseCameraScope
import androidx.camera.camera2.pipe.integration.config.UseCaseGraphConfig
+import androidx.camera.core.Preview
import androidx.camera.core.impl.SessionConfig
import androidx.camera.core.impl.SessionProcessor.CaptureCallback
import androidx.camera.core.impl.TagBundle
+import androidx.camera.core.streamsharing.StreamSharing
import javax.inject.Inject
import kotlinx.atomicfu.atomic
import kotlinx.coroutines.CancellationException
@@ -96,6 +98,9 @@
@GuardedBy("lock")
private var currentTemplate: RequestTemplate? = null
+ @GuardedBy("lock")
+ private var currentSessionConfig: SessionConfig? = null
+
private val requestListener = RequestListener()
/**
@@ -119,6 +124,7 @@
streams: Set<StreamId>? = null,
template: RequestTemplate? = null,
listeners: Set<Request.Listener>? = null,
+ sessionConfig: SessionConfig? = null,
): Deferred<Unit> {
val result: Deferred<Unit>
synchronized(lock) {
@@ -139,7 +145,7 @@
updateState(
parameters, appendParameters, internalParameters,
appendInternalParameters, streams, template,
- listeners
+ listeners, sessionConfig
)
if (updateSignal == null) {
@@ -198,7 +204,8 @@
appendInternalParameters: Boolean = true,
streams: Set<StreamId>? = null,
template: RequestTemplate? = null,
- listeners: Set<Request.Listener>? = null
+ listeners: Set<Request.Listener>? = null,
+ sessionConfig: SessionConfig? = null,
) {
// TODO: Consider if this should detect changes and only invoke an update if state has
// actually changed.
@@ -226,6 +233,9 @@
currentListeners.clear()
currentListeners.addAll(listeners)
}
+ if (sessionConfig != null) {
+ currentSessionConfig = sessionConfig
+ }
}
/**
@@ -235,6 +245,11 @@
fun tryStartRepeating() = submitLatest()
private fun submitLatest() {
+ if (sessionProcessorManager != null) {
+ submitLatestWithSessionProcessor()
+ return
+ }
+
// Update the cameraGraph with the most recent set of values.
// Since acquireSession is a suspending function, it's possible that subsequent updates
// can occur while waiting for the acquireSession call to complete. If this happens,
@@ -242,7 +257,6 @@
// synchronously with the latest values. The startRepeating/stopRepeating call happens
// outside of the synchronized block to avoid holding a lock while updating the camera
// state.
-
threads.scope.launch(start = CoroutineStart.UNDISPATCHED) {
val result: CompletableDeferred<Unit>?
val request: Request?
@@ -285,26 +299,7 @@
}
}
Log.debug { "Update RepeatingRequest: $request" }
- if (sessionProcessorManager != null) {
- val sessionConfig = SessionConfig.Builder().apply {
- request.template?.let { setTemplateType(it.value) }
- setImplementationOptions(Camera2ImplConfig.Builder().apply {
- for ((key, value) in request.parameters) {
- setCaptureRequestOptionWithType(key, value)
- }
- }.build())
- currentInternalParameters[CAMERAX_TAG_BUNDLE]?.let {
- val tagBundleMap = (it as TagBundle).toMap()
- for ((tag, value) in tagBundleMap) {
- addTag(tag, value)
- }
- }
- }.build()
- sessionProcessorManager.sessionConfig = sessionConfig
- sessionProcessorManager.startRepeating(object : CaptureCallback {})
- } else {
- it.startRepeating(request)
- }
+ it.startRepeating(request)
it.update3A(request.parameters)
}
}
@@ -320,6 +315,52 @@
}
}
+ private fun submitLatestWithSessionProcessor() {
+ checkNotNull(sessionProcessorManager)
+ synchronized(lock) {
+ updating = false
+ val signal = updateSignal
+ updateSignal = null
+
+ if (currentSessionConfig == null) {
+ signal?.complete(Unit)
+ return
+ }
+
+ // Here we're intentionally building a new SessionConfig. Various request parameters,
+ // such as zoom or 3A are directly translated to corresponding CameraPipe types and
+ // APIs. As such, we need to build a new, "combined" SessionConfig that has these
+ // updated request parameters set. Otherwise, certain settings like zoom would be
+ // disregarded.
+ SessionConfig.Builder().apply {
+ currentTemplate?.let { setTemplateType(it.value) }
+ setImplementationOptions(Camera2ImplConfig.Builder().apply {
+ for ((key, value) in currentParameters) {
+ setCaptureRequestOptionWithType(key, value)
+ }
+ }.build())
+ currentInternalParameters[CAMERAX_TAG_BUNDLE]?.let {
+ val tagBundleMap = (it as TagBundle).toMap()
+ for ((tag, value) in tagBundleMap) {
+ addTag(tag, value)
+ }
+ }
+ }.build().also { sessionConfig ->
+ sessionProcessorManager.sessionConfig = sessionConfig
+ }
+
+ if (currentSessionConfig!!.repeatingCaptureConfig.surfaces.any {
+ it.containerClass == Preview::class.java ||
+ it.containerClass == StreamSharing::class.java
+ }) {
+ sessionProcessorManager.startRepeating(object : CaptureCallback {})
+ } else {
+ sessionProcessorManager.stopRepeating()
+ }
+ signal?.complete(Unit)
+ }
+ }
+
private fun CameraGraph.Session.update3A(parameters: Map<CaptureRequest.Key<*>, Any>?) {
val aeMode = parameters.getIntOrNull(CaptureRequest.CONTROL_AE_MODE)?.let {
AeMode.fromIntOrNull(it)
diff --git a/camera/camera-camera2-pipe-integration/src/main/java/androidx/camera/camera2/pipe/integration/impl/UseCaseManager.kt b/camera/camera-camera2-pipe-integration/src/main/java/androidx/camera/camera2/pipe/integration/impl/UseCaseManager.kt
index f8c2a8e..1cc2d4a5 100644
--- a/camera/camera-camera2-pipe-integration/src/main/java/androidx/camera/camera2/pipe/integration/impl/UseCaseManager.kt
+++ b/camera/camera-camera2-pipe-integration/src/main/java/androidx/camera/camera2/pipe/integration/impl/UseCaseManager.kt
@@ -123,14 +123,6 @@
}
set(value) = synchronized(lock) {
field = value
- // Only create the SessionProcessorManager when we have a SessionProcessor set.
- if (field != null) {
- sessionProcessorManager = SessionProcessorManager(
- field!!,
- cameraInfoInternal.get(),
- useCaseThreads.get().scope
- )
- }
}
@GuardedBy("lock")
@@ -349,7 +341,13 @@
if (sessionProcessor != null) {
Log.debug { "Setting up UseCaseManager with SessionProcessorManager" }
- checkNotNull(sessionProcessorManager).initialize(this, useCases)
+ sessionProcessorManager = SessionProcessorManager(
+ sessionProcessor!!,
+ cameraInfoInternal.get(),
+ useCaseThreads.get().scope,
+ ).also {
+ it.initialize(this, useCases)
+ }
return
} else {
val sessionConfigAdapter = SessionConfigAdapter(useCases)
@@ -388,13 +386,7 @@
val sessionProcessorEnabled =
useCaseManagerConfig.sessionConfigAdapter.isSessionProcessorEnabled
with(useCaseManagerConfig) {
- var sessionProcessorManager: SessionProcessorManager? = null
if (sessionProcessorEnabled) {
- sessionProcessorManager = SessionProcessorManager(
- checkNotNull(sessionProcessor),
- cameraInfoInternal.get(),
- useCaseThreads.get().scope,
- )
for ((streamConfig, deferrableSurface) in streamConfigMap) {
cameraGraph.streams[streamConfig]?.let {
cameraGraph.setSurface(it.id, deferrableSurface.surface.get())
diff --git a/camera/camera-camera2-pipe-integration/src/test/java/androidx/camera/camera2/pipe/integration/adapter/RequestProcessorAdapterTest.kt b/camera/camera-camera2-pipe-integration/src/test/java/androidx/camera/camera2/pipe/integration/adapter/RequestProcessorAdapterTest.kt
index 4b86a82..bde75b0 100644
--- a/camera/camera-camera2-pipe-integration/src/test/java/androidx/camera/camera2/pipe/integration/adapter/RequestProcessorAdapterTest.kt
+++ b/camera/camera-camera2-pipe-integration/src/test/java/androidx/camera/camera2/pipe/integration/adapter/RequestProcessorAdapterTest.kt
@@ -132,10 +132,11 @@
requestProcessorAdapter = RequestProcessorAdapter(
useCaseGraphConfig,
- fakeSessionConfig,
sessionProcessorSurfaces,
scope,
- )
+ ).apply {
+ sessionConfig = fakeSessionConfig
+ }
scope.advanceUntilIdle()
}
diff --git a/camera/camera-camera2-pipe-integration/src/test/java/androidx/camera/camera2/pipe/integration/impl/SessionProcessorManagerTest.kt b/camera/camera-camera2-pipe-integration/src/test/java/androidx/camera/camera2/pipe/integration/impl/SessionProcessorManagerTest.kt
index 1e506bc..db12111 100644
--- a/camera/camera-camera2-pipe-integration/src/test/java/androidx/camera/camera2/pipe/integration/impl/SessionProcessorManagerTest.kt
+++ b/camera/camera-camera2-pipe-integration/src/test/java/androidx/camera/camera2/pipe/integration/impl/SessionProcessorManagerTest.kt
@@ -23,6 +23,7 @@
import androidx.camera.camera2.pipe.CameraId
import androidx.camera.camera2.pipe.core.Log
import androidx.camera.camera2.pipe.integration.adapter.FakeTestUseCase
+import androidx.camera.camera2.pipe.integration.adapter.RequestProcessorAdapter
import androidx.camera.camera2.pipe.integration.adapter.RobolectricCameraPipeTestRunner
import androidx.camera.camera2.pipe.integration.adapter.TestDeferrableSurface
import androidx.camera.camera2.pipe.integration.interop.CaptureRequestOptions
@@ -120,7 +121,7 @@
}
override fun onCaptureSessionStart(requestProcessor: RequestProcessor) {
- TODO("Not yet implemented")
+ Log.debug { "$this#onCaptureSessionStart" }
}
override fun onCaptureSessionEnd() {
@@ -128,11 +129,12 @@
}
override fun startRepeating(callback: CaptureCallback): Int {
- TODO("Not yet implemented")
+ Log.debug { "$this#startRepeating" }
+ return 0
}
override fun stopRepeating() {
- TODO("Not yet implemented")
+ Log.debug { "$this#stopRepeating" }
}
override fun startCapture(
@@ -229,6 +231,9 @@
).join()
sessionProcessorManager.sessionConfig = SessionConfig.Builder().build()
+ val mockRequestProcessorAdapter: RequestProcessorAdapter = mock()
+ sessionProcessorManager.onCaptureSessionStart(mockRequestProcessorAdapter)
+
val jpegRotation = 90
val jpegQuality = 95
val captureConfig = CaptureConfig.Builder().apply {
diff --git a/camera/camera-camera2-pipe-integration/src/test/java/androidx/camera/camera2/pipe/integration/testing/FakeUseCaseCamera.kt b/camera/camera-camera2-pipe-integration/src/test/java/androidx/camera/camera2/pipe/integration/testing/FakeUseCaseCamera.kt
index 3f60f25..bb21a18 100644
--- a/camera/camera-camera2-pipe-integration/src/test/java/androidx/camera/camera2/pipe/integration/testing/FakeUseCaseCamera.kt
+++ b/camera/camera-camera2-pipe-integration/src/test/java/androidx/camera/camera2/pipe/integration/testing/FakeUseCaseCamera.kt
@@ -40,6 +40,7 @@
import androidx.camera.core.impl.CaptureConfig
import androidx.camera.core.impl.Config
import androidx.camera.core.impl.DeferrableSurface
+import androidx.camera.core.impl.SessionConfig
import java.util.concurrent.TimeUnit
import kotlinx.coroutines.CompletableDeferred
import kotlinx.coroutines.Deferred
@@ -110,7 +111,8 @@
tags: Map<String, Any>,
streams: Set<StreamId>?,
template: RequestTemplate?,
- listeners: Set<Request.Listener>
+ listeners: Set<Request.Listener>,
+ sessionConfig: SessionConfig?,
): Deferred<Unit> {
setConfigCalls.add(RequestParameters(type, config, tags))
return CompletableDeferred(Unit)