Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 12 additions & 0 deletions app/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down Expand Up @@ -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"))
}
Expand Down
6 changes: 2 additions & 4 deletions app/src/main/java/com/google/jetpackcamera/AppModule.kt
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -40,7 +39,6 @@ object AppModule {
* provides the default [SaveMode] to be used by the app
*/
@Provides
@DefaultSaveMode
fun providesSaveMode(): SaveMode = SaveMode.Immediate
Comment thread
davidjiagoogle marked this conversation as resolved.

@Provides
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
54 changes: 54 additions & 0 deletions app/src/main/java/com/google/jetpackcamera/di/AppQualifiers.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
/*
* 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)
annotation class DefaultFilePathGenerator

/**
* Identifies the fallback capture mode override when initializing repository settings.
*/
@Qualifier
@Retention(AnnotationRetention.BINARY)
annotation class DefaultCaptureModeOverride

/**
* Identifies the CPU-bound [kotlinx.coroutines.CoroutineDispatcher] used for general computation.
*/
@Qualifier
@Retention(AnnotationRetention.BINARY)
annotation class DefaultDispatcher

/**
* Identifies the I/O-bound [kotlinx.coroutines.CoroutineDispatcher] used for disk and network tasks.
*/
@Qualifier
@Retention(AnnotationRetention.BINARY)
annotation class IODispatcher

/**
* Identifies the root application-level [kotlinx.coroutines.CoroutineScope] tied to SingletonComponent lifecycle.
*/
@Qualifier
@Retention(AnnotationRetention.BINARY)
annotation class DefaultCoroutineScope
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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
Expand All @@ -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
Expand Down
Original file line number Diff line number Diff line change
@@ -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.
Expand All @@ -13,25 +13,24 @@
* 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
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 object CommonModule {
@Provides
@DefaultDispatcher
fun provideDefaultDispatcher(): CoroutineDispatcher = Dispatchers.Default
Expand All @@ -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
Original file line number Diff line number Diff line change
Expand Up @@ -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)
}
}
1 change: 1 addition & 0 deletions core/camera/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,14 +32,12 @@ import javax.inject.Provider
internal object EffectsModule {
@Provides
@IntoSet
fun provideSingleStreamEffectProviderEntry(
impl: Provider<SingleStreamEffectProvider>
): Map.Entry<
fun provideSingleStreamEffectProviderEntry(): Map.Entry<
CameraEffectFeatureKey,
@JvmSuppressWildcards Provider<CameraEffectProvider>
> =
AbstractMap.SimpleImmutableEntry(
SingleStreamEffectKey,
Provider { impl.get() }
Provider { SingleStreamEffectProvider() }
)
}
Original file line number Diff line number Diff line change
Expand Up @@ -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<CameraEffectTarget> = setOf(
CameraEffectTarget.PREVIEW,
Expand Down
51 changes: 51 additions & 0 deletions core/camera/low-light-playservices-di/build.gradle.kts
Original file line number Diff line number Diff line change
@@ -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
}
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -33,27 +37,25 @@ object PlayServicesLowLightBoostFeatureKey : LowLightBoostFeatureKey
internal object PlayServicesLowLightBoostModule {
@Provides
@IntoSet
fun provideAvailabilityCheckerEntry(
impl: Provider<PlayServicesLowLightBoostAvailabilityChecker>
): Map.Entry<
fun provideAvailabilityCheckerEntry(): Map.Entry<
LowLightBoostFeatureKey,
@JvmSuppressWildcards Provider<LowLightBoostAvailabilityChecker>
> =
AbstractMap.SimpleImmutableEntry(
PlayServicesLowLightBoostFeatureKey,
Provider { impl.get() }
Provider { PlayServicesLowLightBoostAvailabilityChecker() }
)

@Provides
@IntoSet
fun provideEffectProviderEntry(
impl: Provider<PlayServicesLowLightBoostEffectProvider>
@ApplicationContext context: Context
): Map.Entry<
LowLightBoostFeatureKey,
@JvmSuppressWildcards Provider<LowLightBoostEffectProvider>
> =
AbstractMap.SimpleImmutableEntry(
PlayServicesLowLightBoostFeatureKey,
Provider { impl.get() }
Provider { PlayServicesLowLightBoostEffectProvider(context) }
)
}
Loading
Loading