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