From 891f3fed6db524440c98d166c6927eefd6e69f73 Mon Sep 17 00:00:00 2001 From: Ricki Hirner Date: Tue, 31 Dec 2024 16:10:06 +0100 Subject: [PATCH] Use Hilt for explicit Migrations --- .../at/bitfire/davdroid/db/AppDatabaseTest.kt | 6 +- .../db/migration/AutoMigration16Test.kt | 114 +++++++++--------- .../db/migration/DatabaseMigrationTest.kt | 13 +- .../sync/account/TestAccountAuthenticator.kt | 2 +- .../at/bitfire/davdroid/db/AppDatabase.kt | 19 +-- .../davdroid/db/migration/AutoMigration12.kt | 2 +- .../davdroid/db/migration/AutoMigration16.kt | 2 +- .../davdroid/db/migration/Migration2.kt | 12 ++ .../davdroid/db/migration/Migration3.kt | 12 ++ .../davdroid/db/migration/Migration4.kt | 12 ++ .../davdroid/db/migration/Migration5.kt | 12 ++ .../davdroid/db/migration/Migration6.kt | 12 ++ .../davdroid/db/migration/Migration7.kt | 12 ++ .../davdroid/db/migration/Migration8.kt | 12 ++ .../davdroid/db/migration/Migration9.kt | 12 ++ .../davdroid/startup/CrashHandlerSetup.kt | 1 + 16 files changed, 172 insertions(+), 83 deletions(-) diff --git a/app/src/androidTest/kotlin/at/bitfire/davdroid/db/AppDatabaseTest.kt b/app/src/androidTest/kotlin/at/bitfire/davdroid/db/AppDatabaseTest.kt index fcec5f211..8a257cd6d 100644 --- a/app/src/androidTest/kotlin/at/bitfire/davdroid/db/AppDatabaseTest.kt +++ b/app/src/androidTest/kotlin/at/bitfire/davdroid/db/AppDatabaseTest.kt @@ -7,6 +7,7 @@ package at.bitfire.davdroid.db import android.content.Context import androidx.room.Room import androidx.room.migration.AutoMigrationSpec +import androidx.room.migration.Migration import androidx.room.testing.MigrationTestHelper import androidx.sqlite.db.framework.FrameworkSQLiteOpenHelperFactory import androidx.test.platform.app.InstrumentationRegistry @@ -34,6 +35,9 @@ class AppDatabaseTest { @Inject lateinit var logger: Logger + @Inject + lateinit var manualMigrations: Set<@JvmSuppressWildcards Migration> + @Before fun setup() { hiltRule.inject() @@ -56,7 +60,7 @@ class AppDatabaseTest { // open and migrate (to current version) database Room.databaseBuilder(context, AppDatabase::class.java, TEST_DB) // manual migrations - .addMigrations(*AppDatabase.manualMigrations) + .addMigrations(*manualMigrations.toTypedArray()) // auto-migrations that need to be specified explicitly .apply { for (spec in autoMigrations) diff --git a/app/src/androidTest/kotlin/at/bitfire/davdroid/db/migration/AutoMigration16Test.kt b/app/src/androidTest/kotlin/at/bitfire/davdroid/db/migration/AutoMigration16Test.kt index 003c07bb6..38a910a6c 100644 --- a/app/src/androidTest/kotlin/at/bitfire/davdroid/db/migration/AutoMigration16Test.kt +++ b/app/src/androidTest/kotlin/at/bitfire/davdroid/db/migration/AutoMigration16Test.kt @@ -15,74 +15,68 @@ import org.junit.Test class AutoMigration16Test: DatabaseMigrationTest(toVersion = 16) { @Test - fun testMigrate_WithTimeZone() { - testMigration( - prepare = { db -> - val minimalVTimezone = """ - BEGIN:VCALENDAR - VERSION:2.0 - PRODID:DAVx5 - BEGIN:VTIMEZONE - TZID:America/New_York - END:VTIMEZONE - END:VCALENDAR - """.trimIndent() - db.execSQL( - "INSERT INTO service (id, accountName, type) VALUES (?, ?, ?)", - arrayOf(1, "test", Service.Companion.TYPE_CALDAV) - ) - db.execSQL( - "INSERT INTO collection (id, serviceId, type, url, privWriteContent, privUnbind, forceReadOnly, sync, timezone) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)", - arrayOf(1, 1, TYPE_CALENDAR, "https://example.com", true, true, false, false, minimalVTimezone) - ) - } - ) { db -> - db.query("SELECT timezoneId FROM collection WHERE id=1").use { cursor -> - cursor.moveToFirst() - assertEquals("America/New_York", cursor.getString(0)) - } + fun testMigrate_WithTimeZone() = testMigration( + prepare = { db -> + val minimalVTimezone = """ + BEGIN:VCALENDAR + VERSION:2.0 + PRODID:DAVx5 + BEGIN:VTIMEZONE + TZID:America/New_York + END:VTIMEZONE + END:VCALENDAR + """.trimIndent() + db.execSQL( + "INSERT INTO service (id, accountName, type) VALUES (?, ?, ?)", + arrayOf(1, "test", Service.Companion.TYPE_CALDAV) + ) + db.execSQL( + "INSERT INTO collection (id, serviceId, type, url, privWriteContent, privUnbind, forceReadOnly, sync, timezone) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)", + arrayOf(1, 1, TYPE_CALENDAR, "https://example.com", true, true, false, false, minimalVTimezone) + ) + } + ) { db -> + db.query("SELECT timezoneId FROM collection WHERE id=1").use { cursor -> + cursor.moveToFirst() + assertEquals("America/New_York", cursor.getString(0)) } } @Test - fun testMigrate_WithTimeZone_Unparseable() { - testMigration( - prepare = { db -> - db.execSQL( - "INSERT INTO service (id, accountName, type) VALUES (?, ?, ?)", - arrayOf(1, "test", Service.Companion.TYPE_CALDAV) - ) - db.execSQL( - "INSERT INTO collection (id, serviceId, type, url, privWriteContent, privUnbind, forceReadOnly, sync, timezone) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)", - arrayOf(1, 1, TYPE_CALENDAR, "https://example.com", true, true, false, false, "Some Garbage Content") - ) - } - ) { db -> - db.query("SELECT timezoneId FROM collection WHERE id=1").use { cursor -> - cursor.moveToFirst() - assertNull(cursor.getString(0)) - } + fun testMigrate_WithTimeZone_Unparseable() = testMigration( + prepare = { db -> + db.execSQL( + "INSERT INTO service (id, accountName, type) VALUES (?, ?, ?)", + arrayOf(1, "test", Service.Companion.TYPE_CALDAV) + ) + db.execSQL( + "INSERT INTO collection (id, serviceId, type, url, privWriteContent, privUnbind, forceReadOnly, sync, timezone) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)", + arrayOf(1, 1, TYPE_CALENDAR, "https://example.com", true, true, false, false, "Some Garbage Content") + ) + } + ) { db -> + db.query("SELECT timezoneId FROM collection WHERE id=1").use { cursor -> + cursor.moveToFirst() + assertNull(cursor.getString(0)) } } @Test - fun testMigrate_WithoutTimezone() { - testMigration( - prepare = { db -> - db.execSQL( - "INSERT INTO service (id, accountName, type) VALUES (?, ?, ?)", - arrayOf(1, "test", Service.Companion.TYPE_CALDAV) - ) - db.execSQL( - "INSERT INTO collection (id, serviceId, type, url, privWriteContent, privUnbind, forceReadOnly, sync) VALUES (?, ?, ?, ?, ?, ?, ?, ?)", - arrayOf(1, 1, TYPE_CALENDAR, "https://example.com", true, true, false, false) - ) - } - ) { db -> - db.query("SELECT timezoneId FROM collection WHERE id=1").use { cursor -> - cursor.moveToFirst() - assertNull(cursor.getString(0)) - } + fun testMigrate_WithoutTimezone() = testMigration( + prepare = { db -> + db.execSQL( + "INSERT INTO service (id, accountName, type) VALUES (?, ?, ?)", + arrayOf(1, "test", Service.Companion.TYPE_CALDAV) + ) + db.execSQL( + "INSERT INTO collection (id, serviceId, type, url, privWriteContent, privUnbind, forceReadOnly, sync) VALUES (?, ?, ?, ?, ?, ?, ?, ?)", + arrayOf(1, 1, TYPE_CALENDAR, "https://example.com", true, true, false, false) + ) + } + ) { db -> + db.query("SELECT timezoneId FROM collection WHERE id=1").use { cursor -> + cursor.moveToFirst() + assertNull(cursor.getString(0)) } } diff --git a/app/src/androidTest/kotlin/at/bitfire/davdroid/db/migration/DatabaseMigrationTest.kt b/app/src/androidTest/kotlin/at/bitfire/davdroid/db/migration/DatabaseMigrationTest.kt index 8d296699c..b0940512f 100644 --- a/app/src/androidTest/kotlin/at/bitfire/davdroid/db/migration/DatabaseMigrationTest.kt +++ b/app/src/androidTest/kotlin/at/bitfire/davdroid/db/migration/DatabaseMigrationTest.kt @@ -5,6 +5,7 @@ package at.bitfire.davdroid.db.migration import androidx.room.migration.AutoMigrationSpec +import androidx.room.migration.Migration import androidx.room.testing.MigrationTestHelper import androidx.sqlite.db.SupportSQLiteDatabase import androidx.sqlite.db.framework.FrameworkSQLiteOpenHelperFactory @@ -15,6 +16,11 @@ import org.junit.Before import org.junit.Rule import javax.inject.Inject +/** + * Helper for testing the database migration from [toVersion] - 1 to [toVersion]. + * + * @param toVersion The target version to migrate to. + */ abstract class DatabaseMigrationTest( private val toVersion: Int ) { @@ -22,6 +28,9 @@ abstract class DatabaseMigrationTest( @Inject lateinit var autoMigrations: Set<@JvmSuppressWildcards AutoMigrationSpec> + @Inject + lateinit var manualMigrations: Set<@JvmSuppressWildcards Migration> + @get:Rule val hiltRule = HiltAndroidRule(this) @@ -35,7 +44,7 @@ abstract class DatabaseMigrationTest( /** * Used for testing the migration process from [toVersion]-1 to [toVersion]. * - * @param prepare Callback to prepare the database. Will be run with database schema in version [fromVersion]. + * @param prepare Callback to prepare the database. Will be run with database schema in version [toVersion] - 1. * @param validate Callback to validate the migration result. Will be run with database schema in version [toVersion]. */ protected fun testMigration( @@ -61,7 +70,7 @@ abstract class DatabaseMigrationTest( name = dbName, version = toVersion, validateDroppedTables = true, - migrations = AppDatabase.manualMigrations + migrations = manualMigrations.toTypedArray() ) validate(db) diff --git a/app/src/androidTest/kotlin/at/bitfire/davdroid/sync/account/TestAccountAuthenticator.kt b/app/src/androidTest/kotlin/at/bitfire/davdroid/sync/account/TestAccountAuthenticator.kt index d6e9b2c46..f71e0801e 100644 --- a/app/src/androidTest/kotlin/at/bitfire/davdroid/sync/account/TestAccountAuthenticator.kt +++ b/app/src/androidTest/kotlin/at/bitfire/davdroid/sync/account/TestAccountAuthenticator.kt @@ -42,7 +42,7 @@ class TestAccountAuthenticator: Service() { companion object { - val context by lazy { InstrumentationRegistry.getInstrumentation().context } + private val context by lazy { InstrumentationRegistry.getInstrumentation().context } val counter = AtomicInteger(0) /** diff --git a/app/src/main/kotlin/at/bitfire/davdroid/db/AppDatabase.kt b/app/src/main/kotlin/at/bitfire/davdroid/db/AppDatabase.kt index 1fabbf9d8..3f803999f 100644 --- a/app/src/main/kotlin/at/bitfire/davdroid/db/AppDatabase.kt +++ b/app/src/main/kotlin/at/bitfire/davdroid/db/AppDatabase.kt @@ -61,10 +61,11 @@ abstract class AppDatabase: RoomDatabase() { fun appDatabase( autoMigrations: Set<@JvmSuppressWildcards AutoMigrationSpec>, @ApplicationContext context: Context, + manualMigrations: Set<@JvmSuppressWildcards Migration>, notificationRegistry: NotificationRegistry ): AppDatabase = Room .databaseBuilder(context, AppDatabase::class.java, "services.db") - .addMigrations(*manualMigrations) + .addMigrations(*manualMigrations.toTypedArray()) .apply { for (spec in autoMigrations) addAutoMigrationSpec(spec) @@ -95,22 +96,6 @@ abstract class AppDatabase: RoomDatabase() { } - companion object { - - val manualMigrations: Array = arrayOf( - Migration9, - Migration8, - Migration7, - Migration6, - Migration5, - Migration4, - Migration3, - Migration2 - ) - - } - - // DAOs abstract fun serviceDao(): ServiceDao diff --git a/app/src/main/kotlin/at/bitfire/davdroid/db/migration/AutoMigration12.kt b/app/src/main/kotlin/at/bitfire/davdroid/db/migration/AutoMigration12.kt index 92d0a7007..4a60e14b5 100644 --- a/app/src/main/kotlin/at/bitfire/davdroid/db/migration/AutoMigration12.kt +++ b/app/src/main/kotlin/at/bitfire/davdroid/db/migration/AutoMigration12.kt @@ -39,7 +39,7 @@ class AutoMigration12 @Inject constructor( @Module @InstallIn(SingletonComponent::class) - abstract class SettingsMigrationModule { + abstract class AutoMigrationModule { @Binds @IntoSet abstract fun provide(impl: AutoMigration12): AutoMigrationSpec } diff --git a/app/src/main/kotlin/at/bitfire/davdroid/db/migration/AutoMigration16.kt b/app/src/main/kotlin/at/bitfire/davdroid/db/migration/AutoMigration16.kt index 38090bc16..df8be31fe 100644 --- a/app/src/main/kotlin/at/bitfire/davdroid/db/migration/AutoMigration16.kt +++ b/app/src/main/kotlin/at/bitfire/davdroid/db/migration/AutoMigration16.kt @@ -39,7 +39,7 @@ class AutoMigration16 @Inject constructor(): AutoMigrationSpec { @Module @InstallIn(SingletonComponent::class) - abstract class SettingsMigrationModule { + abstract class AutoMigrationModule { @Binds @IntoSet abstract fun provide(impl: AutoMigration16): AutoMigrationSpec } diff --git a/app/src/main/kotlin/at/bitfire/davdroid/db/migration/Migration2.kt b/app/src/main/kotlin/at/bitfire/davdroid/db/migration/Migration2.kt index d24cbc6a7..caae5c207 100644 --- a/app/src/main/kotlin/at/bitfire/davdroid/db/migration/Migration2.kt +++ b/app/src/main/kotlin/at/bitfire/davdroid/db/migration/Migration2.kt @@ -5,6 +5,11 @@ package at.bitfire.davdroid.db.migration import androidx.room.migration.Migration +import dagger.Module +import dagger.Provides +import dagger.hilt.InstallIn +import dagger.hilt.components.SingletonComponent +import dagger.multibindings.IntoSet val Migration2 = Migration(1, 2) { db -> db.execSQL("ALTER TABLE collections ADD COLUMN type TEXT NOT NULL DEFAULT ''") @@ -14,4 +19,11 @@ val Migration2 = Migration(1, 2) { db -> "FROM services WHERE _id=collections.serviceID" + ")", arrayOf("caldav", "CALENDAR", "ADDRESS_BOOK")) +} + +@Module +@InstallIn(SingletonComponent::class) +internal object Migration2Module { + @Provides @IntoSet + fun provide(): Migration = Migration2 } \ No newline at end of file diff --git a/app/src/main/kotlin/at/bitfire/davdroid/db/migration/Migration3.kt b/app/src/main/kotlin/at/bitfire/davdroid/db/migration/Migration3.kt index dc5479c07..4658ddb96 100644 --- a/app/src/main/kotlin/at/bitfire/davdroid/db/migration/Migration3.kt +++ b/app/src/main/kotlin/at/bitfire/davdroid/db/migration/Migration3.kt @@ -5,10 +5,22 @@ package at.bitfire.davdroid.db.migration import androidx.room.migration.Migration +import dagger.Module +import dagger.Provides +import dagger.hilt.InstallIn +import dagger.hilt.components.SingletonComponent +import dagger.multibindings.IntoSet import java.util.logging.Logger val Migration3 = Migration(2, 3) { db -> // We don't have access to the context in a Room migration now, so // we will just drop those settings from old DAVx5 versions. Logger.getGlobal().warning("Dropping settings distrustSystemCerts and overrideProxy*") +} + +@Module +@InstallIn(SingletonComponent::class) +internal object Migration3Module { + @Provides @IntoSet + fun provide(): Migration = Migration3 } \ No newline at end of file diff --git a/app/src/main/kotlin/at/bitfire/davdroid/db/migration/Migration4.kt b/app/src/main/kotlin/at/bitfire/davdroid/db/migration/Migration4.kt index b6285888c..b321596d6 100644 --- a/app/src/main/kotlin/at/bitfire/davdroid/db/migration/Migration4.kt +++ b/app/src/main/kotlin/at/bitfire/davdroid/db/migration/Migration4.kt @@ -5,7 +5,19 @@ package at.bitfire.davdroid.db.migration import androidx.room.migration.Migration +import dagger.Module +import dagger.Provides +import dagger.hilt.InstallIn +import dagger.hilt.components.SingletonComponent +import dagger.multibindings.IntoSet val Migration4 = Migration(3, 4) { db -> db.execSQL("ALTER TABLE collections ADD COLUMN forceReadOnly INTEGER DEFAULT 0 NOT NULL") +} + +@Module +@InstallIn(SingletonComponent::class) +internal object Migration4Module { + @Provides @IntoSet + fun provide(): Migration = Migration4 } \ No newline at end of file diff --git a/app/src/main/kotlin/at/bitfire/davdroid/db/migration/Migration5.kt b/app/src/main/kotlin/at/bitfire/davdroid/db/migration/Migration5.kt index 16d2165c5..d77581fcb 100644 --- a/app/src/main/kotlin/at/bitfire/davdroid/db/migration/Migration5.kt +++ b/app/src/main/kotlin/at/bitfire/davdroid/db/migration/Migration5.kt @@ -5,6 +5,11 @@ package at.bitfire.davdroid.db.migration import androidx.room.migration.Migration +import dagger.Module +import dagger.Provides +import dagger.hilt.InstallIn +import dagger.hilt.components.SingletonComponent +import dagger.multibindings.IntoSet val Migration5 = Migration(4, 5) { db -> db.execSQL("ALTER TABLE collections ADD COLUMN privWriteContent INTEGER DEFAULT 0 NOT NULL") @@ -14,4 +19,11 @@ val Migration5 = Migration(4, 5) { db -> db.execSQL("UPDATE collections SET privUnbind=NOT readOnly") // there's no DROP COLUMN in SQLite, so just keep the "readOnly" column +} + +@Module +@InstallIn(SingletonComponent::class) +internal object Migration5Module { + @Provides @IntoSet + fun provide(): Migration = Migration5 } \ No newline at end of file diff --git a/app/src/main/kotlin/at/bitfire/davdroid/db/migration/Migration6.kt b/app/src/main/kotlin/at/bitfire/davdroid/db/migration/Migration6.kt index 6f63d41ee..91edacd0d 100644 --- a/app/src/main/kotlin/at/bitfire/davdroid/db/migration/Migration6.kt +++ b/app/src/main/kotlin/at/bitfire/davdroid/db/migration/Migration6.kt @@ -5,6 +5,11 @@ package at.bitfire.davdroid.db.migration import androidx.room.migration.Migration +import dagger.Module +import dagger.Provides +import dagger.hilt.InstallIn +import dagger.hilt.components.SingletonComponent +import dagger.multibindings.IntoSet val Migration6 = Migration(5, 6) { db -> val sql = arrayOf( @@ -56,4 +61,11 @@ val Migration6 = Migration(5, 6) { db -> "DROP TABLE collections" ) sql.forEach { db.execSQL(it) } +} + +@Module +@InstallIn(SingletonComponent::class) +internal object Migration6Module { + @Provides @IntoSet + fun provide(): Migration = Migration6 } \ No newline at end of file diff --git a/app/src/main/kotlin/at/bitfire/davdroid/db/migration/Migration7.kt b/app/src/main/kotlin/at/bitfire/davdroid/db/migration/Migration7.kt index ebed06c91..7f831132b 100644 --- a/app/src/main/kotlin/at/bitfire/davdroid/db/migration/Migration7.kt +++ b/app/src/main/kotlin/at/bitfire/davdroid/db/migration/Migration7.kt @@ -5,8 +5,20 @@ package at.bitfire.davdroid.db.migration import androidx.room.migration.Migration +import dagger.Module +import dagger.Provides +import dagger.hilt.InstallIn +import dagger.hilt.components.SingletonComponent +import dagger.multibindings.IntoSet val Migration7 = Migration(6, 7) { db -> db.execSQL("ALTER TABLE homeset ADD COLUMN privBind INTEGER NOT NULL DEFAULT 1") db.execSQL("ALTER TABLE homeset ADD COLUMN displayName TEXT DEFAULT NULL") +} + +@Module +@InstallIn(SingletonComponent::class) +internal object Migration7Module { + @Provides @IntoSet + fun provide(): Migration = Migration7 } \ No newline at end of file diff --git a/app/src/main/kotlin/at/bitfire/davdroid/db/migration/Migration8.kt b/app/src/main/kotlin/at/bitfire/davdroid/db/migration/Migration8.kt index 218ded832..76af39b0e 100644 --- a/app/src/main/kotlin/at/bitfire/davdroid/db/migration/Migration8.kt +++ b/app/src/main/kotlin/at/bitfire/davdroid/db/migration/Migration8.kt @@ -5,10 +5,22 @@ package at.bitfire.davdroid.db.migration import androidx.room.migration.Migration +import dagger.Module +import dagger.Provides +import dagger.hilt.InstallIn +import dagger.hilt.components.SingletonComponent +import dagger.multibindings.IntoSet val Migration8 = Migration(7, 8) { db -> db.execSQL("ALTER TABLE homeset ADD COLUMN personal INTEGER NOT NULL DEFAULT 1") db.execSQL("ALTER TABLE collection ADD COLUMN homeSetId INTEGER DEFAULT NULL REFERENCES homeset(id) ON DELETE SET NULL") db.execSQL("ALTER TABLE collection ADD COLUMN owner TEXT DEFAULT NULL") db.execSQL("CREATE INDEX index_collection_homeSetId_type ON collection(homeSetId, type)") +} + +@Module +@InstallIn(SingletonComponent::class) +internal object Migration8Module { + @Provides @IntoSet + fun provide(): Migration = Migration8 } \ No newline at end of file diff --git a/app/src/main/kotlin/at/bitfire/davdroid/db/migration/Migration9.kt b/app/src/main/kotlin/at/bitfire/davdroid/db/migration/Migration9.kt index fc09908df..f066fc0bc 100644 --- a/app/src/main/kotlin/at/bitfire/davdroid/db/migration/Migration9.kt +++ b/app/src/main/kotlin/at/bitfire/davdroid/db/migration/Migration9.kt @@ -5,6 +5,11 @@ package at.bitfire.davdroid.db.migration import androidx.room.migration.Migration +import dagger.Module +import dagger.Provides +import dagger.hilt.InstallIn +import dagger.hilt.components.SingletonComponent +import dagger.multibindings.IntoSet val Migration9 = Migration(8, 9) { db -> db.execSQL("CREATE TABLE syncstats (" + @@ -15,4 +20,11 @@ val Migration9 = Migration(8, 9) { db -> db.execSQL("CREATE UNIQUE INDEX index_syncstats_collectionId_authority ON syncstats(collectionId, authority)") db.execSQL("CREATE INDEX index_collection_url ON collection(url)") +} + +@Module +@InstallIn(SingletonComponent::class) +internal object Migration9Module { + @Provides @IntoSet + fun provide(): Migration = Migration9 } \ No newline at end of file diff --git a/app/src/main/kotlin/at/bitfire/davdroid/startup/CrashHandlerSetup.kt b/app/src/main/kotlin/at/bitfire/davdroid/startup/CrashHandlerSetup.kt index 94e965647..fa6aa7772 100644 --- a/app/src/main/kotlin/at/bitfire/davdroid/startup/CrashHandlerSetup.kt +++ b/app/src/main/kotlin/at/bitfire/davdroid/startup/CrashHandlerSetup.kt @@ -26,6 +26,7 @@ import kotlin.jvm.optionals.getOrNull * Sets up the uncaught exception (crash) handler and enables StrictMode in debug builds. */ class CrashHandlerSetup @Inject constructor( + @ApplicationContext private val context: Context, private val logger: Logger, private val crashHandler: Optional ): StartupPlugin {