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

@ -7,16 +7,17 @@
package io.element.android.features.rageshake.impl
import com.squareup.anvil.annotations.ContributesBinding
import dev.zacsweers.metro.ContributesBinding
import io.element.android.features.rageshake.api.RageshakeFeatureAvailability
import io.element.android.features.rageshake.impl.reporter.BugReporterUrlProvider
import io.element.android.libraries.di.AppScope
import dev.zacsweers.metro.AppScope
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.map
import javax.inject.Inject
import dev.zacsweers.metro.Inject
@ContributesBinding(AppScope::class)
class DefaultRageshakeFeatureAvailability @Inject constructor(
@Inject
class DefaultRageshakeFeatureAvailability(
private val bugReporterUrlProvider: BugReporterUrlProvider,
) : RageshakeFeatureAvailability {
override fun isAvailable(): Flow<Boolean> {

View file

@ -14,17 +14,18 @@ import com.bumble.appyx.core.modality.BuildContext
import com.bumble.appyx.core.node.Node
import com.bumble.appyx.core.plugin.Plugin
import com.bumble.appyx.core.plugin.plugins
import dagger.assisted.Assisted
import dagger.assisted.AssistedInject
import dev.zacsweers.metro.Assisted
import dev.zacsweers.metro.Inject
import io.element.android.anvilannotations.ContributesNode
import io.element.android.features.rageshake.api.bugreport.BugReportEntryPoint
import io.element.android.features.rageshake.api.reporter.BugReporter
import io.element.android.libraries.androidutils.system.toast
import io.element.android.libraries.di.AppScope
import dev.zacsweers.metro.AppScope
import io.element.android.libraries.ui.strings.CommonStrings
@ContributesNode(AppScope::class)
class BugReportNode @AssistedInject constructor(
@Inject
class BugReportNode(
@Assisted buildContext: BuildContext,
@Assisted plugins: List<Plugin>,
private val presenter: BugReportPresenter,

View file

@ -25,9 +25,10 @@ import io.element.android.libraries.architecture.Presenter
import io.element.android.libraries.di.annotations.AppCoroutineScope
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.launch
import javax.inject.Inject
import dev.zacsweers.metro.Inject
class BugReportPresenter @Inject constructor(
@Inject
class BugReportPresenter(
private val bugReporter: BugReporter,
private val crashDataStore: CrashDataStore,
private val screenshotHolder: ScreenshotHolder,

View file

@ -10,14 +10,15 @@ package io.element.android.features.rageshake.impl.bugreport
import com.bumble.appyx.core.modality.BuildContext
import com.bumble.appyx.core.node.Node
import com.bumble.appyx.core.plugin.Plugin
import com.squareup.anvil.annotations.ContributesBinding
import dev.zacsweers.metro.ContributesBinding
import io.element.android.features.rageshake.api.bugreport.BugReportEntryPoint
import io.element.android.libraries.architecture.createNode
import io.element.android.libraries.di.AppScope
import javax.inject.Inject
import dev.zacsweers.metro.AppScope
import dev.zacsweers.metro.Inject
@ContributesBinding(AppScope::class)
class DefaultBugReportEntryPoint @Inject constructor() : BugReportEntryPoint {
@Inject
class DefaultBugReportEntryPoint() : BugReportEntryPoint {
override fun nodeBuilder(parentNode: Node, buildContext: BuildContext): BugReportEntryPoint.NodeBuilder {
val plugins = ArrayList<Plugin>()

View file

@ -14,22 +14,23 @@ import androidx.compose.runtime.collectAsState
import androidx.compose.runtime.getValue
import androidx.compose.runtime.remember
import androidx.compose.runtime.rememberCoroutineScope
import com.squareup.anvil.annotations.ContributesBinding
import dev.zacsweers.metro.ContributesBinding
import io.element.android.features.rageshake.api.RageshakeFeatureAvailability
import io.element.android.features.rageshake.api.crash.CrashDetectionEvents
import io.element.android.features.rageshake.api.crash.CrashDetectionPresenter
import io.element.android.features.rageshake.api.crash.CrashDetectionState
import io.element.android.libraries.core.meta.BuildMeta
import io.element.android.libraries.di.AppScope
import dev.zacsweers.metro.AppScope
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.flow.flatMapLatest
import kotlinx.coroutines.flow.flowOf
import kotlinx.coroutines.launch
import javax.inject.Inject
import dev.zacsweers.metro.Inject
@ContributesBinding(AppScope::class)
class DefaultCrashDetectionPresenter @Inject constructor(
@Inject
class DefaultCrashDetectionPresenter(
private val buildMeta: BuildMeta,
private val crashDataStore: CrashDataStore,
private val rageshakeFeatureAvailability: RageshakeFeatureAvailability,

View file

@ -10,20 +10,21 @@ package io.element.android.features.rageshake.impl.crash
import androidx.datastore.preferences.core.booleanPreferencesKey
import androidx.datastore.preferences.core.edit
import androidx.datastore.preferences.core.stringPreferencesKey
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.core.bool.orFalse
import io.element.android.libraries.di.AppScope
import io.element.android.libraries.preferences.api.store.PreferenceDataStoreFactory
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.map
import kotlinx.coroutines.runBlocking
import javax.inject.Inject
private val appHasCrashedKey = booleanPreferencesKey("appHasCrashed")
private val crashDataKey = stringPreferencesKey("crashData")
@ContributesBinding(AppScope::class)
class PreferencesCrashDataStore @Inject constructor(
@Inject
class PreferencesCrashDataStore(
preferenceDataStoreFactory: PreferenceDataStoreFactory,
) : CrashDataStore {
private val store = preferenceDataStoreFactory.create("elementx_crash")

View file

@ -14,7 +14,7 @@ import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.rememberCoroutineScope
import androidx.compose.runtime.saveable.rememberSaveable
import com.squareup.anvil.annotations.ContributesBinding
import dev.zacsweers.metro.ContributesBinding
import io.element.android.features.rageshake.api.detection.RageshakeDetectionEvents
import io.element.android.features.rageshake.api.detection.RageshakeDetectionPresenter
import io.element.android.features.rageshake.api.detection.RageshakeDetectionState
@ -23,14 +23,15 @@ import io.element.android.features.rageshake.api.preferences.RageshakePreference
import io.element.android.features.rageshake.api.screenshot.ImageResult
import io.element.android.features.rageshake.impl.rageshake.RageShake
import io.element.android.features.rageshake.impl.screenshot.ScreenshotHolder
import io.element.android.libraries.di.AppScope
import dev.zacsweers.metro.AppScope
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.launch
import timber.log.Timber
import javax.inject.Inject
import dev.zacsweers.metro.Inject
@ContributesBinding(AppScope::class)
class DefaultRageshakeDetectionPresenter @Inject constructor(
@Inject
class DefaultRageshakeDetectionPresenter(
private val screenshotHolder: ScreenshotHolder,
private val rageShake: RageShake,
private val preferencesPresenter: RageshakePreferencesPresenter,

View file

@ -7,9 +7,9 @@
package io.element.android.features.rageshake.impl.di
import com.squareup.anvil.annotations.ContributesTo
import dagger.Binds
import dagger.Module
import dev.zacsweers.metro.BindingContainer
import dev.zacsweers.metro.Binds
import dev.zacsweers.metro.ContributesTo
import io.element.android.features.rageshake.api.crash.CrashDetectionPresenter
import io.element.android.features.rageshake.api.crash.CrashDetectionState
import io.element.android.features.rageshake.api.detection.RageshakeDetectionPresenter
@ -17,10 +17,10 @@ import io.element.android.features.rageshake.api.detection.RageshakeDetectionSta
import io.element.android.features.rageshake.api.preferences.RageshakePreferencesPresenter
import io.element.android.features.rageshake.api.preferences.RageshakePreferencesState
import io.element.android.libraries.architecture.Presenter
import io.element.android.libraries.di.AppScope
import dev.zacsweers.metro.AppScope
@ContributesTo(AppScope::class)
@Module
@BindingContainer
interface RageshakeModule {
@Binds
fun bindRageshakePreferencesPresenter(presenter: RageshakePreferencesPresenter): Presenter<RageshakePreferencesState>

View file

@ -7,15 +7,16 @@
package io.element.android.features.rageshake.impl.logs
import com.squareup.anvil.annotations.ContributesBinding
import dev.zacsweers.metro.ContributesBinding
import io.element.android.features.rageshake.api.logs.LogFilesRemover
import io.element.android.features.rageshake.impl.reporter.DefaultBugReporter
import io.element.android.libraries.di.AppScope
import dev.zacsweers.metro.AppScope
import java.io.File
import javax.inject.Inject
import dev.zacsweers.metro.Inject
@ContributesBinding(AppScope::class)
class DefaultLogFilesRemover @Inject constructor(
@Inject
class DefaultLogFilesRemover(
private val bugReporter: DefaultBugReporter,
) : LogFilesRemover {
override suspend fun perform(predicate: (File) -> Boolean) {

View file

@ -15,20 +15,21 @@ import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.rememberCoroutineScope
import androidx.compose.runtime.saveable.rememberSaveable
import com.squareup.anvil.annotations.ContributesBinding
import dev.zacsweers.metro.ContributesBinding
import io.element.android.features.rageshake.api.RageshakeFeatureAvailability
import io.element.android.features.rageshake.api.preferences.RageshakePreferencesEvents
import io.element.android.features.rageshake.api.preferences.RageshakePreferencesPresenter
import io.element.android.features.rageshake.api.preferences.RageshakePreferencesState
import io.element.android.features.rageshake.impl.rageshake.RageShake
import io.element.android.features.rageshake.impl.rageshake.RageshakeDataStore
import io.element.android.libraries.di.AppScope
import dev.zacsweers.metro.AppScope
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.launch
import javax.inject.Inject
import dev.zacsweers.metro.Inject
@ContributesBinding(AppScope::class)
class DefaultRageshakePreferencesPresenter @Inject constructor(
@Inject
class DefaultRageshakePreferencesPresenter(
private val rageshake: RageShake,
private val rageshakeDataStore: RageshakeDataStore,
private val rageshakeFeatureAvailability: RageshakeFeatureAvailability,

View file

@ -11,16 +11,18 @@ import android.content.Context
import android.hardware.Sensor
import android.hardware.SensorManager
import androidx.core.content.getSystemService
import com.squareup.anvil.annotations.ContributesBinding
import dev.zacsweers.metro.ContributesBinding
import com.squareup.seismic.ShakeDetector
import io.element.android.libraries.di.AppScope
import io.element.android.libraries.di.ApplicationContext
import io.element.android.libraries.di.SingleIn
import javax.inject.Inject
import dev.zacsweers.metro.AppScope
import io.element.android.libraries.di.annotations.ApplicationContext
import dev.zacsweers.metro.SingleIn
import dev.zacsweers.metro.Inject
import dev.zacsweers.metro.binding
@SingleIn(AppScope::class)
@ContributesBinding(scope = AppScope::class, boundType = RageShake::class)
class DefaultRageShake @Inject constructor(
@ContributesBinding(scope = AppScope::class, binding = binding<RageShake>())
@Inject
class DefaultRageShake(
@ApplicationContext context: Context,
) : ShakeDetector.Listener, RageShake {
private var sensorManager = context.getSystemService<SensorManager>()

View file

@ -10,19 +10,20 @@ package io.element.android.features.rageshake.impl.rageshake
import androidx.datastore.preferences.core.booleanPreferencesKey
import androidx.datastore.preferences.core.edit
import androidx.datastore.preferences.core.floatPreferencesKey
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.core.bool.orFalse
import io.element.android.libraries.di.AppScope
import io.element.android.libraries.preferences.api.store.PreferenceDataStoreFactory
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.map
import javax.inject.Inject
private val enabledKey = booleanPreferencesKey("enabled")
private val sensitivityKey = floatPreferencesKey("sensitivity")
@ContributesBinding(AppScope::class)
class PreferencesRageshakeDataStore @Inject constructor(
@Inject
class PreferencesRageshakeDataStore(
preferenceDataStoreFactory: PreferenceDataStoreFactory,
) : RageshakeDataStore {
private val store = preferenceDataStoreFactory.create("elementx_rageshake")

View file

@ -7,16 +7,17 @@
package io.element.android.features.rageshake.impl.reporter
import com.squareup.anvil.annotations.ContributesBinding
import dev.zacsweers.metro.ContributesBinding
import io.element.android.appconfig.RageshakeConfig
import io.element.android.libraries.di.AppScope
import javax.inject.Inject
import dev.zacsweers.metro.AppScope
import dev.zacsweers.metro.Inject
fun interface BugReportAppNameProvider {
fun provide(): String
}
@ContributesBinding(AppScope::class)
class DefaultBugReportAppNameProvider @Inject constructor() : BugReportAppNameProvider {
@Inject
class DefaultBugReportAppNameProvider() : BugReportAppNameProvider {
override fun provide(): String = RageshakeConfig.BUG_REPORT_APP_NAME
}

View file

@ -11,7 +11,7 @@ import android.content.Context
import android.os.Build
import androidx.core.net.toFile
import androidx.core.net.toUri
import com.squareup.anvil.annotations.ContributesBinding
import dev.zacsweers.metro.ContributesBinding
import io.element.android.appconfig.RageshakeConfig
import io.element.android.features.rageshake.api.logs.createWriteToFilesConfiguration
import io.element.android.features.rageshake.api.reporter.BugReporter
@ -24,9 +24,9 @@ import io.element.android.libraries.core.coroutine.CoroutineDispatchers
import io.element.android.libraries.core.data.tryOrNull
import io.element.android.libraries.core.meta.BuildMeta
import io.element.android.libraries.core.mimetype.MimeTypes
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
import dev.zacsweers.metro.SingleIn
import io.element.android.libraries.matrix.api.MatrixClientProvider
import io.element.android.libraries.matrix.api.SdkMetadata
import io.element.android.libraries.matrix.api.auth.MatrixAuthenticationService
@ -55,15 +55,16 @@ import java.time.LocalDateTime
import java.time.ZoneOffset
import java.time.format.DateTimeFormatter
import java.util.Locale
import javax.inject.Inject
import javax.inject.Provider
import dev.zacsweers.metro.Inject
import dev.zacsweers.metro.Provider
/**
* BugReporter creates and sends the bug reports.
*/
@SingleIn(AppScope::class)
@ContributesBinding(AppScope::class)
class DefaultBugReporter @Inject constructor(
@Inject
class DefaultBugReporter(
@ApplicationContext private val context: Context,
private val screenshotHolder: ScreenshotHolder,
private val crashDataStore: CrashDataStore,
@ -255,7 +256,7 @@ class DefaultBugReporter @Inject constructor(
var errorMessage: String? = null
// trigger the request
try {
response = okHttpClient.get()
response = okHttpClient()
.newCall(request)
.execute()
} catch (e: CancellationException) {

View file

@ -7,20 +7,21 @@
package io.element.android.features.rageshake.impl.reporter
import com.squareup.anvil.annotations.ContributesBinding
import dev.zacsweers.metro.ContributesBinding
import io.element.android.appconfig.RageshakeConfig
import io.element.android.features.enterprise.api.BugReportUrl
import io.element.android.features.enterprise.api.EnterpriseService
import io.element.android.libraries.di.AppScope
import dev.zacsweers.metro.AppScope
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.flowOf
import kotlinx.coroutines.flow.map
import okhttp3.HttpUrl
import okhttp3.HttpUrl.Companion.toHttpUrl
import javax.inject.Inject
import dev.zacsweers.metro.Inject
@ContributesBinding(AppScope::class)
class DefaultBugReporterUrlProvider @Inject constructor(
@Inject
class DefaultBugReporterUrlProvider(
private val bugReportAppNameProvider: BugReportAppNameProvider,
private val enterpriseService: EnterpriseService,
) : BugReporterUrlProvider {

View file

@ -10,18 +10,19 @@ package io.element.android.features.rageshake.impl.screenshot
import android.content.Context
import android.graphics.Bitmap
import androidx.core.net.toUri
import com.squareup.anvil.annotations.ContributesBinding
import dev.zacsweers.metro.ContributesBinding
import io.element.android.libraries.androidutils.bitmap.writeBitmap
import io.element.android.libraries.androidutils.file.safeDelete
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
import dev.zacsweers.metro.SingleIn
import java.io.File
import javax.inject.Inject
import dev.zacsweers.metro.Inject
@SingleIn(AppScope::class)
@ContributesBinding(AppScope::class)
class DefaultScreenshotHolder @Inject constructor(
@Inject
class DefaultScreenshotHolder(
@ApplicationContext private val context: Context,
) : ScreenshotHolder {
private val file = File(context.filesDir, "screenshot.png")