From b7f84f65a8c84a1832827433b88fb14e35475199 Mon Sep 17 00:00:00 2001 From: ganfra Date: Wed, 14 Dec 2022 16:11:04 +0100 Subject: [PATCH] Continue setting up dagger --- app/build.gradle.kts | 16 +++++---- app/src/main/AndroidManifest.xml | 9 +++++ .../element/android/x/ElementXApplication.kt | 33 +++++++++-------- .../java/io/element/android/x/MainActivity.kt | 8 ++++- .../io/element/android/x/di/AppBindings.kt | 12 +++++++ .../io/element/android/x/di/AppComponent.kt | 16 +++++++++ .../java/io/element/android/x/di/AppModule.kt | 20 +++++++++++ .../android/x/initializer/CoilInitializer.kt | 36 +++++++++++++++++++ .../x/initializer/MavericksInitializer.kt | 16 +++++++++ .../x/initializer/TimberInitializer.kt | 14 ++++++++ gradle/libs.versions.toml | 6 +++- libraries/matrix/build.gradle.kts | 6 ++++ .../io/element/android/x/matrix/Matrix.kt | 12 ++++--- .../android/x/matrix/MatrixInstance.kt | 4 +-- 14 files changed, 177 insertions(+), 31 deletions(-) create mode 100644 app/src/main/java/io/element/android/x/di/AppBindings.kt create mode 100644 app/src/main/java/io/element/android/x/di/AppComponent.kt create mode 100644 app/src/main/java/io/element/android/x/di/AppModule.kt create mode 100644 app/src/main/java/io/element/android/x/initializer/CoilInitializer.kt create mode 100644 app/src/main/java/io/element/android/x/initializer/MavericksInitializer.kt create mode 100644 app/src/main/java/io/element/android/x/initializer/TimberInitializer.kt diff --git a/app/build.gradle.kts b/app/build.gradle.kts index 9c465615ea..c9c77fe66f 100644 --- a/app/build.gradle.kts +++ b/app/build.gradle.kts @@ -3,6 +3,7 @@ plugins { alias(libs.plugins.kotlin.android) alias(libs.plugins.ksp) alias(libs.plugins.anvil) + alias(libs.plugins.kapt) id("com.google.firebase.appdistribution") version "3.0.2" } @@ -101,16 +102,16 @@ android { } } - kotlin { - sourceSets.main { - kotlin.srcDir("build/generated/ksp/main/kotlin") - } - sourceSets.test { - kotlin.srcDir("build/generated/ksp/test/kotlin") + applicationVariants.all { + kotlin.sourceSets { + getByName(name) { + kotlin.srcDir("build/generated/ksp/$name/kotlin") + } } } } + dependencies { implementation(project(":libraries:designsystem")) implementation(project(":libraries:matrix")) @@ -119,6 +120,7 @@ dependencies { implementation(project(":features:login")) implementation(project(":features:roomlist")) implementation(project(":features:messages")) + implementation(project(":libraries:daggerscopes")) coreLibraryDesugaring("com.android.tools:desugar_jdk_libs:1.2.0") implementation(libs.compose.destinations) @@ -128,11 +130,13 @@ dependencies { implementation(libs.androidx.lifecycle.runtime) implementation(libs.androidx.lifecycle.viewmodel.compose) implementation(libs.androidx.activity.compose) + implementation(libs.androidx.startup) implementation(libs.coil) implementation(libs.timber) implementation(libs.mavericks.compose) implementation(libs.dagger) + kapt(libs.dagger.compiler) implementation(libs.showkase) ksp(libs.showkase.processor) diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 0a49fe2a4b..b82495751d 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -26,6 +26,15 @@ + + + + + \ No newline at end of file diff --git a/app/src/main/java/io/element/android/x/ElementXApplication.kt b/app/src/main/java/io/element/android/x/ElementXApplication.kt index 715b6c215b..7980a5aea4 100644 --- a/app/src/main/java/io/element/android/x/ElementXApplication.kt +++ b/app/src/main/java/io/element/android/x/ElementXApplication.kt @@ -1,32 +1,31 @@ package io.element.android.x import android.app.Application -import coil.ImageLoader -import coil.ImageLoaderFactory -import com.airbnb.mvrx.Mavericks +import androidx.startup.AppInitializer +import io.element.android.x.core.di.DaggerComponentOwner +import io.element.android.x.di.DaggerAppComponent +import io.element.android.x.initializer.CoilInitializer +import io.element.android.x.initializer.MavericksInitializer +import io.element.android.x.initializer.TimberInitializer import io.element.android.x.matrix.MatrixInstance import kotlinx.coroutines.CoroutineName import kotlinx.coroutines.MainScope import kotlinx.coroutines.plus -import timber.log.Timber -class ElementXApplication : Application(), ImageLoaderFactory { +class ElementXApplication : Application(), DaggerComponentOwner { + + override lateinit var daggerComponent: Any private val applicationScope = MainScope() + CoroutineName("ElementX Scope") override fun onCreate() { super.onCreate() - Timber.plant(Timber.DebugTree()) + daggerComponent = DaggerAppComponent.factory().create(this) MatrixInstance.init(this, applicationScope) - Mavericks.initialize(this) + AppInitializer.getInstance(this).apply { + initializeComponent(TimberInitializer::class.java) + initializeComponent(CoilInitializer::class.java) + initializeComponent(MavericksInitializer::class.java) + } } - - override fun newImageLoader(): ImageLoader { - return ImageLoader - .Builder(this) - .components { - MatrixInstance.getInstance().registerComponents(this) - } - .build() - } -} \ No newline at end of file +} diff --git a/app/src/main/java/io/element/android/x/MainActivity.kt b/app/src/main/java/io/element/android/x/MainActivity.kt index 68c524d52a..61bd7660cc 100644 --- a/app/src/main/java/io/element/android/x/MainActivity.kt +++ b/app/src/main/java/io/element/android/x/MainActivity.kt @@ -32,8 +32,11 @@ import com.google.accompanist.navigation.material.ExperimentalMaterialNavigation import com.ramcosta.composedestinations.DestinationsNavHost import com.ramcosta.composedestinations.animations.defaults.RootNavGraphDefaultAnimations import com.ramcosta.composedestinations.animations.rememberAnimatedNavHostEngine +import com.ramcosta.composedestinations.manualcomposablecalls.animatedComposable +import com.ramcosta.composedestinations.navigation.dependency import com.ramcosta.composedestinations.spec.Route import io.element.android.x.core.compose.OnLifecycleEvent +import io.element.android.x.core.di.DaggerComponentOwner import io.element.android.x.designsystem.ElementXTheme import io.element.android.x.destinations.OnBoardingScreenNavigationDestination import kotlinx.coroutines.runBlocking @@ -147,7 +150,10 @@ class MainActivity : ComponentActivity() { engine = engine, navController = navController, navGraph = NavGraphs.root, - startRoute = startRoute + startRoute = startRoute, + dependenciesContainerBuilder = { + + } ) } diff --git a/app/src/main/java/io/element/android/x/di/AppBindings.kt b/app/src/main/java/io/element/android/x/di/AppBindings.kt new file mode 100644 index 0000000000..b11192b8b1 --- /dev/null +++ b/app/src/main/java/io/element/android/x/di/AppBindings.kt @@ -0,0 +1,12 @@ +package io.element.android.x.di + +import com.squareup.anvil.annotations.ContributesTo +import io.element.android.x.di.AppScope +import io.element.android.x.matrix.Matrix +import kotlinx.coroutines.CoroutineScope + +@ContributesTo(AppScope::class) +interface AppBindings { + fun coroutineScope(): CoroutineScope + fun matrix(): Matrix +} \ No newline at end of file diff --git a/app/src/main/java/io/element/android/x/di/AppComponent.kt b/app/src/main/java/io/element/android/x/di/AppComponent.kt new file mode 100644 index 0000000000..b12230cbee --- /dev/null +++ b/app/src/main/java/io/element/android/x/di/AppComponent.kt @@ -0,0 +1,16 @@ +package io.element.android.x.di + +import android.app.Application +import com.squareup.anvil.annotations.MergeComponent +import dagger.BindsInstance +import dagger.Component + +@SingleIn(AppScope::class) +@MergeComponent(AppScope::class) +interface AppComponent { + + @Component.Factory + interface Factory { + fun create(@BindsInstance application: Application): AppComponent + } +} \ No newline at end of file diff --git a/app/src/main/java/io/element/android/x/di/AppModule.kt b/app/src/main/java/io/element/android/x/di/AppModule.kt new file mode 100644 index 0000000000..681365aa9f --- /dev/null +++ b/app/src/main/java/io/element/android/x/di/AppModule.kt @@ -0,0 +1,20 @@ +package io.element.android.x.di + +import com.squareup.anvil.annotations.ContributesTo +import dagger.Module +import dagger.Provides +import kotlinx.coroutines.CoroutineName +import kotlinx.coroutines.CoroutineScope +import kotlinx.coroutines.MainScope +import kotlinx.coroutines.plus + +@Module +@ContributesTo(AppScope::class) +object AppModule { + + @Provides + @SingleIn(AppScope::class) + fun providesAppCoroutineScope(): CoroutineScope { + return MainScope() + CoroutineName("ElementX Scope") + } +} \ No newline at end of file diff --git a/app/src/main/java/io/element/android/x/initializer/CoilInitializer.kt b/app/src/main/java/io/element/android/x/initializer/CoilInitializer.kt new file mode 100644 index 0000000000..8db0737e51 --- /dev/null +++ b/app/src/main/java/io/element/android/x/initializer/CoilInitializer.kt @@ -0,0 +1,36 @@ +package io.element.android.x.initializer + +import android.content.Context +import androidx.startup.Initializer +import coil.Coil +import coil.ImageLoader +import coil.ImageLoaderFactory +import io.element.android.x.core.di.DaggerComponentOwner +import io.element.android.x.core.di.bindings +import io.element.android.x.di.AppBindings +import io.element.android.x.di.AppComponent + +class CoilInitializer : Initializer { + + override fun create(context: Context) { + Coil.setImageLoader(ElementImageLoaderFactory(context)) + } + + override fun dependencies(): MutableList>> = mutableListOf() +} + +private class ElementImageLoaderFactory( + private val context: Context +) : + ImageLoaderFactory { + override fun newImageLoader(): ImageLoader { + return ImageLoader + .Builder(context) + .components { + context.bindings().matrix().registerCoilComponents(this) + } + .build() + } + + +} \ No newline at end of file diff --git a/app/src/main/java/io/element/android/x/initializer/MavericksInitializer.kt b/app/src/main/java/io/element/android/x/initializer/MavericksInitializer.kt new file mode 100644 index 0000000000..fe6fcc07df --- /dev/null +++ b/app/src/main/java/io/element/android/x/initializer/MavericksInitializer.kt @@ -0,0 +1,16 @@ +package io.element.android.x.initializer + +import android.content.Context +import androidx.startup.Initializer +import com.airbnb.mvrx.Mavericks + +class MavericksInitializer : Initializer { + + override fun create(context: Context) { + Mavericks.initialize(context) + } + + override fun dependencies(): MutableList>> = mutableListOf() + + +} \ No newline at end of file diff --git a/app/src/main/java/io/element/android/x/initializer/TimberInitializer.kt b/app/src/main/java/io/element/android/x/initializer/TimberInitializer.kt new file mode 100644 index 0000000000..e8fe1f7118 --- /dev/null +++ b/app/src/main/java/io/element/android/x/initializer/TimberInitializer.kt @@ -0,0 +1,14 @@ +package io.element.android.x.initializer + +import android.content.Context +import androidx.startup.Initializer +import timber.log.Timber + +class TimberInitializer: Initializer { + + override fun create(context: Context) { + Timber.plant(Timber.DebugTree()) + } + + override fun dependencies(): MutableList>> = mutableListOf() +} \ No newline at end of file diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 2eed05aef1..704c0236ac 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -14,6 +14,7 @@ recyclerview = "1.2.1" lifecycle = "2.5.1" activity_compose = "1.6.1" fragment = "1.5.5" +startup = "1.1.1" # Compose compose_compiler = "1.3.2" @@ -48,7 +49,7 @@ compose_destinations = "1.7.23-beta" jsoup = "1.15.3" # DI -dagger = "2.32" +dagger = "2.43" anvil = "2.4.2" [libraries] @@ -68,6 +69,7 @@ androidx_lifecycle_runtime = { module = "androidx.lifecycle:lifecycle-runtime-kt androidx_lifecycle_viewmodel_compose = { module = "androidx.lifecycle:lifecycle-viewmodel-compose", version.ref = "lifecycle" } androidx_activity_compose = { module = "androidx.activity:activity-compose", version.ref = "activity_compose" } androidx_fragment = {module = "androidx.fragment:fragment-ktx", version.ref = "fragment"} +androidx_startup = { module = "androidx.startup:startup-runtime", version.ref = "startup"} androidx_compose_bom = { group = "androidx.compose", name = "compose-bom", version.ref = "compose_bom" } androidx_compose_foundation = { group = "androidx.compose.foundation", name = "foundation" } @@ -111,9 +113,11 @@ showkase = { module = "com.airbnb.android:showkase", version.ref = "showkase" } showkase_processor = { module = "com.airbnb.android:showkase-processor", version.ref = "showkase" } jsoup = { module = "org.jsoup:jsoup", version.ref = "jsoup" } + # Di inject = {module = "javax.inject:javax.inject", version = "1"} dagger = { module = "com.google.dagger:dagger", version.ref = "dagger" } +dagger_compiler = { module = "com.google.dagger:dagger-compiler", version.ref = "dagger" } anvil_compiler_api = { module = "com.squareup.anvil:compiler-api", version.ref = "anvil" } anvil_compiler_utils = { module = "com.squareup.anvil:compiler-utils", version.ref = "anvil" } diff --git a/libraries/matrix/build.gradle.kts b/libraries/matrix/build.gradle.kts index b420b32794..5001895635 100644 --- a/libraries/matrix/build.gradle.kts +++ b/libraries/matrix/build.gradle.kts @@ -1,5 +1,6 @@ plugins { id("io.element.android-library") + alias(libs.plugins.anvil) kotlin("plugin.serialization") version "1.7.20" } @@ -7,8 +8,13 @@ android { namespace = "io.element.android.x.sdk.matrix" } +anvil { + generateDaggerFactories.set(true) +} + dependencies { api(project(":libraries:rustsdk")) + implementation(project(":libraries:daggerscopes")) implementation(project(":libraries:core")) implementation(libs.timber) implementation("net.java.dev.jna:jna:5.12.1@aar") diff --git a/libraries/matrix/src/main/java/io/element/android/x/matrix/Matrix.kt b/libraries/matrix/src/main/java/io/element/android/x/matrix/Matrix.kt index 5be629b7f8..e6a7cdda2c 100644 --- a/libraries/matrix/src/main/java/io/element/android/x/matrix/Matrix.kt +++ b/libraries/matrix/src/main/java/io/element/android/x/matrix/Matrix.kt @@ -1,8 +1,10 @@ package io.element.android.x.matrix -import android.content.Context +import android.app.Application import coil.ComponentRegistry import io.element.android.x.core.coroutine.CoroutineDispatchers +import io.element.android.x.di.AppScope +import io.element.android.x.di.SingleIn import io.element.android.x.matrix.media.MediaFetcher import io.element.android.x.matrix.media.MediaKeyer import io.element.android.x.matrix.session.SessionStore @@ -19,10 +21,12 @@ import timber.log.Timber import java.io.File import java.util.* import java.util.concurrent.Executors +import javax.inject.Inject -class Matrix( +@SingleIn(AppScope::class) +class Matrix @Inject constructor( private val coroutineScope: CoroutineScope, - context: Context, + context: Application, ) { private val coroutineDispatchers = CoroutineDispatchers( io = Dispatchers.IO, @@ -58,7 +62,7 @@ class Matrix( return matrixClient.value.get() } - fun registerComponents(builder: ComponentRegistry.Builder) { + fun registerCoilComponents(builder: ComponentRegistry.Builder) { builder.add(MediaKeyer()) builder.add(MediaFetcher.Factory(this)) } diff --git a/libraries/matrix/src/main/java/io/element/android/x/matrix/MatrixInstance.kt b/libraries/matrix/src/main/java/io/element/android/x/matrix/MatrixInstance.kt index b7173b0b2b..6497791622 100644 --- a/libraries/matrix/src/main/java/io/element/android/x/matrix/MatrixInstance.kt +++ b/libraries/matrix/src/main/java/io/element/android/x/matrix/MatrixInstance.kt @@ -1,7 +1,7 @@ package io.element.android.x.matrix import android.annotation.SuppressLint -import android.content.Context +import android.app.Application import io.element.android.x.matrix.tracing.TracingConfigurations import io.element.android.x.matrix.tracing.setupTracing import io.element.android.x.sdk.matrix.BuildConfig @@ -12,7 +12,7 @@ object MatrixInstance { @SuppressLint("StaticFieldLeak") private lateinit var instance: Matrix - fun init(context: Context, coroutineScope: CoroutineScope) { + fun init(context: Application, coroutineScope: CoroutineScope) { if (BuildConfig.DEBUG) { setupTracing(TracingConfigurations.debug) } else {