1 /* <lambda>null2 * Copyright 2020 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.integration.config 18 19 import androidx.camera.camera2.pipe.CameraGraph 20 import androidx.camera.camera2.pipe.CameraStream 21 import androidx.camera.camera2.pipe.StreamId 22 import androidx.camera.camera2.pipe.core.Log 23 import androidx.camera.camera2.pipe.integration.adapter.CameraStateAdapter 24 import androidx.camera.camera2.pipe.integration.adapter.SessionConfigAdapter 25 import androidx.camera.camera2.pipe.integration.compat.workaround.CapturePipelineTorchCorrection 26 import androidx.camera.camera2.pipe.integration.impl.CameraInteropStateCallbackRepository 27 import androidx.camera.camera2.pipe.integration.impl.CapturePipeline 28 import androidx.camera.camera2.pipe.integration.impl.CapturePipelineImpl 29 import androidx.camera.camera2.pipe.integration.impl.SessionProcessorManager 30 import androidx.camera.camera2.pipe.integration.impl.UseCaseCamera 31 import androidx.camera.camera2.pipe.integration.impl.UseCaseCameraImpl 32 import androidx.camera.camera2.pipe.integration.impl.UseCaseCameraRequestControlImpl 33 import androidx.camera.camera2.pipe.integration.impl.UseCaseSurfaceManager 34 import androidx.camera.core.UseCase 35 import androidx.camera.core.impl.DeferrableSurface 36 import dagger.Module 37 import dagger.Provides 38 import dagger.Subcomponent 39 import java.util.concurrent.CancellationException 40 import javax.inject.Scope 41 42 @Scope public annotation class UseCaseCameraScope 43 44 /** Dependency bindings for building a [UseCaseCamera] */ 45 @Module( 46 includes = 47 [ 48 UseCaseCameraImpl.Bindings::class, 49 UseCaseCameraRequestControlImpl.Bindings::class, 50 ] 51 ) 52 public abstract class UseCaseCameraModule { 53 // Used for dagger provider methods that are static. 54 public companion object { 55 56 @UseCaseCameraScope 57 @Provides 58 public fun provideCapturePipeline( 59 capturePipelineImpl: CapturePipelineImpl, 60 capturePipelineTorchCorrection: CapturePipelineTorchCorrection 61 ): CapturePipeline { 62 if (CapturePipelineTorchCorrection.isEnabled) { 63 return capturePipelineTorchCorrection 64 } 65 66 return capturePipelineImpl 67 } 68 } 69 } 70 71 /** Dagger module for binding the [UseCase]'s to the [UseCaseCamera]. */ 72 @Module 73 public class UseCaseCameraConfig( 74 private val useCases: List<UseCase>, 75 private val sessionConfigAdapter: SessionConfigAdapter, 76 private val cameraStateAdapter: CameraStateAdapter, 77 private val cameraGraph: CameraGraph, 78 private val streamConfigMap: Map<CameraStream.Config, DeferrableSurface>, 79 private val sessionProcessorManager: SessionProcessorManager?, 80 ) { 81 @UseCaseCameraScope 82 @Provides provideUseCaseListnull83 public fun provideUseCaseList(): java.util.ArrayList<UseCase> { 84 return java.util.ArrayList(useCases) 85 } 86 87 @UseCaseCameraScope 88 @Provides provideSessionConfigAdapternull89 public fun provideSessionConfigAdapter(): SessionConfigAdapter { 90 return sessionConfigAdapter 91 } 92 93 @UseCaseCameraScope 94 @Provides provideSessionProcessorManagernull95 public fun provideSessionProcessorManager(): SessionProcessorManager? { 96 return sessionProcessorManager 97 } 98 99 /** 100 * [UseCaseGraphConfig] would store the CameraGraph and related surface map that would be used 101 * for [UseCaseCamera]. 102 */ 103 @UseCaseCameraScope 104 @Provides provideUseCaseGraphConfignull105 public fun provideUseCaseGraphConfig( 106 useCaseSurfaceManager: UseCaseSurfaceManager, 107 cameraInteropStateCallbackRepository: CameraInteropStateCallbackRepository 108 ): UseCaseGraphConfig { 109 sessionConfigAdapter.getValidSessionConfigOrNull()?.let { sessionConfig -> 110 cameraInteropStateCallbackRepository.updateCallbacks(sessionConfig) 111 } 112 113 val surfaceToStreamMap = mutableMapOf<DeferrableSurface, StreamId>() 114 streamConfigMap.forEach { (streamConfig, deferrableSurface) -> 115 cameraGraph.streams[streamConfig]?.let { surfaceToStreamMap[deferrableSurface] = it.id } 116 } 117 118 Log.debug { "Prepare UseCaseCameraGraphConfig: $cameraGraph " } 119 120 // Start the CameraGraph first before setting up Surfaces. Surfaces can be closed, and we 121 // will close the CameraGraph when that happens, and we cannot start a closed CameraGraph. 122 cameraGraph.start() 123 124 if (!sessionConfigAdapter.isSessionProcessorEnabled) { 125 Log.debug { "Setting up Surfaces with UseCaseSurfaceManager" } 126 if (sessionConfigAdapter.isSessionConfigValid()) { 127 useCaseSurfaceManager 128 .setupAsync( 129 cameraGraph, 130 sessionConfigAdapter, 131 surfaceToStreamMap, 132 ) 133 .invokeOnCompletion { throwable -> 134 // Only show logs for error cases, ignore CancellationException since the 135 // task could be cancelled by UseCaseSurfaceManager#stopAsync(). 136 if (throwable != null && throwable !is CancellationException) { 137 Log.error(throwable) { "Surface setup error!" } 138 } 139 } 140 } else { 141 Log.error { "Unable to create capture session due to conflicting configurations" } 142 } 143 } 144 145 return UseCaseGraphConfig( 146 graph = cameraGraph, 147 surfaceToStreamMap = surfaceToStreamMap, 148 cameraStateAdapter = cameraStateAdapter, 149 ) 150 } 151 } 152 153 public data class UseCaseGraphConfig( 154 val graph: CameraGraph, 155 val surfaceToStreamMap: Map<DeferrableSurface, StreamId>, 156 val cameraStateAdapter: CameraStateAdapter, 157 ) { getStreamIdsFromSurfacesnull158 public fun getStreamIdsFromSurfaces( 159 deferrableSurfaces: Collection<DeferrableSurface> 160 ): Set<StreamId> { 161 val streamIds = mutableSetOf<StreamId>() 162 deferrableSurfaces.forEach { 163 surfaceToStreamMap[it]?.let { streamId -> streamIds.add(streamId) } 164 } 165 return streamIds 166 } 167 } 168 169 /** Dagger subcomponent for a single [UseCaseCamera] instance. */ 170 @UseCaseCameraScope 171 @Subcomponent(modules = [UseCaseCameraModule::class, UseCaseCameraConfig::class]) 172 public interface UseCaseCameraComponent { getUseCaseCameranull173 public fun getUseCaseCamera(): UseCaseCamera 174 175 public fun getUseCaseGraphConfig(): UseCaseGraphConfig 176 177 @Subcomponent.Builder 178 public interface Builder { 179 public fun config(config: UseCaseCameraConfig): Builder 180 181 public fun build(): UseCaseCameraComponent 182 } 183 } 184