From a946bc5c44234b6c3f5a5ae35191c6c77684964d Mon Sep 17 00:00:00 2001 From: davidjiagoogle Date: Tue, 4 Aug 2026 20:56:44 +0000 Subject: [PATCH 1/4] Reapply "Refactor: Move Hilt modules from core to data layer (#537)" (#546) This reverts commit bbe615379227eb3c0edb1b1d8c59f336d3d53dd7. --- app/build.gradle.kts | 12 ++++ .../com/google/jetpackcamera/AppModule.kt | 6 +- .../google/jetpackcamera/AppSettingsModule.kt | 2 +- .../google/jetpackcamera/di/AppQualifiers.kt | 61 +++++++++++++++++++ .../google/jetpackcamera/di}/CameraModule.kt | 11 ++-- .../google/jetpackcamera/di}/CommonModule.kt | 37 ++--------- .../google/jetpackcamera/di}/MediaModule.kt | 22 +++++-- .../core/camera/effects/EffectsModule.kt | 6 +- .../effects/SingleStreamEffectProvider.kt | 6 +- .../build.gradle.kts | 51 ++++++++++++++++ .../di}/PlayServicesLowLightBoostModule.kt | 16 ++--- .../low-light-playservices/build.gradle.kts | 9 --- ...ervicesLowLightBoostAvailabilityChecker.kt | 3 +- ...PlayServicesLowLightBoostEffectProvider.kt | 6 +- core/camera/low-light/build.gradle.kts | 9 --- .../low-light/low-light-di/build.gradle.kts | 51 ++++++++++++++++ .../lowlight/di}/LowLightBoostModule.kt | 7 ++- core/camera/postprocess/build.gradle.kts | 12 ---- .../postprocess-di/build.gradle.kts | 51 ++++++++++++++++ .../postprocess/di}/PostProcessModule.kt | 6 +- .../core/camera/CameraXCameraSystem.kt | 9 +-- core/common/build.gradle.kts | 9 --- core/settings/build.gradle.kts | 10 --- .../PrefsDataStoreSettingsDataSource.kt | 3 +- .../data/media/LocalMediaRepository.kt | 13 ++-- .../feature/preview/PreviewViewModel.kt | 3 +- settings.gradle.kts | 3 + ui/components/capture/build.gradle.kts | 6 +- 28 files changed, 294 insertions(+), 146 deletions(-) create mode 100644 app/src/main/java/com/google/jetpackcamera/di/AppQualifiers.kt rename {data/camera/src/main/java/com/google/jetpackcamera/data/camera => app/src/main/java/com/google/jetpackcamera/di}/CameraModule.kt (91%) rename {core/common/src/main/java/com/google/jetpackcamera/core/common => app/src/main/java/com/google/jetpackcamera/di}/CommonModule.kt (60%) rename {data/media/src/main/kotlin/com/google/jetpackcamera/data/media => app/src/main/java/com/google/jetpackcamera/di}/MediaModule.kt (54%) create mode 100644 core/camera/low-light-playservices-di/build.gradle.kts rename core/camera/{low-light-playservices/src/main/java/com/google/jetpackcamera/core/camera/lowlight/playservices => low-light-playservices-di/src/main/java/com/google/jetpackcamera/core/camera/lowlight/playservices/di}/PlayServicesLowLightBoostModule.kt (76%) create mode 100644 core/camera/low-light/low-light-di/build.gradle.kts rename core/camera/low-light/{src/main/java/com/google/jetpackcamera/core/camera/lowlight => low-light-di/src/main/java/com/google/jetpackcamera/core/camera/lowlight/di}/LowLightBoostModule.kt (87%) create mode 100644 core/camera/postprocess/postprocess-di/build.gradle.kts rename core/camera/postprocess/{src/main/java/com/google/jetpackcamera/core/camera/postprocess => postprocess-di/src/main/java/com/google/jetpackcamera/core/camera/postprocess/di}/PostProcessModule.kt (86%) diff --git a/app/build.gradle.kts b/app/build.gradle.kts index ad359692b..8173334da 100644 --- a/app/build.gradle.kts +++ b/app/build.gradle.kts @@ -101,6 +101,11 @@ android { dependencies { implementation(libs.androidx.tracing) implementation(project(":core:common")) + implementation(project(":core:camera")) + implementation(project(":core:camera:low-light")) + implementation(project(":core:camera:postprocess")) + implementation(project(":data:camera")) + implementation(project(":data:media")) implementation(project(":feature:postcapture")) // Compose val composeBom = platform(libs.compose.bom) @@ -177,6 +182,13 @@ dependencies { implementation(project(":ui:components:capture")) implementation(project(":ui:debug")) + // Low Light implementations + implementation(project(":core:camera:low-light:low-light-di")) + implementation(project(":core:camera:low-light-playservices-di")) + + // Postprocess implementations + implementation(project(":core:camera:postprocess:postprocess-di")) + implementation(project(":core:camera:low-light-playservices")) implementation(project(":core:camera:effects:single-stream")) } diff --git a/app/src/main/java/com/google/jetpackcamera/AppModule.kt b/app/src/main/java/com/google/jetpackcamera/AppModule.kt index 0c4f6ff72..46e30da70 100644 --- a/app/src/main/java/com/google/jetpackcamera/AppModule.kt +++ b/app/src/main/java/com/google/jetpackcamera/AppModule.kt @@ -15,10 +15,9 @@ */ package com.google.jetpackcamera -import com.google.jetpackcamera.core.common.DefaultCaptureModeOverride -import com.google.jetpackcamera.core.common.DefaultFilePathGenerator -import com.google.jetpackcamera.core.common.DefaultSaveMode import com.google.jetpackcamera.core.common.FilePathGenerator +import com.google.jetpackcamera.di.DefaultCaptureModeOverride +import com.google.jetpackcamera.di.DefaultFilePathGenerator import com.google.jetpackcamera.model.CaptureMode import com.google.jetpackcamera.model.SaveMode import dagger.Module @@ -40,7 +39,6 @@ object AppModule { * provides the default [SaveMode] to be used by the app */ @Provides - @DefaultSaveMode fun providesSaveMode(): SaveMode = SaveMode.Immediate @Provides diff --git a/app/src/main/java/com/google/jetpackcamera/AppSettingsModule.kt b/app/src/main/java/com/google/jetpackcamera/AppSettingsModule.kt index 49a9f434c..e2e8e741c 100644 --- a/app/src/main/java/com/google/jetpackcamera/AppSettingsModule.kt +++ b/app/src/main/java/com/google/jetpackcamera/AppSettingsModule.kt @@ -20,8 +20,8 @@ import androidx.datastore.core.DataStore import androidx.datastore.preferences.core.PreferenceDataStoreFactory import androidx.datastore.preferences.core.Preferences import androidx.datastore.preferences.preferencesDataStoreFile -import com.google.jetpackcamera.core.common.DefaultCaptureModeOverride import com.google.jetpackcamera.core.settings.datastoreprefs.PrefsDataStoreSettingsDataSource +import com.google.jetpackcamera.di.DefaultCaptureModeOverride import com.google.jetpackcamera.model.CaptureMode import com.google.jetpackcamera.settings.SettingsDataSource import dagger.Module diff --git a/app/src/main/java/com/google/jetpackcamera/di/AppQualifiers.kt b/app/src/main/java/com/google/jetpackcamera/di/AppQualifiers.kt new file mode 100644 index 000000000..cb54a56db --- /dev/null +++ b/app/src/main/java/com/google/jetpackcamera/di/AppQualifiers.kt @@ -0,0 +1,61 @@ +/* + * Copyright (C) 2026 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.google.jetpackcamera.di + +import javax.inject.Qualifier + +/** + * Identifies the default file path generator instance used for naming and locating media output files. + */ +@Target(AnnotationTarget.FUNCTION, AnnotationTarget.VALUE_PARAMETER) +@Qualifier +@Retention(AnnotationRetention.BINARY) +internal annotation class DefaultFilePathGenerator + +/** + * Identifies the fallback capture mode override when initializing repository settings. + */ +@Qualifier +@Retention(AnnotationRetention.BINARY) +internal annotation class DefaultCaptureModeOverride + +/** + * Identifies the default media saving location policy (e.g. device storage vs app cache). + */ +@Qualifier +@Retention(AnnotationRetention.BINARY) +internal annotation class DefaultSaveMode + +/** + * Identifies the CPU-bound [kotlinx.coroutines.CoroutineDispatcher] used for general computation. + */ +@Qualifier +@Retention(AnnotationRetention.BINARY) +internal annotation class DefaultDispatcher + +/** + * Identifies the I/O-bound [kotlinx.coroutines.CoroutineDispatcher] used for disk and network tasks. + */ +@Qualifier +@Retention(AnnotationRetention.BINARY) +internal annotation class IODispatcher + +/** + * Identifies the root application-level [kotlinx.coroutines.CoroutineScope] tied to SingletonComponent lifecycle. + */ +@Qualifier +@Retention(AnnotationRetention.BINARY) +internal annotation class DefaultCoroutineScope diff --git a/data/camera/src/main/java/com/google/jetpackcamera/data/camera/CameraModule.kt b/app/src/main/java/com/google/jetpackcamera/di/CameraModule.kt similarity index 91% rename from data/camera/src/main/java/com/google/jetpackcamera/data/camera/CameraModule.kt rename to app/src/main/java/com/google/jetpackcamera/di/CameraModule.kt index ca67280aa..261fb645b 100644 --- a/data/camera/src/main/java/com/google/jetpackcamera/data/camera/CameraModule.kt +++ b/app/src/main/java/com/google/jetpackcamera/di/CameraModule.kt @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.google.jetpackcamera.data.camera +package com.google.jetpackcamera.di import android.app.Application import android.content.Context @@ -25,10 +25,9 @@ import com.google.jetpackcamera.core.camera.lowlight.LowLightBoostEffectProvider import com.google.jetpackcamera.core.camera.lowlight.LowLightBoostFeatureKey import com.google.jetpackcamera.core.camera.postprocess.ImagePostProcessor import com.google.jetpackcamera.core.camera.postprocess.ImagePostProcessorFeatureKey -import com.google.jetpackcamera.core.common.DefaultDispatcher -import com.google.jetpackcamera.core.common.DefaultFilePathGenerator import com.google.jetpackcamera.core.common.FilePathGenerator -import com.google.jetpackcamera.core.common.IODispatcher +import com.google.jetpackcamera.data.camera.CameraSystemRepository +import com.google.jetpackcamera.data.camera.CameraXCameraSystemRepository import dagger.Binds import dagger.Module import dagger.Provides @@ -40,11 +39,11 @@ import javax.inject.Provider import kotlinx.coroutines.CoroutineDispatcher /** - * Dagger [Module] for camera data layer. + * Dagger [Module] for camera dependencies. */ @Module @InstallIn(ActivityRetainedComponent::class) -interface CameraModule { +internal interface CameraModule { @Binds @ActivityRetainedScoped diff --git a/core/common/src/main/java/com/google/jetpackcamera/core/common/CommonModule.kt b/app/src/main/java/com/google/jetpackcamera/di/CommonModule.kt similarity index 60% rename from core/common/src/main/java/com/google/jetpackcamera/core/common/CommonModule.kt rename to app/src/main/java/com/google/jetpackcamera/di/CommonModule.kt index 998ab951e..78b0427cf 100644 --- a/core/common/src/main/java/com/google/jetpackcamera/core/common/CommonModule.kt +++ b/app/src/main/java/com/google/jetpackcamera/di/CommonModule.kt @@ -1,5 +1,5 @@ /* - * Copyright (C) 2023 The Android Open Source Project + * Copyright (C) 2026 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -13,13 +13,12 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.google.jetpackcamera.core.common +package com.google.jetpackcamera.di import dagger.Module import dagger.Provides import dagger.hilt.InstallIn import dagger.hilt.components.SingletonComponent -import javax.inject.Qualifier import javax.inject.Singleton import kotlinx.coroutines.CoroutineDispatcher import kotlinx.coroutines.CoroutineScope @@ -27,11 +26,11 @@ import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.SupervisorJob /** - * Dagger [Module] for Common dependencies. + * Dagger [Module] for global application-level coroutine dispatchers and scope. */ @Module @InstallIn(SingletonComponent::class) -class CommonModule { +internal class CommonModule { @Provides @DefaultDispatcher fun provideDefaultDispatcher(): CoroutineDispatcher = Dispatchers.Default @@ -46,31 +45,3 @@ class CommonModule { fun providesCoroutineScope(@DefaultDispatcher dispatcher: CoroutineDispatcher) = CoroutineScope(SupervisorJob() + dispatcher) } - -@Target(AnnotationTarget.FUNCTION, AnnotationTarget.VALUE_PARAMETER) -@Qualifier -@Retention(AnnotationRetention.BINARY) -annotation class DefaultFilePathGenerator - -/** - * provides the default [CaptureMode] to override in [LocalSettingsRepository] - */ -@Qualifier -@Retention(AnnotationRetention.BINARY) -annotation class DefaultCaptureModeOverride - -@Qualifier -@Retention(AnnotationRetention.BINARY) -annotation class DefaultSaveMode - -@Qualifier -@Retention(AnnotationRetention.BINARY) -annotation class DefaultDispatcher - -@Qualifier -@Retention(AnnotationRetention.BINARY) -annotation class IODispatcher - -@Qualifier -@Retention(AnnotationRetention.BINARY) -annotation class DefaultCoroutineScope diff --git a/data/media/src/main/kotlin/com/google/jetpackcamera/data/media/MediaModule.kt b/app/src/main/java/com/google/jetpackcamera/di/MediaModule.kt similarity index 54% rename from data/media/src/main/kotlin/com/google/jetpackcamera/data/media/MediaModule.kt rename to app/src/main/java/com/google/jetpackcamera/di/MediaModule.kt index a4ec2ddfc..467bb455e 100644 --- a/data/media/src/main/kotlin/com/google/jetpackcamera/data/media/MediaModule.kt +++ b/app/src/main/java/com/google/jetpackcamera/di/MediaModule.kt @@ -13,22 +13,34 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.google.jetpackcamera.data.media +package com.google.jetpackcamera.di -import dagger.Binds +import android.content.Context +import com.google.jetpackcamera.core.common.FilePathGenerator +import com.google.jetpackcamera.data.media.LocalMediaRepository +import com.google.jetpackcamera.data.media.MediaRepository import dagger.Module +import dagger.Provides import dagger.hilt.InstallIn +import dagger.hilt.android.qualifiers.ApplicationContext import dagger.hilt.components.SingletonComponent import javax.inject.Singleton +import kotlinx.coroutines.CoroutineDispatcher /** * Dagger [Module] for Media dependencies. */ @Module @InstallIn(SingletonComponent::class) -interface MediaModule { +internal object MediaModule { - @Binds + @Provides @Singleton - fun bindsMediaRepository(localMediaRepository: LocalMediaRepository): MediaRepository + fun provideMediaRepository( + @ApplicationContext context: Context, + @IODispatcher ioDispatcher: CoroutineDispatcher, + @DefaultFilePathGenerator filePathGenerator: FilePathGenerator + ): MediaRepository { + return LocalMediaRepository(context, ioDispatcher, filePathGenerator) + } } diff --git a/core/camera/effects/single-stream/src/main/java/com/google/jetpackcamera/core/camera/effects/EffectsModule.kt b/core/camera/effects/single-stream/src/main/java/com/google/jetpackcamera/core/camera/effects/EffectsModule.kt index 59ac7bece..1f3b129dd 100644 --- a/core/camera/effects/single-stream/src/main/java/com/google/jetpackcamera/core/camera/effects/EffectsModule.kt +++ b/core/camera/effects/single-stream/src/main/java/com/google/jetpackcamera/core/camera/effects/EffectsModule.kt @@ -32,14 +32,12 @@ import javax.inject.Provider internal object EffectsModule { @Provides @IntoSet - fun provideSingleStreamEffectProviderEntry( - impl: Provider - ): Map.Entry< + fun provideSingleStreamEffectProviderEntry(): Map.Entry< CameraEffectFeatureKey, @JvmSuppressWildcards Provider > = AbstractMap.SimpleImmutableEntry( SingleStreamEffectKey, - Provider { impl.get() } + Provider { SingleStreamEffectProvider() } ) } diff --git a/core/camera/effects/single-stream/src/main/java/com/google/jetpackcamera/core/camera/effects/SingleStreamEffectProvider.kt b/core/camera/effects/single-stream/src/main/java/com/google/jetpackcamera/core/camera/effects/SingleStreamEffectProvider.kt index 0e68cdd7e..226ca4b10 100644 --- a/core/camera/effects/single-stream/src/main/java/com/google/jetpackcamera/core/camera/effects/SingleStreamEffectProvider.kt +++ b/core/camera/effects/single-stream/src/main/java/com/google/jetpackcamera/core/camera/effects/SingleStreamEffectProvider.kt @@ -18,13 +18,9 @@ package com.google.jetpackcamera.core.camera.effects import androidx.camera.core.CameraEffect import com.google.jetpackcamera.core.camera.CameraEffectProvider import com.google.jetpackcamera.model.CameraEffectTarget -import javax.inject.Inject import kotlinx.coroutines.CoroutineScope -/** - * Implementation of [CameraEffectProvider] that provides [SingleSurfaceForcingEffect]. - */ -internal class SingleStreamEffectProvider @Inject constructor() : CameraEffectProvider { +internal class SingleStreamEffectProvider : CameraEffectProvider { override val targets: Set = setOf( CameraEffectTarget.PREVIEW, diff --git a/core/camera/low-light-playservices-di/build.gradle.kts b/core/camera/low-light-playservices-di/build.gradle.kts new file mode 100644 index 000000000..aa8a68189 --- /dev/null +++ b/core/camera/low-light-playservices-di/build.gradle.kts @@ -0,0 +1,51 @@ +/* + * Copyright (C) 2026 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +plugins { + alias(libs.plugins.android.library) + alias(libs.plugins.kotlin.android) + alias(libs.plugins.kotlin.kapt) + alias(libs.plugins.dagger.hilt.android) +} + +android { + namespace = "com.google.jetpackcamera.core.camera.lowlight.playservices.di" + compileSdk = libs.versions.compileSdk.get().toInt() + + defaultConfig { + minSdk = libs.versions.minSdk.get().toInt() + } + compileOptions { + sourceCompatibility = JavaVersion.VERSION_17 + targetCompatibility = JavaVersion.VERSION_17 + } + kotlin { + jvmToolchain(17) + } +} + +dependencies { + implementation(project(":core:camera:low-light")) + implementation(project(":core:camera:low-light-playservices")) + + // Hilt + implementation(libs.dagger.hilt.android) + kapt(libs.dagger.hilt.compiler) +} + +kapt { + correctErrorTypes = true +} diff --git a/core/camera/low-light-playservices/src/main/java/com/google/jetpackcamera/core/camera/lowlight/playservices/PlayServicesLowLightBoostModule.kt b/core/camera/low-light-playservices-di/src/main/java/com/google/jetpackcamera/core/camera/lowlight/playservices/di/PlayServicesLowLightBoostModule.kt similarity index 76% rename from core/camera/low-light-playservices/src/main/java/com/google/jetpackcamera/core/camera/lowlight/playservices/PlayServicesLowLightBoostModule.kt rename to core/camera/low-light-playservices-di/src/main/java/com/google/jetpackcamera/core/camera/lowlight/playservices/di/PlayServicesLowLightBoostModule.kt index 172e0ba1c..f0577b6c9 100644 --- a/core/camera/low-light-playservices/src/main/java/com/google/jetpackcamera/core/camera/lowlight/playservices/PlayServicesLowLightBoostModule.kt +++ b/core/camera/low-light-playservices-di/src/main/java/com/google/jetpackcamera/core/camera/lowlight/playservices/di/PlayServicesLowLightBoostModule.kt @@ -13,14 +13,18 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.google.jetpackcamera.core.camera.lowlight.playservices +package com.google.jetpackcamera.core.camera.lowlight.playservices.di +import android.content.Context import com.google.jetpackcamera.core.camera.lowlight.LowLightBoostAvailabilityChecker import com.google.jetpackcamera.core.camera.lowlight.LowLightBoostEffectProvider import com.google.jetpackcamera.core.camera.lowlight.LowLightBoostFeatureKey +import com.google.jetpackcamera.core.camera.lowlight.playservices.PlayServicesLowLightBoostAvailabilityChecker +import com.google.jetpackcamera.core.camera.lowlight.playservices.PlayServicesLowLightBoostEffectProvider import dagger.Module import dagger.Provides import dagger.hilt.InstallIn +import dagger.hilt.android.qualifiers.ApplicationContext import dagger.hilt.components.SingletonComponent import dagger.multibindings.IntoSet import java.util.AbstractMap @@ -33,27 +37,25 @@ object PlayServicesLowLightBoostFeatureKey : LowLightBoostFeatureKey internal object PlayServicesLowLightBoostModule { @Provides @IntoSet - fun provideAvailabilityCheckerEntry( - impl: Provider - ): Map.Entry< + fun provideAvailabilityCheckerEntry(): Map.Entry< LowLightBoostFeatureKey, @JvmSuppressWildcards Provider > = AbstractMap.SimpleImmutableEntry( PlayServicesLowLightBoostFeatureKey, - Provider { impl.get() } + Provider { PlayServicesLowLightBoostAvailabilityChecker() } ) @Provides @IntoSet fun provideEffectProviderEntry( - impl: Provider + @ApplicationContext context: Context ): Map.Entry< LowLightBoostFeatureKey, @JvmSuppressWildcards Provider > = AbstractMap.SimpleImmutableEntry( PlayServicesLowLightBoostFeatureKey, - Provider { impl.get() } + Provider { PlayServicesLowLightBoostEffectProvider(context) } ) } diff --git a/core/camera/low-light-playservices/build.gradle.kts b/core/camera/low-light-playservices/build.gradle.kts index 639fa3e51..42d191648 100644 --- a/core/camera/low-light-playservices/build.gradle.kts +++ b/core/camera/low-light-playservices/build.gradle.kts @@ -17,8 +17,6 @@ plugins { alias(libs.plugins.android.library) alias(libs.plugins.kotlin.android) - alias(libs.plugins.kotlin.kapt) - alias(libs.plugins.dagger.hilt.android) } android { @@ -44,12 +42,5 @@ dependencies { implementation(libs.androidx.annotation) implementation(libs.camera.camera2) implementation(libs.camera.core) - implementation(libs.dagger.hilt.android) - kapt(libs.dagger.hilt.compiler) implementation(libs.kotlinx.coroutines.play.services) } - -// Allow references to generated code -kapt { - correctErrorTypes = true -} diff --git a/core/camera/low-light-playservices/src/main/java/com/google/jetpackcamera/core/camera/lowlight/playservices/PlayServicesLowLightBoostAvailabilityChecker.kt b/core/camera/low-light-playservices/src/main/java/com/google/jetpackcamera/core/camera/lowlight/playservices/PlayServicesLowLightBoostAvailabilityChecker.kt index 40068b59d..e07be3f79 100644 --- a/core/camera/low-light-playservices/src/main/java/com/google/jetpackcamera/core/camera/lowlight/playservices/PlayServicesLowLightBoostAvailabilityChecker.kt +++ b/core/camera/low-light-playservices/src/main/java/com/google/jetpackcamera/core/camera/lowlight/playservices/PlayServicesLowLightBoostAvailabilityChecker.kt @@ -26,12 +26,11 @@ import com.google.android.gms.cameralowlight.LowLightBoost import com.google.android.gms.common.ConnectionResult import com.google.android.gms.common.GoogleApiAvailability import com.google.jetpackcamera.core.camera.lowlight.LowLightBoostAvailabilityChecker -import javax.inject.Inject import kotlinx.coroutines.tasks.await private const val TAG = "PsLlbAvailChecker" -class PlayServicesLowLightBoostAvailabilityChecker @Inject constructor() : +class PlayServicesLowLightBoostAvailabilityChecker : LowLightBoostAvailabilityChecker { @OptIn(ExperimentalCamera2Interop::class) override suspend fun isImplementationAvailable( diff --git a/core/camera/low-light-playservices/src/main/java/com/google/jetpackcamera/core/camera/lowlight/playservices/PlayServicesLowLightBoostEffectProvider.kt b/core/camera/low-light-playservices/src/main/java/com/google/jetpackcamera/core/camera/lowlight/playservices/PlayServicesLowLightBoostEffectProvider.kt index 0699ec78f..b16d1cf34 100644 --- a/core/camera/low-light-playservices/src/main/java/com/google/jetpackcamera/core/camera/lowlight/playservices/PlayServicesLowLightBoostEffectProvider.kt +++ b/core/camera/low-light-playservices/src/main/java/com/google/jetpackcamera/core/camera/lowlight/playservices/PlayServicesLowLightBoostEffectProvider.kt @@ -25,13 +25,11 @@ import com.google.android.gms.cameralowlight.LowLightBoost import com.google.android.gms.cameralowlight.LowLightBoostSession import com.google.android.gms.cameralowlight.SceneDetectorCallback import com.google.jetpackcamera.core.camera.lowlight.LowLightBoostEffectProvider -import dagger.hilt.android.qualifiers.ApplicationContext -import javax.inject.Inject import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.flow.StateFlow -class PlayServicesLowLightBoostEffectProvider @Inject constructor( - @ApplicationContext private val context: Context +class PlayServicesLowLightBoostEffectProvider( + private val context: Context ) : LowLightBoostEffectProvider { @SuppressLint("RestrictedApi") @RequiresApi(Build.VERSION_CODES.R) diff --git a/core/camera/low-light/build.gradle.kts b/core/camera/low-light/build.gradle.kts index cade65c9e..52776e2fa 100644 --- a/core/camera/low-light/build.gradle.kts +++ b/core/camera/low-light/build.gradle.kts @@ -17,8 +17,6 @@ plugins { alias(libs.plugins.android.library) alias(libs.plugins.kotlin.android) - alias(libs.plugins.kotlin.kapt) - alias(libs.plugins.dagger.hilt.android) } android { @@ -40,12 +38,5 @@ android { dependencies { implementation(libs.camera.core) - implementation(libs.dagger.hilt.android) - kapt(libs.dagger.hilt.compiler) implementation(libs.kotlinx.coroutines.core) } - -// Allow references to generated code -kapt { - correctErrorTypes = true -} diff --git a/core/camera/low-light/low-light-di/build.gradle.kts b/core/camera/low-light/low-light-di/build.gradle.kts new file mode 100644 index 000000000..d5d3db5fd --- /dev/null +++ b/core/camera/low-light/low-light-di/build.gradle.kts @@ -0,0 +1,51 @@ +/* + * Copyright (C) 2026 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +plugins { + alias(libs.plugins.android.library) + alias(libs.plugins.kotlin.android) + alias(libs.plugins.kotlin.kapt) + alias(libs.plugins.dagger.hilt.android) +} + +android { + namespace = "com.google.jetpackcamera.core.camera.lowlight.di" + compileSdk = libs.versions.compileSdk.get().toInt() + + defaultConfig { + minSdk = libs.versions.minSdk.get().toInt() + } + + compileOptions { + sourceCompatibility = JavaVersion.VERSION_17 + targetCompatibility = JavaVersion.VERSION_17 + } + kotlin { + jvmToolchain(17) + } +} + +dependencies { + implementation(project(":core:camera:low-light")) + + // Hilt + implementation(libs.dagger.hilt.android) + kapt(libs.dagger.hilt.compiler) +} + +kapt { + correctErrorTypes = true +} diff --git a/core/camera/low-light/src/main/java/com/google/jetpackcamera/core/camera/lowlight/LowLightBoostModule.kt b/core/camera/low-light/low-light-di/src/main/java/com/google/jetpackcamera/core/camera/lowlight/di/LowLightBoostModule.kt similarity index 87% rename from core/camera/low-light/src/main/java/com/google/jetpackcamera/core/camera/lowlight/LowLightBoostModule.kt rename to core/camera/low-light/low-light-di/src/main/java/com/google/jetpackcamera/core/camera/lowlight/di/LowLightBoostModule.kt index 030d18bb6..c92e48b29 100644 --- a/core/camera/low-light/src/main/java/com/google/jetpackcamera/core/camera/lowlight/LowLightBoostModule.kt +++ b/core/camera/low-light/low-light-di/src/main/java/com/google/jetpackcamera/core/camera/lowlight/di/LowLightBoostModule.kt @@ -13,8 +13,11 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.google.jetpackcamera.core.camera.lowlight +package com.google.jetpackcamera.core.camera.lowlight.di +import com.google.jetpackcamera.core.camera.lowlight.LowLightBoostAvailabilityChecker +import com.google.jetpackcamera.core.camera.lowlight.LowLightBoostEffectProvider +import com.google.jetpackcamera.core.camera.lowlight.LowLightBoostFeatureKey import dagger.Module import dagger.Provides import dagger.hilt.InstallIn @@ -25,7 +28,7 @@ import javax.inject.Singleton @Module @InstallIn(SingletonComponent::class) -abstract class LowLightBoostModule { +internal abstract class LowLightBoostModule { @Multibinds abstract fun availabilityCheckerEntries(): Set< diff --git a/core/camera/postprocess/build.gradle.kts b/core/camera/postprocess/build.gradle.kts index ceedef0b7..38692d709 100644 --- a/core/camera/postprocess/build.gradle.kts +++ b/core/camera/postprocess/build.gradle.kts @@ -17,8 +17,6 @@ plugins { alias(libs.plugins.android.library) alias(libs.plugins.kotlin.android) - alias(libs.plugins.kotlin.kapt) - alias(libs.plugins.dagger.hilt.android) } android { @@ -37,13 +35,3 @@ android { jvmToolchain(17) } } - -dependencies { - implementation(libs.dagger.hilt.android) - kapt(libs.dagger.hilt.compiler) -} - -// Allow references to generated code -kapt { - correctErrorTypes = true -} diff --git a/core/camera/postprocess/postprocess-di/build.gradle.kts b/core/camera/postprocess/postprocess-di/build.gradle.kts new file mode 100644 index 000000000..063b2553e --- /dev/null +++ b/core/camera/postprocess/postprocess-di/build.gradle.kts @@ -0,0 +1,51 @@ +/* + * Copyright (C) 2026 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +plugins { + alias(libs.plugins.android.library) + alias(libs.plugins.kotlin.android) + alias(libs.plugins.kotlin.kapt) + alias(libs.plugins.dagger.hilt.android) +} + +android { + namespace = "com.google.jetpackcamera.core.camera.postprocess.di" + compileSdk = libs.versions.compileSdk.get().toInt() + + defaultConfig { + minSdk = libs.versions.minSdk.get().toInt() + } + + compileOptions { + sourceCompatibility = JavaVersion.VERSION_17 + targetCompatibility = JavaVersion.VERSION_17 + } + kotlin { + jvmToolchain(17) + } +} + +dependencies { + implementation(project(":core:camera:postprocess")) + + // Hilt + implementation(libs.dagger.hilt.android) + kapt(libs.dagger.hilt.compiler) +} + +kapt { + correctErrorTypes = true +} diff --git a/core/camera/postprocess/src/main/java/com/google/jetpackcamera/core/camera/postprocess/PostProcessModule.kt b/core/camera/postprocess/postprocess-di/src/main/java/com/google/jetpackcamera/core/camera/postprocess/di/PostProcessModule.kt similarity index 86% rename from core/camera/postprocess/src/main/java/com/google/jetpackcamera/core/camera/postprocess/PostProcessModule.kt rename to core/camera/postprocess/postprocess-di/src/main/java/com/google/jetpackcamera/core/camera/postprocess/di/PostProcessModule.kt index d26475400..e1ccc662b 100644 --- a/core/camera/postprocess/src/main/java/com/google/jetpackcamera/core/camera/postprocess/PostProcessModule.kt +++ b/core/camera/postprocess/postprocess-di/src/main/java/com/google/jetpackcamera/core/camera/postprocess/di/PostProcessModule.kt @@ -13,8 +13,10 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.google.jetpackcamera.core.camera.postprocess +package com.google.jetpackcamera.core.camera.postprocess.di +import com.google.jetpackcamera.core.camera.postprocess.ImagePostProcessor +import com.google.jetpackcamera.core.camera.postprocess.ImagePostProcessorFeatureKey import dagger.Module import dagger.Provides import dagger.hilt.InstallIn @@ -25,7 +27,7 @@ import javax.inject.Singleton @Module @InstallIn(SingletonComponent::class) -abstract class PostProcessModule { +internal abstract class PostProcessModule { @Multibinds abstract fun imagePostProcessorEntries(): Set< Map.Entry< diff --git a/core/camera/src/main/java/com/google/jetpackcamera/core/camera/CameraXCameraSystem.kt b/core/camera/src/main/java/com/google/jetpackcamera/core/camera/CameraXCameraSystem.kt index 5aa7e465c..97ad165ee 100644 --- a/core/camera/src/main/java/com/google/jetpackcamera/core/camera/CameraXCameraSystem.kt +++ b/core/camera/src/main/java/com/google/jetpackcamera/core/camera/CameraXCameraSystem.kt @@ -46,10 +46,7 @@ import com.google.jetpackcamera.core.camera.lowlight.LowLightBoostEffectProvider import com.google.jetpackcamera.core.camera.lowlight.LowLightBoostFeatureKey import com.google.jetpackcamera.core.camera.postprocess.ImagePostProcessor import com.google.jetpackcamera.core.camera.postprocess.ImagePostProcessorFeatureKey -import com.google.jetpackcamera.core.common.DefaultDispatcher -import com.google.jetpackcamera.core.common.DefaultFilePathGenerator import com.google.jetpackcamera.core.common.FilePathGenerator -import com.google.jetpackcamera.core.common.IODispatcher import com.google.jetpackcamera.model.AspectRatio import com.google.jetpackcamera.model.CameraEffectId import com.google.jetpackcamera.model.CameraZoomRatio @@ -103,9 +100,9 @@ private const val TAG = "CameraXCameraSystem" */ class CameraXCameraSystem( private val application: Application, - @param:DefaultDispatcher private val defaultDispatcher: CoroutineDispatcher, - @param:IODispatcher private val iODispatcher: CoroutineDispatcher, - @DefaultFilePathGenerator private val filePathGenerator: FilePathGenerator, + private val defaultDispatcher: CoroutineDispatcher, + private val iODispatcher: CoroutineDispatcher, + private val filePathGenerator: FilePathGenerator, availabilityCheckers: Map>, effectProviders: diff --git a/core/common/build.gradle.kts b/core/common/build.gradle.kts index 185217b27..4d6c55938 100644 --- a/core/common/build.gradle.kts +++ b/core/common/build.gradle.kts @@ -17,8 +17,6 @@ plugins { alias(libs.plugins.android.library) alias(libs.plugins.kotlin.android) - alias(libs.plugins.kotlin.kapt) - alias(libs.plugins.dagger.hilt.android) } android { @@ -77,11 +75,4 @@ dependencies { androidTestImplementation(libs.androidx.junit) androidTestImplementation(libs.androidx.espresso.core) - // Hilt - implementation(libs.dagger.hilt.android) - kapt(libs.dagger.hilt.compiler) -} - -kapt { - correctErrorTypes = true } diff --git a/core/settings/build.gradle.kts b/core/settings/build.gradle.kts index 35c256a56..a5c778046 100644 --- a/core/settings/build.gradle.kts +++ b/core/settings/build.gradle.kts @@ -17,8 +17,6 @@ plugins { alias(libs.plugins.android.library) alias(libs.plugins.kotlin.android) - alias(libs.plugins.kotlin.kapt) - alias(libs.plugins.dagger.hilt.android) } android { @@ -46,14 +44,6 @@ android { dependencies { implementation(libs.kotlinx.coroutines.core) - // Hilt - implementation(libs.dagger.hilt.android) - kapt(libs.dagger.hilt.compiler) - // Domain models implementation(project(":core:model")) } - -kapt { - correctErrorTypes = true -} diff --git a/core/settings/datastore-prefs/src/main/java/com/google/jetpackcamera/core/settings/datastoreprefs/PrefsDataStoreSettingsDataSource.kt b/core/settings/datastore-prefs/src/main/java/com/google/jetpackcamera/core/settings/datastoreprefs/PrefsDataStoreSettingsDataSource.kt index c81b9cea5..8c0fa53d4 100644 --- a/core/settings/datastore-prefs/src/main/java/com/google/jetpackcamera/core/settings/datastoreprefs/PrefsDataStoreSettingsDataSource.kt +++ b/core/settings/datastore-prefs/src/main/java/com/google/jetpackcamera/core/settings/datastoreprefs/PrefsDataStoreSettingsDataSource.kt @@ -18,7 +18,6 @@ package com.google.jetpackcamera.core.settings.datastoreprefs import androidx.datastore.core.DataStore import androidx.datastore.preferences.core.Preferences import androidx.datastore.preferences.core.edit -import com.google.jetpackcamera.core.common.DefaultCaptureModeOverride import com.google.jetpackcamera.model.AspectRatio import com.google.jetpackcamera.model.CameraEffectId import com.google.jetpackcamera.model.CaptureMode @@ -45,7 +44,7 @@ import kotlinx.coroutines.flow.map */ class PrefsDataStoreSettingsDataSource( private val dataStore: DataStore, - @DefaultCaptureModeOverride private val defaultCaptureModeOverride: CaptureMode + private val defaultCaptureModeOverride: CaptureMode ) : SettingsDataSource { override val defaultCameraAppSettings: Flow = dataStore.data.map { prefs -> diff --git a/data/media/src/main/kotlin/com/google/jetpackcamera/data/media/LocalMediaRepository.kt b/data/media/src/main/kotlin/com/google/jetpackcamera/data/media/LocalMediaRepository.kt index 4950fa147..2adb1823d 100644 --- a/data/media/src/main/kotlin/com/google/jetpackcamera/data/media/LocalMediaRepository.kt +++ b/data/media/src/main/kotlin/com/google/jetpackcamera/data/media/LocalMediaRepository.kt @@ -28,13 +28,9 @@ import android.provider.MediaStore import android.util.Log import android.util.Size import androidx.core.net.toFile -import com.google.jetpackcamera.core.common.DefaultFilePathGenerator import com.google.jetpackcamera.core.common.FilePathGenerator -import com.google.jetpackcamera.core.common.IODispatcher -import dagger.hilt.android.qualifiers.ApplicationContext import java.io.File import java.io.IOException -import javax.inject.Inject import kotlinx.coroutines.CoroutineDispatcher import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.ExperimentalCoroutinesApi @@ -48,11 +44,10 @@ private const val TAG = "LocalMediaRepository" private const val IMAGE_MIME_TYPE = "image/jpeg" private const val VIDEO_MIME_TYPE = "video/mp4" -class LocalMediaRepository -@Inject constructor( - @ApplicationContext private val context: Context, - @IODispatcher private val iODispatcher: CoroutineDispatcher, - @DefaultFilePathGenerator private val filePathGenerator: FilePathGenerator +class LocalMediaRepository( + private val context: Context, + private val iODispatcher: CoroutineDispatcher, + private val filePathGenerator: FilePathGenerator ) : MediaRepository { private val repositoryScope = CoroutineScope(iODispatcher + SupervisorJob()) private val _currentMedia = MutableStateFlow(MediaDescriptor.None) diff --git a/feature/preview/src/main/java/com/google/jetpackcamera/feature/preview/PreviewViewModel.kt b/feature/preview/src/main/java/com/google/jetpackcamera/feature/preview/PreviewViewModel.kt index 0ee79a224..2ef2b4356 100644 --- a/feature/preview/src/main/java/com/google/jetpackcamera/feature/preview/PreviewViewModel.kt +++ b/feature/preview/src/main/java/com/google/jetpackcamera/feature/preview/PreviewViewModel.kt @@ -22,7 +22,6 @@ import androidx.lifecycle.SavedStateHandle import androidx.lifecycle.ViewModel import androidx.lifecycle.viewModelScope import com.google.jetpackcamera.core.camera.CameraSystem.Companion.applyDiffs -import com.google.jetpackcamera.core.common.DefaultSaveMode import com.google.jetpackcamera.data.camera.CameraSystemRepository import com.google.jetpackcamera.data.media.MediaRepository import com.google.jetpackcamera.feature.preview.navigation.getCaptureUris @@ -94,7 +93,7 @@ private const val TAG = "PreviewViewModel" class PreviewViewModel @Inject constructor( private val cameraSystemRepository: CameraSystemRepository, private val savedStateHandle: SavedStateHandle, - @DefaultSaveMode private val defaultSaveMode: SaveMode, + private val defaultSaveMode: SaveMode, private val settingsRepository: SettingsRepository, private val constraintsRepository: SettableConstraintsRepository, private val mediaRepository: MediaRepository diff --git a/settings.gradle.kts b/settings.gradle.kts index dfb9e6557..53029e8ba 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -39,7 +39,9 @@ include(":core:camera") include(":data:camera") include(":core:camera:testing") include(":core:camera:low-light") +include(":core:camera:low-light:low-light-di") include(":core:camera:low-light-playservices") +include(":core:camera:low-light-playservices-di") include(":core:camera:effects:single-stream") include(":feature:settings") include(":data:settings") @@ -63,6 +65,7 @@ include(":core:model") include(":ui:uistate:postcapture") include(":ui:uistateadapter:postcapture") include(":core:camera:postprocess") +include(":core:camera:postprocess:postprocess-di") include(":ui:controller") include(":ui:controller:impl") include(":ui:controller:testing") diff --git a/ui/components/capture/build.gradle.kts b/ui/components/capture/build.gradle.kts index d2f9fc5fa..e2f456b45 100644 --- a/ui/components/capture/build.gradle.kts +++ b/ui/components/capture/build.gradle.kts @@ -64,6 +64,9 @@ dependencies { val composeBom = platform(libs.compose.bom) implementation(composeBom) + // AndroidX Core KTX + implementation(libs.androidx.core.ktx) + // Accompanist - Permissions implementation(libs.accompanist.permissions) @@ -74,9 +77,6 @@ dependencies { implementation(libs.compose.ui.tooling.preview) debugImplementation(libs.compose.ui.tooling) - // Compose - Integration with ViewModels with Navigation and Hilt - implementation(libs.hilt.navigation.compose) - // CameraX implementation(libs.camera.core) implementation(libs.camera.compose) From 13e3c0603b9220be5ede7755b203afdb9fc2af5c Mon Sep 17 00:00:00 2001 From: davidjiagoogle Date: Wed, 5 Aug 2026 00:31:11 +0000 Subject: [PATCH 2/4] Address code review feedback: optimize DI modules and clean up qualifiers --- .../google/jetpackcamera/di/AppQualifiers.kt | 17 +++++------------ .../com/google/jetpackcamera/di/CommonModule.kt | 2 +- .../camera/lowlight/di/LowLightBoostModule.kt | 6 +++--- .../camera/postprocess/di/PostProcessModule.kt | 4 ++-- .../data/media/LocalMediaRepository.kt | 7 ++----- 5 files changed, 13 insertions(+), 23 deletions(-) diff --git a/app/src/main/java/com/google/jetpackcamera/di/AppQualifiers.kt b/app/src/main/java/com/google/jetpackcamera/di/AppQualifiers.kt index cb54a56db..c6c51c5b6 100644 --- a/app/src/main/java/com/google/jetpackcamera/di/AppQualifiers.kt +++ b/app/src/main/java/com/google/jetpackcamera/di/AppQualifiers.kt @@ -23,39 +23,32 @@ import javax.inject.Qualifier @Target(AnnotationTarget.FUNCTION, AnnotationTarget.VALUE_PARAMETER) @Qualifier @Retention(AnnotationRetention.BINARY) -internal annotation class DefaultFilePathGenerator +annotation class DefaultFilePathGenerator /** * Identifies the fallback capture mode override when initializing repository settings. */ @Qualifier @Retention(AnnotationRetention.BINARY) -internal annotation class DefaultCaptureModeOverride - -/** - * Identifies the default media saving location policy (e.g. device storage vs app cache). - */ -@Qualifier -@Retention(AnnotationRetention.BINARY) -internal annotation class DefaultSaveMode +annotation class DefaultCaptureModeOverride /** * Identifies the CPU-bound [kotlinx.coroutines.CoroutineDispatcher] used for general computation. */ @Qualifier @Retention(AnnotationRetention.BINARY) -internal annotation class DefaultDispatcher +annotation class DefaultDispatcher /** * Identifies the I/O-bound [kotlinx.coroutines.CoroutineDispatcher] used for disk and network tasks. */ @Qualifier @Retention(AnnotationRetention.BINARY) -internal annotation class IODispatcher +annotation class IODispatcher /** * Identifies the root application-level [kotlinx.coroutines.CoroutineScope] tied to SingletonComponent lifecycle. */ @Qualifier @Retention(AnnotationRetention.BINARY) -internal annotation class DefaultCoroutineScope +annotation class DefaultCoroutineScope diff --git a/app/src/main/java/com/google/jetpackcamera/di/CommonModule.kt b/app/src/main/java/com/google/jetpackcamera/di/CommonModule.kt index 78b0427cf..8b36394e9 100644 --- a/app/src/main/java/com/google/jetpackcamera/di/CommonModule.kt +++ b/app/src/main/java/com/google/jetpackcamera/di/CommonModule.kt @@ -30,7 +30,7 @@ import kotlinx.coroutines.SupervisorJob */ @Module @InstallIn(SingletonComponent::class) -internal class CommonModule { +internal object CommonModule { @Provides @DefaultDispatcher fun provideDefaultDispatcher(): CoroutineDispatcher = Dispatchers.Default diff --git a/core/camera/low-light/low-light-di/src/main/java/com/google/jetpackcamera/core/camera/lowlight/di/LowLightBoostModule.kt b/core/camera/low-light/low-light-di/src/main/java/com/google/jetpackcamera/core/camera/lowlight/di/LowLightBoostModule.kt index c92e48b29..472abbc86 100644 --- a/core/camera/low-light/low-light-di/src/main/java/com/google/jetpackcamera/core/camera/lowlight/di/LowLightBoostModule.kt +++ b/core/camera/low-light/low-light-di/src/main/java/com/google/jetpackcamera/core/camera/lowlight/di/LowLightBoostModule.kt @@ -28,10 +28,10 @@ import javax.inject.Singleton @Module @InstallIn(SingletonComponent::class) -internal abstract class LowLightBoostModule { +internal interface LowLightBoostModule { @Multibinds - abstract fun availabilityCheckerEntries(): Set< + fun availabilityCheckerEntries(): Set< Map.Entry< LowLightBoostFeatureKey, @JvmSuppressWildcards Provider @@ -39,7 +39,7 @@ internal abstract class LowLightBoostModule { > @Multibinds - abstract fun effectProviderEntries(): Set< + fun effectProviderEntries(): Set< Map.Entry< LowLightBoostFeatureKey, @JvmSuppressWildcards Provider diff --git a/core/camera/postprocess/postprocess-di/src/main/java/com/google/jetpackcamera/core/camera/postprocess/di/PostProcessModule.kt b/core/camera/postprocess/postprocess-di/src/main/java/com/google/jetpackcamera/core/camera/postprocess/di/PostProcessModule.kt index e1ccc662b..2f697090a 100644 --- a/core/camera/postprocess/postprocess-di/src/main/java/com/google/jetpackcamera/core/camera/postprocess/di/PostProcessModule.kt +++ b/core/camera/postprocess/postprocess-di/src/main/java/com/google/jetpackcamera/core/camera/postprocess/di/PostProcessModule.kt @@ -27,9 +27,9 @@ import javax.inject.Singleton @Module @InstallIn(SingletonComponent::class) -internal abstract class PostProcessModule { +internal interface PostProcessModule { @Multibinds - abstract fun imagePostProcessorEntries(): Set< + fun imagePostProcessorEntries(): Set< Map.Entry< ImagePostProcessorFeatureKey, @JvmSuppressWildcards Provider diff --git a/data/media/src/main/kotlin/com/google/jetpackcamera/data/media/LocalMediaRepository.kt b/data/media/src/main/kotlin/com/google/jetpackcamera/data/media/LocalMediaRepository.kt index 2adb1823d..b9e02be06 100644 --- a/data/media/src/main/kotlin/com/google/jetpackcamera/data/media/LocalMediaRepository.kt +++ b/data/media/src/main/kotlin/com/google/jetpackcamera/data/media/LocalMediaRepository.kt @@ -32,9 +32,7 @@ import com.google.jetpackcamera.core.common.FilePathGenerator import java.io.File import java.io.IOException import kotlinx.coroutines.CoroutineDispatcher -import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.ExperimentalCoroutinesApi -import kotlinx.coroutines.SupervisorJob import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.flow.asStateFlow import kotlinx.coroutines.flow.update @@ -49,7 +47,6 @@ class LocalMediaRepository( private val iODispatcher: CoroutineDispatcher, private val filePathGenerator: FilePathGenerator ) : MediaRepository { - private val repositoryScope = CoroutineScope(iODispatcher + SupervisorJob()) private val _currentMedia = MutableStateFlow(MediaDescriptor.None) override val currentMedia = _currentMedia.asStateFlow() @@ -173,7 +170,7 @@ class LocalMediaRepository( * @return `true` if the media was successfully deleted, `false` otherwise. */ override suspend fun deleteMedia(mediaDescriptor: MediaDescriptor.Content): Boolean { - val finalResult = withContext(repositoryScope.coroutineContext) { + val finalResult = withContext(iODispatcher) { val result = if (mediaDescriptor.uri.scheme == ContentResolver.SCHEME_CONTENT) { deleteContentMedia(mediaDescriptor.uri) @@ -262,7 +259,7 @@ class LocalMediaRepository( override suspend fun saveToMediaStore( mediaDescriptor: MediaDescriptor.Content, outputFilename: String? - ): Uri? = withContext(repositoryScope.coroutineContext) { + ): Uri? = withContext(iODispatcher) { val finalOutputFilename: String val mimeType: String val mediaUrl: Uri From d7f588fdf2e9fe60ed2e818ecd0ec6eb31adfb71 Mon Sep 17 00:00:00 2001 From: davidjiagoogle Date: Wed, 5 Aug 2026 00:51:21 +0000 Subject: [PATCH 3/4] Fix PostProcessModule import in CameraXCameraSystemTest --- .../google/jetpackcamera/core/camera/CameraXCameraSystemTest.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/camera/src/androidTest/java/com/google/jetpackcamera/core/camera/CameraXCameraSystemTest.kt b/core/camera/src/androidTest/java/com/google/jetpackcamera/core/camera/CameraXCameraSystemTest.kt index e139929ca..f936ba40f 100644 --- a/core/camera/src/androidTest/java/com/google/jetpackcamera/core/camera/CameraXCameraSystemTest.kt +++ b/core/camera/src/androidTest/java/com/google/jetpackcamera/core/camera/CameraXCameraSystemTest.kt @@ -29,7 +29,7 @@ import com.google.jetpackcamera.core.camera.OnVideoRecordEvent.OnVideoRecordErro import com.google.jetpackcamera.core.camera.OnVideoRecordEvent.OnVideoRecorded import com.google.jetpackcamera.core.camera.postprocess.ImagePostProcessor import com.google.jetpackcamera.core.camera.postprocess.ImagePostProcessorFeatureKey -import com.google.jetpackcamera.core.camera.postprocess.PostProcessModule.Companion.provideImagePostProcessorMap +import com.google.jetpackcamera.core.camera.postprocess.di.PostProcessModule.Companion.provideImagePostProcessorMap import com.google.jetpackcamera.core.camera.utils.APP_REQUIRED_PERMISSIONS import com.google.jetpackcamera.core.camera.utils.provideUpdatingSurface import com.google.jetpackcamera.core.common.ignoreResult From 58162660a0fa82277e6e5053fbec3c3ef3807636 Mon Sep 17 00:00:00 2001 From: davidjiagoogle Date: Wed, 5 Aug 2026 00:56:43 +0000 Subject: [PATCH 4/4] Fix PostProcessModule visibility and add test dependency --- core/camera/build.gradle.kts | 1 + .../core/camera/postprocess/di/PostProcessModule.kt | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/core/camera/build.gradle.kts b/core/camera/build.gradle.kts index b87fb79ee..93d48ce5d 100644 --- a/core/camera/build.gradle.kts +++ b/core/camera/build.gradle.kts @@ -113,6 +113,7 @@ dependencies { androidTestImplementation(libs.kotlinx.coroutines.test) androidTestImplementation(libs.truth) androidTestImplementation(project(":core:common:testing")) + androidTestImplementation(project(":core:camera:postprocess:postprocess-di")) testImplementation(project(":core:camera:testing")) // Futures diff --git a/core/camera/postprocess/postprocess-di/src/main/java/com/google/jetpackcamera/core/camera/postprocess/di/PostProcessModule.kt b/core/camera/postprocess/postprocess-di/src/main/java/com/google/jetpackcamera/core/camera/postprocess/di/PostProcessModule.kt index 2f697090a..727ed867b 100644 --- a/core/camera/postprocess/postprocess-di/src/main/java/com/google/jetpackcamera/core/camera/postprocess/di/PostProcessModule.kt +++ b/core/camera/postprocess/postprocess-di/src/main/java/com/google/jetpackcamera/core/camera/postprocess/di/PostProcessModule.kt @@ -27,7 +27,7 @@ import javax.inject.Singleton @Module @InstallIn(SingletonComponent::class) -internal interface PostProcessModule { +interface PostProcessModule { @Multibinds fun imagePostProcessorEntries(): Set< Map.Entry<