Start migrating Anvil KSP to Metro

This commit is contained in:
Jorge Martín 2025-08-20 15:29:50 +02:00
parent d4d57b1e21
commit b76a71ebf5
703 changed files with 3523 additions and 2820 deletions

View file

@ -9,16 +9,18 @@ package io.element.android.x
import android.app.Application
import androidx.startup.AppInitializer
import dev.zacsweers.metro.asContribution
import dev.zacsweers.metro.createGraphFactory
import io.element.android.features.cachecleaner.api.CacheCleanerInitializer
import io.element.android.libraries.di.DaggerComponentOwner
import io.element.android.x.di.AppComponent
import io.element.android.x.di.DaggerAppComponent
import io.element.android.x.di.globalGraph
import io.element.android.x.info.logApplicationInfo
import io.element.android.x.initializer.CrashInitializer
import io.element.android.x.initializer.PlatformInitializer
class ElementXApplication : Application(), DaggerComponentOwner {
override val daggerComponent: AppComponent = DaggerAppComponent.factory().create(this)
override val daggerComponent: AppComponent = globalGraph.asContribution<AppComponent.Factory>().create(this)
override fun onCreate() {
super.onCreate()

View file

@ -21,7 +21,7 @@ import com.bumble.appyx.core.node.ParentNode
import com.bumble.appyx.core.plugin.Plugin
import io.element.android.appnav.RootFlowNode
import io.element.android.libraries.architecture.createNode
import io.element.android.libraries.di.ApplicationContext
import io.element.android.libraries.di.annotations.ApplicationContext
import io.element.android.libraries.di.DaggerComponentOwner
import kotlinx.coroutines.launch
import kotlinx.parcelize.Parcelize

View file

@ -7,7 +7,7 @@
package io.element.android.x.di
import com.squareup.anvil.annotations.ContributesTo
import dev.zacsweers.metro.ContributesTo
import io.element.android.features.api.MigrationEntryPoint
import io.element.android.features.enterprise.api.EnterpriseService
import io.element.android.features.lockscreen.api.LockScreenEntryPoint
@ -15,7 +15,7 @@ import io.element.android.features.lockscreen.api.LockScreenService
import io.element.android.features.rageshake.api.reporter.BugReporter
import io.element.android.libraries.core.meta.BuildMeta
import io.element.android.libraries.designsystem.utils.snackbar.SnackbarDispatcher
import io.element.android.libraries.di.AppScope
import dev.zacsweers.metro.AppScope
import io.element.android.libraries.featureflag.api.FeatureFlagService
import io.element.android.libraries.matrix.api.platform.InitPlatformService
import io.element.android.libraries.matrix.api.tracing.TracingService

View file

@ -1,5 +1,5 @@
/*
* Copyright 2023, 2024 New Vector Ltd.
* Copyright 2025 New Vector Ltd.
*
* SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-Element-Commercial
* Please see LICENSE files in the repository root for full details.
@ -8,20 +8,22 @@
package io.element.android.x.di
import android.content.Context
import com.squareup.anvil.annotations.MergeComponent
import dagger.BindsInstance
import dev.zacsweers.metro.ContributesTo
import dev.zacsweers.metro.GraphExtension
import dev.zacsweers.metro.Provides
import io.element.android.libraries.architecture.NodeFactoriesBindings
import io.element.android.libraries.di.AppScope
import io.element.android.libraries.di.ApplicationContext
import io.element.android.libraries.di.SingleIn
import dev.zacsweers.metro.AppScope
import io.element.android.libraries.di.annotations.ApplicationContext
@SingleIn(AppScope::class)
@MergeComponent(AppScope::class)
@GraphExtension(AppScope::class)
interface AppComponent : NodeFactoriesBindings {
@MergeComponent.Factory
val sessionComponentFactory: SessionComponent.Factory
@ContributesTo(GlobalScope::class)
@GraphExtension.Factory
interface Factory {
fun create(
@ApplicationContext @BindsInstance
@ApplicationContext @Provides
context: Context
): AppComponent
}

View file

@ -11,9 +11,10 @@ import android.content.Context
import android.content.SharedPreferences
import android.content.res.Resources
import androidx.preference.PreferenceManager
import com.squareup.anvil.annotations.ContributesTo
import dagger.Module
import dagger.Provides
import dev.zacsweers.metro.BindingContainer
import dev.zacsweers.metro.ContributesTo
import dev.zacsweers.metro.Named
import dev.zacsweers.metro.Provides
import io.element.android.appconfig.ApplicationConfig
import io.element.android.features.enterprise.api.EnterpriseService
import io.element.android.features.messages.impl.timeline.components.customreaction.DefaultEmojibaseProvider
@ -23,10 +24,10 @@ import io.element.android.libraries.core.coroutine.CoroutineDispatchers
import io.element.android.libraries.core.meta.BuildMeta
import io.element.android.libraries.core.meta.BuildType
import io.element.android.libraries.designsystem.utils.snackbar.SnackbarDispatcher
import io.element.android.libraries.di.AppScope
import io.element.android.libraries.di.ApplicationContext
import dev.zacsweers.metro.AppScope
import io.element.android.libraries.di.annotations.ApplicationContext
import io.element.android.libraries.di.CacheDirectory
import io.element.android.libraries.di.SingleIn
import dev.zacsweers.metro.SingleIn
import io.element.android.libraries.di.annotations.AppCoroutineScope
import io.element.android.x.BuildConfig
import io.element.android.x.R
@ -37,16 +38,17 @@ import kotlinx.coroutines.MainScope
import kotlinx.coroutines.plus
import java.io.File
@Module
@BindingContainer
@ContributesTo(AppScope::class)
object AppModule {
@Provides
@Named("baseDirectory")
fun providesBaseDirectory(@ApplicationContext context: Context): File {
return File(context.filesDir, "sessions")
}
@Provides
@CacheDirectory
@Named("cacheDirectory")
fun providesCacheDirectory(@ApplicationContext context: Context): File {
return context.cacheDir
}

View file

@ -7,20 +7,19 @@
package io.element.android.x.di
import com.squareup.anvil.annotations.ContributesBinding
import dev.zacsweers.metro.ContributesBinding
import io.element.android.appnav.di.RoomComponentFactory
import io.element.android.libraries.di.SessionScope
import io.element.android.libraries.matrix.api.room.JoinedRoom
import javax.inject.Inject
import dev.zacsweers.metro.Inject
@ContributesBinding(SessionScope::class)
class DefaultRoomComponentFactory @Inject constructor(
private val roomComponentBuilder: RoomComponent.Builder
@Inject
class DefaultRoomComponentFactory(
private val sessionComponent: SessionComponent,
) : RoomComponentFactory {
override fun create(room: JoinedRoom): Any {
return roomComponentBuilder
.joinedRoom(room)
.baseRoom(room)
.build()
return sessionComponent.roomComponentFactory
.create(room, room)
}
}

View file

@ -7,17 +7,18 @@
package io.element.android.x.di
import com.squareup.anvil.annotations.ContributesBinding
import dev.zacsweers.metro.AppScope
import dev.zacsweers.metro.ContributesBinding
import dev.zacsweers.metro.Inject
import io.element.android.appnav.di.SessionComponentFactory
import io.element.android.libraries.di.AppScope
import io.element.android.libraries.matrix.api.MatrixClient
import javax.inject.Inject
@ContributesBinding(AppScope::class)
class DefaultSessionComponentFactory @Inject constructor(
private val sessionComponentBuilder: SessionComponent.Builder
@Inject
class DefaultSessionComponentFactory(
private val appComponent: AppComponent
) : SessionComponentFactory {
override fun create(client: MatrixClient): Any {
return sessionComponentBuilder.client(client).build()
return appComponent.sessionComponentFactory.createSessionComponent(client)
}
}

View file

@ -0,0 +1,16 @@
/*
* Copyright 2025 New Vector Ltd.
*
* SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-Element-Commercial
* Please see LICENSE files in the repository root for full details.
*/
package io.element.android.x.di
import dev.zacsweers.metro.DependencyGraph
import dev.zacsweers.metro.createGraph
@DependencyGraph(GlobalScope::class)
interface GlobalGraph
internal val globalGraph = createGraph<GlobalGraph>()

View file

@ -0,0 +1,10 @@
/*
* Copyright 2025 New Vector Ltd.
*
* SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-Element-Commercial
* Please see LICENSE files in the repository root for full details.
*/
package io.element.android.x.di
class GlobalScope private constructor()

View file

@ -1,5 +1,5 @@
/*
* Copyright 2023, 2024 New Vector Ltd.
* Copyright 2025 New Vector Ltd.
*
* SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-Element-Commercial
* Please see LICENSE files in the repository root for full details.
@ -7,32 +7,24 @@
package io.element.android.x.di
import com.squareup.anvil.annotations.ContributesTo
import com.squareup.anvil.annotations.MergeSubcomponent
import dagger.BindsInstance
import dev.zacsweers.metro.ContributesTo
import dev.zacsweers.metro.GraphExtension
import dev.zacsweers.metro.Provides
import io.element.android.libraries.architecture.NodeFactoriesBindings
import dev.zacsweers.metro.SingleIn
import io.element.android.libraries.di.RoomScope
import io.element.android.libraries.di.SessionScope
import io.element.android.libraries.di.SingleIn
import io.element.android.libraries.matrix.api.room.BaseRoom
import io.element.android.libraries.matrix.api.room.JoinedRoom
@SingleIn(RoomScope::class)
@MergeSubcomponent(RoomScope::class)
@GraphExtension(RoomScope::class)
interface RoomComponent : NodeFactoriesBindings {
@MergeSubcomponent.Builder
interface Builder {
@BindsInstance
fun joinedRoom(room: JoinedRoom): Builder
@BindsInstance
fun baseRoom(room: BaseRoom): Builder
fun build(): RoomComponent
}
@ContributesTo(SessionScope::class)
interface ParentBindings {
fun roomComponentBuilder(): Builder
@GraphExtension.Factory
interface Factory {
fun create(
@Provides joinedRoom: JoinedRoom,
@Provides baseRoom: BaseRoom
): RoomComponent
}
}

View file

@ -1,5 +1,5 @@
/*
* Copyright 2023, 2024 New Vector Ltd.
* Copyright 2025 New Vector Ltd.
*
* SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-Element-Commercial
* Please see LICENSE files in the repository root for full details.
@ -7,28 +7,21 @@
package io.element.android.x.di
import com.squareup.anvil.annotations.ContributesTo
import com.squareup.anvil.annotations.MergeSubcomponent
import dagger.BindsInstance
import dev.zacsweers.metro.AppScope
import dev.zacsweers.metro.ContributesTo
import dev.zacsweers.metro.GraphExtension
import dev.zacsweers.metro.Provides
import io.element.android.libraries.architecture.NodeFactoriesBindings
import io.element.android.libraries.di.AppScope
import io.element.android.libraries.di.SessionScope
import io.element.android.libraries.di.SingleIn
import io.element.android.libraries.matrix.api.MatrixClient
@SingleIn(SessionScope::class)
@MergeSubcomponent(SessionScope::class)
@GraphExtension(SessionScope::class)
interface SessionComponent : NodeFactoriesBindings {
@MergeSubcomponent.Builder
interface Builder {
@BindsInstance
fun client(matrixClient: MatrixClient): Builder
fun build(): SessionComponent
}
val roomComponentFactory: RoomComponent.Factory
@ContributesTo(AppScope::class)
interface ParentBindings {
fun sessionComponentBuilder(): Builder
@GraphExtension.Factory
interface Factory {
fun createSessionComponent(@Provides matrixClient: MatrixClient): SessionComponent
}
}

View file

@ -10,19 +10,20 @@ package io.element.android.x.intent
import android.content.Context
import android.content.Intent
import androidx.core.net.toUri
import com.squareup.anvil.annotations.ContributesBinding
import dev.zacsweers.metro.AppScope
import dev.zacsweers.metro.ContributesBinding
import dev.zacsweers.metro.Inject
import io.element.android.libraries.deeplink.api.DeepLinkCreator
import io.element.android.libraries.di.AppScope
import io.element.android.libraries.di.ApplicationContext
import io.element.android.libraries.matrix.api.core.RoomId
import io.element.android.libraries.matrix.api.core.SessionId
import io.element.android.libraries.matrix.api.core.ThreadId
import io.element.android.libraries.push.impl.intent.IntentProvider
import io.element.android.x.MainActivity
import javax.inject.Inject
@ContributesBinding(AppScope::class)
class DefaultIntentProvider @Inject constructor(
@Inject
class DefaultIntentProvider(
@ApplicationContext private val context: Context,
private val deepLinkCreator: DeepLinkCreator,
) : IntentProvider {

View file

@ -7,15 +7,16 @@
package io.element.android.x.oidc
import com.squareup.anvil.annotations.ContributesBinding
import io.element.android.libraries.di.AppScope
import dev.zacsweers.metro.ContributesBinding
import dev.zacsweers.metro.AppScope
import io.element.android.libraries.matrix.api.auth.OidcRedirectUrlProvider
import io.element.android.services.toolbox.api.strings.StringProvider
import io.element.android.x.R
import javax.inject.Inject
import dev.zacsweers.metro.Inject
@ContributesBinding(AppScope::class)
class DefaultOidcRedirectUrlProvider @Inject constructor(
@Inject
class DefaultOidcRedirectUrlProvider(
private val stringProvider: StringProvider,
) : OidcRedirectUrlProvider {
override fun provide() = buildString {