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 17 package androidx.camera.camera2.pipe.config 18 19 import android.app.admin.DevicePolicyManager 20 import android.content.Context 21 import android.content.pm.PackageManager 22 import android.hardware.camera2.CameraManager 23 import androidx.camera.camera2.pipe.CameraBackend 24 import androidx.camera.camera2.pipe.CameraBackendFactory 25 import androidx.camera.camera2.pipe.CameraBackendId 26 import androidx.camera.camera2.pipe.CameraBackends 27 import androidx.camera.camera2.pipe.CameraContext 28 import androidx.camera.camera2.pipe.CameraDevices 29 import androidx.camera.camera2.pipe.CameraPipe 30 import androidx.camera.camera2.pipe.CameraPipe.CameraMetadataConfig 31 import androidx.camera.camera2.pipe.CameraSurfaceManager 32 import androidx.camera.camera2.pipe.compat.AndroidDevicePolicyManagerWrapper 33 import androidx.camera.camera2.pipe.compat.AudioRestrictionController 34 import androidx.camera.camera2.pipe.compat.AudioRestrictionControllerImpl 35 import androidx.camera.camera2.pipe.compat.DevicePolicyManagerWrapper 36 import androidx.camera.camera2.pipe.core.Debug 37 import androidx.camera.camera2.pipe.core.SystemTimeSource 38 import androidx.camera.camera2.pipe.core.Threads 39 import androidx.camera.camera2.pipe.core.TimeSource 40 import androidx.camera.camera2.pipe.internal.CameraBackendsImpl 41 import androidx.camera.camera2.pipe.internal.CameraDevicesImpl 42 import androidx.camera.camera2.pipe.media.ImageReaderImageSources 43 import androidx.camera.camera2.pipe.media.ImageSources 44 import dagger.Binds 45 import dagger.Component 46 import dagger.Module 47 import dagger.Provides 48 import dagger.Reusable 49 import javax.inject.Provider 50 import javax.inject.Qualifier 51 import javax.inject.Singleton 52 53 @Qualifier internal annotation class DefaultCameraBackend 54 55 /** Qualifier for requesting the CameraPipe scoped Context object */ 56 @Qualifier internal annotation class CameraPipeContext 57 58 @Singleton 59 @Component( 60 modules = 61 [ 62 CameraPipeConfigModule::class, 63 CameraPipeModules::class, 64 Camera2Module::class, 65 ] 66 ) 67 internal interface CameraPipeComponent { cameraGraphComponentBuildernull68 fun cameraGraphComponentBuilder(): CameraGraphComponent.Builder 69 70 fun cameras(): CameraDevices 71 72 fun cameraBackends(): CameraBackends 73 74 fun cameraSurfaceManager(): CameraSurfaceManager 75 76 fun cameraAudioRestrictionController(): AudioRestrictionController 77 } 78 79 @Module(includes = [ThreadConfigModule::class], subcomponents = [CameraGraphComponent::class]) 80 internal class CameraPipeConfigModule(private val config: CameraPipe.Config) { 81 @Provides fun provideCameraPipeConfig(): CameraPipe.Config = config 82 83 @Provides 84 fun provideCameraInteropConfig( 85 cameraPipeConfig: CameraPipe.Config 86 ): CameraPipe.CameraInteropConfig { 87 return cameraPipeConfig.cameraInteropConfig 88 } 89 } 90 91 @Module 92 internal abstract class CameraPipeModules { bindCamerasnull93 @Binds abstract fun bindCameras(impl: CameraDevicesImpl): CameraDevices 94 95 @Binds abstract fun bindTimeSource(timeSource: SystemTimeSource): TimeSource 96 97 companion object { 98 @Provides 99 @CameraPipeContext 100 fun provideContext(config: CameraPipe.Config): Context = config.appContext 101 102 @Provides 103 fun provideCameraMetadataConfig(config: CameraPipe.Config): CameraMetadataConfig = 104 config.cameraMetadataConfig 105 106 @Reusable 107 @Provides 108 fun provideCameraManager(@CameraPipeContext cameraPipeContext: Context): CameraManager = 109 cameraPipeContext.getSystemService(Context.CAMERA_SERVICE) as CameraManager 110 111 @Reusable 112 @Provides 113 fun provideDevicePolicyManagerWrapper( 114 @CameraPipeContext cameraPipeContext: Context 115 ): DevicePolicyManagerWrapper { 116 val devicePolicyService = 117 cameraPipeContext.getSystemService(Context.DEVICE_POLICY_SERVICE) 118 return AndroidDevicePolicyManagerWrapper(devicePolicyService as DevicePolicyManager) 119 } 120 121 @Singleton 122 @Provides 123 fun provideCameraContext( 124 @CameraPipeContext cameraPipeContext: Context, 125 threads: Threads, 126 cameraBackends: CameraBackends 127 ): CameraContext = 128 object : CameraContext { 129 override val appContext: Context = cameraPipeContext 130 override val threads: Threads = threads 131 override val cameraBackends: CameraBackends = cameraBackends 132 } 133 134 @Singleton 135 @Provides 136 fun providePackageManager(@CameraPipeContext cameraPipeContext: Context): PackageManager = 137 cameraPipeContext.packageManager 138 139 @Singleton 140 @Provides 141 fun provideCameraBackends( 142 config: CameraPipe.Config, 143 @DefaultCameraBackend defaultCameraBackend: Provider<CameraBackend>, 144 @CameraPipeContext cameraPipeContext: Context, 145 threads: Threads, 146 ): CameraBackends { 147 // This is intentionally lazy. If an internalBackend is defined as part of the 148 // CameraPipe configuration, we will never create the default cameraPipeCameraBackend. 149 val internalBackend = 150 config.cameraBackendConfig.internalBackend 151 ?: Debug.trace("Initialize defaultCameraBackend") { defaultCameraBackend.get() } 152 153 // Make sure that the list of additional backends does not contain the 154 check(!config.cameraBackendConfig.cameraBackends.containsKey(internalBackend.id)) { 155 "CameraBackendConfig#cameraBackends should not contain a backend with " + 156 "${internalBackend.id}. Use CameraBackendConfig#internalBackend field instead." 157 } 158 val allBackends: Map<CameraBackendId, CameraBackendFactory> = 159 config.cameraBackendConfig.cameraBackends + 160 (internalBackend.id to CameraBackendFactory { internalBackend }) 161 162 val defaultBackendId = config.cameraBackendConfig.defaultBackend ?: internalBackend.id 163 check(allBackends.containsKey(defaultBackendId)) { 164 "Failed to find $defaultBackendId in the list of available CameraPipe backends! " + 165 "Available values are ${allBackends.keys}" 166 } 167 return CameraBackendsImpl(defaultBackendId, allBackends, cameraPipeContext, threads) 168 } 169 170 @Provides 171 fun configureImageSources( 172 imageReaderImageSources: ImageReaderImageSources, 173 cameraPipeConfig: CameraPipe.Config 174 ): ImageSources { 175 if (cameraPipeConfig.imageSources != null) { 176 return cameraPipeConfig.imageSources 177 } 178 return imageReaderImageSources 179 } 180 181 @Singleton @Provides fun provideCameraSurfaceManager() = CameraSurfaceManager() 182 183 @Singleton 184 @Provides 185 fun provideAudioRestrictionController() = AudioRestrictionControllerImpl() 186 } 187 } 188