First version bumps for Android 12
diff --git a/.idea/runConfigurations.xml b/.idea/runConfigurations.xml
deleted file mode 100644
index e2456cb..0000000
--- a/.idea/runConfigurations.xml
+++ /dev/null
@@ -1,13 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<project version="4">
-  <component name="RunConfigurationProducerService">
-    <option name="ignoredProducers">
-      <set>
-        <option value="com.android.tools.idea.compose.preview.runconfiguration.ComposePreviewRunConfigurationProducer" />
-        <option value="org.jetbrains.plugins.gradle.execution.test.runner.AllInPackageGradleConfigurationProducer" />
-        <option value="org.jetbrains.plugins.gradle.execution.test.runner.TestClassGradleConfigurationProducer" />
-        <option value="org.jetbrains.plugins.gradle.execution.test.runner.TestMethodGradleConfigurationProducer" />
-      </set>
-    </option>
-  </component>
-</project>
diff --git a/Android.bp b/Android.bp
index 5664d6d..cf5d6f5 100644
--- a/Android.bp
+++ b/Android.bp
@@ -27,6 +27,7 @@
         "kotlin-stdlib-jdk8",
         "androidx.core_core-ktx",
         "androidx.preference_preference",
+        "androidx.documentfile_documentfile",
         "androidx.lifecycle_lifecycle-viewmodel-ktx",
         "androidx.lifecycle_lifecycle-livedata-ktx",
         "androidx-constraintlayout_constraintlayout",
@@ -37,9 +38,8 @@
         "androidx.room_room-runtime",
         "libprotobuf-java-lite",
         // koin
-        "seedvault-lib-koin-core", // did not manage to add this as transitive dependency
+        "seedvault-lib-koin-core-jvm", // did not manage to add this as transitive dependency
         "seedvault-lib-koin-android",
-        "seedvault-lib-koin-androidx-viewmodel",
         // bip39
         "seedvault-lib-kotlin-bip39",
     ],
diff --git a/app/build.gradle b/app/build.gradle
index 8509fc4..eb78fa3 100644
--- a/app/build.gradle
+++ b/app/build.gradle
@@ -1,9 +1,7 @@
-import groovy.xml.XmlUtil
-
 plugins {
     id "com.android.application"
     id "kotlin-android"
-    id "org.jlleitschuh.gradle.ktlint" version "9.4.0"
+    id "org.jlleitschuh.gradle.ktlint" version "10.2.0"
 }
 
 def gitDescribe = { ->
@@ -34,7 +32,9 @@
     }
 
     lintOptions {
-        disable "CheckedExceptions"
+        disable "DialogFragmentCallbacksDetector",
+                "InvalidFragmentVersionForActivityResult",
+                "CheckedExceptions"
         abortOnError true
     }
     compileOptions {
@@ -43,7 +43,7 @@
     }
     kotlinOptions {
         jvmTarget = JavaVersion.VERSION_1_8.toString()
-        languageVersion = "1.3"
+        languageVersion = "1.4"
     }
     testOptions {
         unitTests.all {
@@ -98,6 +98,7 @@
     implementation rootProject.ext.std_libs.androidx_core
     // A newer version gets pulled in with AOSP via core, so we include fragment here explicitly
     implementation rootProject.ext.std_libs.androidx_fragment
+    implementation rootProject.ext.std_libs.androidx_activity
     implementation rootProject.ext.std_libs.androidx_preference
     implementation rootProject.ext.std_libs.androidx_lifecycle_viewmodel_ktx
     implementation rootProject.ext.std_libs.androidx_lifecycle_livedata_ktx
@@ -119,12 +120,15 @@
      * If the dependencies below are updated,
      * please make sure to update the prebuilt libraries and the Android.bp files
      * in the top-level `libs` folder to reflect that.
-     * You can copy these libraries from ~/.gradle/caches/modules-2
+     * You can copy these libraries from ~/.gradle/caches/modules-2/files-2.1
      */
     // later versions than 2.1.1 require newer kotlin version
+//    implementation "io.insert-koin:koin-core-jvm:3.1.2"
+//    implementation "io.insert-koin:koin-android:3.1.2"
     implementation fileTree(include: ['*.jar'], dir: "${rootProject.rootDir}/libs/koin-android")
     implementation fileTree(include: ['*.aar'], dir: "${rootProject.rootDir}/libs/koin-android")
 
+//    implementation "cash.z.ecc.android:kotlin-bip39:1.0.2"
     implementation fileTree(include: ['kotlin-bip39-1.0.2.jar'], dir: "${rootProject.rootDir}/libs")
 
     /**
@@ -134,7 +138,7 @@
 
     // anything less than 'implementation' fails tests run with gradlew
     testImplementation rootProject.ext.aosp_libs
-    testImplementation 'androidx.test.ext:junit:1.1.2'
+    testImplementation 'androidx.test.ext:junit:1.1.3'
     testImplementation('org.robolectric:robolectric:4.3.1') { // 4.4 has issue with non-idle Looper
         // https://github.com/robolectric/robolectric/issues/5245
         exclude group: "com.google.auto.service", module: "auto-service"
@@ -146,9 +150,9 @@
     testRuntimeOnly "org.junit.jupiter:junit-jupiter-engine:$junit5_version"
     testRuntimeOnly "org.junit.vintage:junit-vintage-engine:$junit5_version"
 
-    androidTestImplementation 'androidx.test:runner:1.3.0'
-    androidTestImplementation 'androidx.test:rules:1.3.0'
-    androidTestImplementation 'androidx.test.ext:junit:1.1.2'
+    androidTestImplementation 'androidx.test:runner:1.4.0'
+    androidTestImplementation 'androidx.test:rules:1.4.0'
+    androidTestImplementation 'androidx.test.ext:junit:1.1.3'
     androidTestImplementation "io.mockk:mockk-android:$mockk_version"
 }
 
@@ -163,30 +167,6 @@
     }
 }
 
-// http://www.31mins.com/android-studio-build-system-application/
-preBuild.doLast {
-    def imlFile = file(project.name + ".iml")
-
-    try {
-        def parsedXml = (new XmlParser()).parse(imlFile)
-        def jdkNode = parsedXml.component[1].orderEntry.find { it.'@type' == 'jdk' }
-        parsedXml.component[1].remove(jdkNode)
-
-        def apiString = android.compileSdkVersion.substring("android-".length())
-        def sdkString = "Android API " + apiString + " Platform"
-        //noinspection GroovyResultOfObjectAllocationIgnored // the note gets inserted
-        new Node(parsedXml.component[1], 'orderEntry', [
-                'type'   : 'jdk',
-                'jdkName': sdkString,
-                'jdkType': 'Android SDK'
-        ])
-        XmlUtil.serialize(parsedXml, new FileOutputStream(imlFile))
-
-    } catch (NullPointerException | FileNotFoundException ex) {
-        ex.printStackTrace()
-    }
-}
-
 configurations {
     all {
         resolutionStrategy {
diff --git a/app/libs/android.jar b/app/libs/android.jar
index 8e479c1..48002e3 100644
--- a/app/libs/android.jar
+++ b/app/libs/android.jar
Binary files differ
diff --git a/app/libs/libcore.jar b/app/libs/libcore.jar
index c79b11f..94d798d 100644
--- a/app/libs/libcore.jar
+++ b/app/libs/libcore.jar
Binary files differ
diff --git a/app/src/androidTest/java/com/stevesoltys/seedvault/PluginTest.kt b/app/src/androidTest/java/com/stevesoltys/seedvault/PluginTest.kt
index 2045add..688f01b 100644
--- a/app/src/androidTest/java/com/stevesoltys/seedvault/PluginTest.kt
+++ b/app/src/androidTest/java/com/stevesoltys/seedvault/PluginTest.kt
@@ -23,8 +23,8 @@
 import org.junit.Before
 import org.junit.Test
 import org.junit.runner.RunWith
-import org.koin.core.KoinComponent
-import org.koin.core.inject
+import org.koin.core.component.KoinComponent
+import org.koin.core.component.inject
 
 @RunWith(AndroidJUnit4::class)
 @Suppress("BlockingMethodInNonBlockingContext")
diff --git a/app/src/androidTest/java/com/stevesoltys/seedvault/plugins/saf/DocumentsStorageTest.kt b/app/src/androidTest/java/com/stevesoltys/seedvault/plugins/saf/DocumentsStorageTest.kt
index 8068aed..d6bdf68 100644
--- a/app/src/androidTest/java/com/stevesoltys/seedvault/plugins/saf/DocumentsStorageTest.kt
+++ b/app/src/androidTest/java/com/stevesoltys/seedvault/plugins/saf/DocumentsStorageTest.kt
@@ -32,8 +32,8 @@
 import org.junit.Before
 import org.junit.Test
 import org.junit.runner.RunWith
-import org.koin.core.KoinComponent
-import org.koin.core.inject
+import org.koin.core.component.KoinComponent
+import org.koin.core.component.inject
 import java.io.IOException
 import kotlin.random.Random
 
diff --git a/app/src/androidTest/java/com/stevesoltys/seedvault/transport/backup/PackageServiceTest.kt b/app/src/androidTest/java/com/stevesoltys/seedvault/transport/backup/PackageServiceTest.kt
index 4d5ecc2..64ea9c4 100644
--- a/app/src/androidTest/java/com/stevesoltys/seedvault/transport/backup/PackageServiceTest.kt
+++ b/app/src/androidTest/java/com/stevesoltys/seedvault/transport/backup/PackageServiceTest.kt
@@ -4,8 +4,8 @@
 import androidx.test.ext.junit.runners.AndroidJUnit4
 import org.junit.Test
 import org.junit.runner.RunWith
-import org.koin.core.KoinComponent
-import org.koin.core.inject
+import org.koin.core.component.KoinComponent
+import org.koin.core.component.inject
 
 @RunWith(AndroidJUnit4::class)
 class PackageServiceTest : KoinComponent {
diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index 7c330d9..79b2ea5 100644
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -129,7 +129,8 @@
         </receiver>
 
         <receiver
-            android:name=".SecretCodeReceiver">
+            android:name=".SecretCodeReceiver"
+            android:exported="true">
             <intent-filter>
                 <action android:name="android.telephony.action.SECRET_CODE" />
                 <!-- *#*#RESTORE#*#* -->
diff --git a/app/src/main/java/com/stevesoltys/seedvault/App.kt b/app/src/main/java/com/stevesoltys/seedvault/App.kt
index 9ac333e..b99e87b 100644
--- a/app/src/main/java/com/stevesoltys/seedvault/App.kt
+++ b/app/src/main/java/com/stevesoltys/seedvault/App.kt
@@ -7,6 +7,7 @@
 import android.os.Build
 import android.os.ServiceManager.getService
 import android.os.StrictMode
+import org.koin.core.logger.Level
 import com.stevesoltys.seedvault.crypto.cryptoModule
 import com.stevesoltys.seedvault.header.headerModule
 import com.stevesoltys.seedvault.metadata.MetadataManager
@@ -77,7 +78,7 @@
     }
 
     protected open fun startKoin() = startKoin {
-        androidLogger()
+        androidLogger(Level.ERROR)
         androidContext(this@App)
         modules(
             listOf(
diff --git a/app/src/main/java/com/stevesoltys/seedvault/UsbIntentReceiver.kt b/app/src/main/java/com/stevesoltys/seedvault/UsbIntentReceiver.kt
index 8f175a3..4800fce 100644
--- a/app/src/main/java/com/stevesoltys/seedvault/UsbIntentReceiver.kt
+++ b/app/src/main/java/com/stevesoltys/seedvault/UsbIntentReceiver.kt
@@ -22,7 +22,7 @@
 import com.stevesoltys.seedvault.storage.StorageBackupService.Companion.EXTRA_START_APP_BACKUP
 import com.stevesoltys.seedvault.transport.requestBackup
 import com.stevesoltys.seedvault.ui.storage.AUTHORITY_STORAGE
-import org.koin.core.context.KoinContextHandler.get
+import org.koin.core.context.GlobalContext.get
 import java.util.concurrent.TimeUnit.HOURS
 
 private val TAG = UsbIntentReceiver::class.java.simpleName
@@ -32,8 +32,8 @@
 class UsbIntentReceiver : UsbMonitor() {
 
     // using KoinComponent would crash robolectric tests :(
-    private val settingsManager: SettingsManager by lazy { get().get<SettingsManager>() }
-    private val metadataManager: MetadataManager by lazy { get().get<MetadataManager>() }
+    private val settingsManager: SettingsManager by lazy { get().get() }
+    private val metadataManager: MetadataManager by lazy { get().get() }
 
     override fun shouldMonitorStatus(context: Context, action: String, device: UsbDevice): Boolean {
         if (action != ACTION_USB_DEVICE_ATTACHED) return false
diff --git a/app/src/main/java/com/stevesoltys/seedvault/restore/RestoreErrorBroadcastReceiver.kt b/app/src/main/java/com/stevesoltys/seedvault/restore/RestoreErrorBroadcastReceiver.kt
index d8e3ed3..b3ad72c 100644
--- a/app/src/main/java/com/stevesoltys/seedvault/restore/RestoreErrorBroadcastReceiver.kt
+++ b/app/src/main/java/com/stevesoltys/seedvault/restore/RestoreErrorBroadcastReceiver.kt
@@ -6,7 +6,7 @@
 import android.content.Intent.FLAG_ACTIVITY_NEW_TASK
 import androidx.core.net.toUri
 import com.stevesoltys.seedvault.ui.notification.BackupNotificationManager
-import org.koin.core.context.KoinContextHandler.get
+import org.koin.core.context.GlobalContext.get
 
 internal const val ACTION_RESTORE_ERROR_UNINSTALL = "com.stevesoltys.seedvault.action.UNINSTALL"
 internal const val EXTRA_PACKAGE_NAME = "com.stevesoltys.seedvault.extra.PACKAGE_NAME"
diff --git a/app/src/main/java/com/stevesoltys/seedvault/transport/ConfigurableBackupTransport.kt b/app/src/main/java/com/stevesoltys/seedvault/transport/ConfigurableBackupTransport.kt
index 3592666..c4b6539 100644
--- a/app/src/main/java/com/stevesoltys/seedvault/transport/ConfigurableBackupTransport.kt
+++ b/app/src/main/java/com/stevesoltys/seedvault/transport/ConfigurableBackupTransport.kt
@@ -14,8 +14,8 @@
 import com.stevesoltys.seedvault.transport.backup.BackupCoordinator
 import com.stevesoltys.seedvault.transport.restore.RestoreCoordinator
 import kotlinx.coroutines.runBlocking
-import org.koin.core.KoinComponent
-import org.koin.core.inject
+import org.koin.core.component.KoinComponent
+import org.koin.core.component.inject
 
 // If we ever change this, we should use a ComponentName like the other backup transports.
 val TRANSPORT_ID: String = ConfigurableBackupTransport::class.java.name
diff --git a/app/src/main/java/com/stevesoltys/seedvault/transport/ConfigurableBackupTransportService.kt b/app/src/main/java/com/stevesoltys/seedvault/transport/ConfigurableBackupTransportService.kt
index 143b47a..69a3513 100644
--- a/app/src/main/java/com/stevesoltys/seedvault/transport/ConfigurableBackupTransportService.kt
+++ b/app/src/main/java/com/stevesoltys/seedvault/transport/ConfigurableBackupTransportService.kt
@@ -14,9 +14,9 @@
 import com.stevesoltys.seedvault.transport.backup.PackageService
 import com.stevesoltys.seedvault.ui.notification.BackupNotificationManager
 import com.stevesoltys.seedvault.ui.notification.NotificationBackupObserver
-import org.koin.core.KoinComponent
-import org.koin.core.context.KoinContextHandler.get
-import org.koin.core.inject
+import org.koin.core.component.KoinComponent
+import org.koin.core.component.inject
+import org.koin.core.context.GlobalContext.get
 
 private val TAG = ConfigurableBackupTransportService::class.java.simpleName
 
diff --git a/app/src/main/java/com/stevesoltys/seedvault/ui/notification/NotificationBackupObserver.kt b/app/src/main/java/com/stevesoltys/seedvault/ui/notification/NotificationBackupObserver.kt
index ef5fa80..2fdc262 100644
--- a/app/src/main/java/com/stevesoltys/seedvault/ui/notification/NotificationBackupObserver.kt
+++ b/app/src/main/java/com/stevesoltys/seedvault/ui/notification/NotificationBackupObserver.kt
@@ -11,8 +11,8 @@
 import com.stevesoltys.seedvault.R
 import com.stevesoltys.seedvault.metadata.MetadataManager
 import com.stevesoltys.seedvault.transport.backup.ExpectedAppTotals
-import org.koin.core.KoinComponent
-import org.koin.core.inject
+import org.koin.core.component.KoinComponent
+import org.koin.core.component.inject
 
 private val TAG = NotificationBackupObserver::class.java.simpleName
 
diff --git a/app/src/main/java/com/stevesoltys/seedvault/ui/recoverycode/RecoveryCodeInputFragment.kt b/app/src/main/java/com/stevesoltys/seedvault/ui/recoverycode/RecoveryCodeInputFragment.kt
index 8cb7fd8..4aa0963 100644
--- a/app/src/main/java/com/stevesoltys/seedvault/ui/recoverycode/RecoveryCodeInputFragment.kt
+++ b/app/src/main/java/com/stevesoltys/seedvault/ui/recoverycode/RecoveryCodeInputFragment.kt
@@ -166,6 +166,7 @@
 
     @RequiresApi(30)
     private fun storeNewCodeAfterAuth(input: List<CharSequence>) {
+        val context = requireContext()
         val biometricPrompt = BiometricPrompt.Builder(context)
             .setConfirmationRequired(true)
             .setTitle(getString(R.string.recovery_code_auth_title))
diff --git a/app/src/main/res/layout/fragment_restore_files_started.xml b/app/src/main/res/layout/fragment_restore_files_started.xml
index 8746717..df39a4a 100644
--- a/app/src/main/res/layout/fragment_restore_files_started.xml
+++ b/app/src/main/res/layout/fragment_restore_files_started.xml
@@ -10,11 +10,11 @@
         android:layout_width="32dp"
         android:layout_height="32dp"
         android:layout_margin="16dp"
-        android:tint="?android:colorAccent"
         app:layout_constraintEnd_toEndOf="parent"
         app:layout_constraintStart_toStartOf="parent"
         app:layout_constraintTop_toTopOf="parent"
         app:srcCompat="@drawable/ic_cloud_restore"
+        app:tint="?android:colorAccent"
         tools:ignore="ContentDescription" />
 
     <TextView
diff --git a/app/src/main/res/layout/fragment_restore_progress.xml b/app/src/main/res/layout/fragment_restore_progress.xml
index c2bd845..96d717c 100644
--- a/app/src/main/res/layout/fragment_restore_progress.xml
+++ b/app/src/main/res/layout/fragment_restore_progress.xml
@@ -23,11 +23,11 @@
         android:layout_width="32dp"
         android:layout_height="32dp"
         android:layout_margin="16dp"
-        android:tint="?android:colorAccent"
         app:layout_constraintEnd_toEndOf="parent"
         app:layout_constraintStart_toStartOf="parent"
         app:layout_constraintTop_toBottomOf="@+id/progressBar"
         app:srcCompat="@drawable/ic_cloud_download"
+        app:tint="?android:colorAccent"
         tools:ignore="ContentDescription" />
 
     <TextView
diff --git a/app/src/main/res/layout/fragment_restore_set.xml b/app/src/main/res/layout/fragment_restore_set.xml
index eba8d78..c4dc07d 100644
--- a/app/src/main/res/layout/fragment_restore_set.xml
+++ b/app/src/main/res/layout/fragment_restore_set.xml
@@ -10,11 +10,11 @@
         android:layout_width="32dp"
         android:layout_height="32dp"
         android:layout_margin="16dp"
-        android:tint="?android:colorAccent"
         app:layout_constraintEnd_toEndOf="parent"
         app:layout_constraintStart_toStartOf="parent"
         app:layout_constraintTop_toTopOf="parent"
         app:srcCompat="@drawable/ic_cloud_download"
+        app:tint="?android:colorAccent"
         tools:ignore="ContentDescription" />
 
     <TextView
diff --git a/app/src/main/res/layout/fragment_storage_check.xml b/app/src/main/res/layout/fragment_storage_check.xml
index 8965997..22c1185 100644
--- a/app/src/main/res/layout/fragment_storage_check.xml
+++ b/app/src/main/res/layout/fragment_storage_check.xml
@@ -10,11 +10,11 @@
         android:layout_width="32dp"
         android:layout_height="32dp"
         android:layout_margin="16dp"
-        android:tint="?android:colorAccent"
         app:layout_constraintEnd_toEndOf="parent"
         app:layout_constraintStart_toStartOf="parent"
         app:layout_constraintTop_toTopOf="parent"
         app:srcCompat="@drawable/ic_storage"
+        app:tint="?android:colorAccent"
         tools:ignore="ContentDescription" />
 
     <TextView
diff --git a/app/src/main/res/layout/fragment_storage_root.xml b/app/src/main/res/layout/fragment_storage_root.xml
index 3263f5b..cc746e9 100644
--- a/app/src/main/res/layout/fragment_storage_root.xml
+++ b/app/src/main/res/layout/fragment_storage_root.xml
@@ -10,11 +10,11 @@
         android:layout_width="32dp"
         android:layout_height="32dp"
         android:layout_margin="16dp"
-        android:tint="?android:colorAccent"
         app:layout_constraintEnd_toEndOf="parent"
         app:layout_constraintStart_toStartOf="parent"
         app:layout_constraintTop_toTopOf="parent"
         app:srcCompat="@drawable/ic_storage"
+        app:tint="?android:colorAccent"
         tools:ignore="ContentDescription" />
 
     <TextView
diff --git a/app/src/main/res/layout/header_snapshots.xml b/app/src/main/res/layout/header_snapshots.xml
index ea84481..fb712f2 100644
--- a/app/src/main/res/layout/header_snapshots.xml
+++ b/app/src/main/res/layout/header_snapshots.xml
@@ -10,11 +10,11 @@
         android:layout_width="32dp"
         android:layout_height="32dp"
         android:layout_margin="16dp"
-        android:tint="?android:colorAccent"
         app:layout_constraintEnd_toEndOf="parent"
         app:layout_constraintStart_toStartOf="parent"
         app:layout_constraintTop_toTopOf="parent"
         app:srcCompat="@drawable/ic_cloud_download"
+        app:tint="?android:colorAccent"
         tools:ignore="ContentDescription" />
 
     <TextView
diff --git a/build.gradle b/build.gradle
index 3acb684..dce917c 100644
--- a/build.gradle
+++ b/build.gradle
@@ -1,29 +1,31 @@
 buildscript {
     // 1.3.21 Android 10
     // 1.3.61 Android 11
+    // 1.4.30 Android 12
     // Check:
-    // https://android.googlesource.com/platform/external/kotlinc/+/refs/tags/android-11.0.0_r3/build.txt
-    ext.aosp_kotlin_version = '1.3.61'
+    // https://android.googlesource.com/platform/external/kotlinc/+/refs/tags/android-12.0.0_r2/build.txt
+    ext.aosp_kotlin_version = '1.4.31'  // 1.4.30 breaks Kotlin plugin in Android Studio
     ext.kotlin_version = '1.4.31'
 
     repositories {
         mavenCentral()
+        //noinspection JcenterRepositoryObsolete
         jcenter()
         google()
     }
     dependencies {
         //noinspection DifferentKotlinGradleVersion
         classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
-        classpath "com.google.protobuf:protobuf-gradle-plugin:0.8.14"
-        classpath 'com.android.tools.build:gradle:4.2.1'
+        classpath "com.google.protobuf:protobuf-gradle-plugin:0.8.17"
+        classpath 'com.android.tools.build:gradle:7.0.2'
     }
 }
 
 ext {
-    buildToolsVersion = '30.0.2'
-    compileSdkVersion = 30
+    buildToolsVersion = '31.0.0'
+    compileSdkVersion = 31
     minSdkVersion = 29
-    targetSdkVersion = 30
+    targetSdkVersion = 31
 }
 
 apply from: 'gradle/dependencies.gradle'
@@ -31,6 +33,7 @@
 allprojects {
     repositories {
         mavenCentral()
+        //noinspection JcenterRepositoryObsolete
         jcenter()
         google()
         maven { url 'https://jitpack.io' }
diff --git a/contactsbackup/build.gradle b/contactsbackup/build.gradle
index 8fb5026..c799969 100644
--- a/contactsbackup/build.gradle
+++ b/contactsbackup/build.gradle
@@ -2,15 +2,16 @@
 apply plugin: 'kotlin-android'
 
 android {
-    compileSdkVersion 30
-    buildToolsVersion "30.0.2"
+    compileSdkVersion rootProject.ext.compileSdkVersion
+    buildToolsVersion rootProject.ext.buildToolsVersion
 
     defaultConfig {
         applicationId "org.calyxos.backup.contacts"
-        minSdkVersion 30
-        targetSdkVersion 30
+        minSdkVersion rootProject.ext.minSdkVersion
+        targetSdkVersion rootProject.ext.targetSdkVersion
 
         testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
+        testInstrumentationRunnerArguments disableAnalytics: 'true'
     }
 
     compileOptions {
@@ -18,6 +19,10 @@
         targetCompatibility = 1.8
     }
 
+    kotlinOptions {
+        jvmTarget = '1.8'
+    }
+
     testOptions {
         unitTests.returnDefaultValues = true
     }
@@ -55,7 +60,7 @@
     testImplementation "io.mockk:mockk:$mockk_version"
 
     androidTestImplementation "org.jetbrains.kotlin:kotlin-stdlib-jdk8:$kotlin_version"
-    androidTestImplementation 'androidx.test.ext:junit:1.1.2'
+    androidTestImplementation 'androidx.test.ext:junit:1.1.3'
     androidTestImplementation "androidx.test.espresso:espresso-core:$espresso_version"
     androidTestImplementation "io.mockk:mockk-android:$mockk_version"
 }
diff --git a/contactsbackup/libs/com.android.vcard.jar b/contactsbackup/libs/com.android.vcard.jar
index 9cd0189..f677ef6 100644
--- a/contactsbackup/libs/com.android.vcard.jar
+++ b/contactsbackup/libs/com.android.vcard.jar
Binary files differ
diff --git a/gradle/dependencies.gradle b/gradle/dependencies.gradle
index a0b53e8..607af4e 100644
--- a/gradle/dependencies.gradle
+++ b/gradle/dependencies.gradle
@@ -1,12 +1,12 @@
 ext {
-    // https://android.googlesource.com/platform/prebuilts/sdk/+/refs/tags/android-11.0.0_r3/current/androidx/Android.bp#2713
-    ext.room_version = "2.3.0-alpha02"
-    // http://aosp.opersys.com/xref/android-11.0.0_r27/xref/external/protobuf/java/pom.xml#7
+    // https://android.googlesource.com/platform/prebuilts/sdk/+/refs/tags/android-12.0.0_r2/current/androidx/Android.bp#2943
+    ext.room_version = "2.3.0-beta02"
+    // https://android.googlesource.com/platform/external/protobuf/+/refs/tags/android-12.0.0_r2/java/pom.xml#7
     ext.protobuf_version = "3.9.1"
     junit4_version = "4.13.2"
     junit5_version = "5.5.2" // careful, upgrading this can change a Cipher's IV size in tests!?
-    mockk_version = "1.10.2" // higher versions get us a kotlin version conflict
-    espresso_version = "3.3.0"
+    mockk_version = "1.12.0"
+    espresso_version = "3.4.0"
 }
 
 // To produce these binaries, in latest AOSP source tree, run
@@ -19,7 +19,7 @@
     //
     // out/target/common/obj/JAVA_LIBRARIES/framework-minus-apex_intermediates/classes.jar
     'android.jar',
-    // out/target/common/obj/JAVA_LIBRARIES/core-libart.com.android.art.release_intermediates/classes.jar
+    // out/target/common/obj/JAVA_LIBRARIES/core-libart.com.android.art_intermediates/classes.jar
     'libcore.jar',
 ], dir: "$projectDir/app/libs")
 
@@ -36,66 +36,74 @@
         },
     ],
     coroutines: [
-        dependencies.create('org.jetbrains.kotlinx:kotlinx-coroutines-core') {
-            // https://android.googlesource.com/platform/prebuilts/tools/+/refs/tags/android-11.0.0_r3/common/m2/Android.bp#326
-            version { strictly '1.3.0' }
+        dependencies.create('org.jetbrains.kotlinx:kotlinx-coroutines-core-jvm') {
+            // https://android.googlesource.com/platform/prebuilts/tools/+/refs/tags/android-12.0.0_r2/common/m2/Android.bp#273
+            version { strictly '1.4.2' }
         },
         dependencies.create('org.jetbrains.kotlinx:kotlinx-coroutines-android') {
-            // https://android.googlesource.com/platform/prebuilts/tools/+/refs/tags/android-11.0.0_r3/common/m2/Android.bp#340
+            // https://android.googlesource.com/platform/prebuilts/tools/+/refs/tags/android-12.0.0_r2/common/m2/Android.bp#288
             version { strictly '1.3.0' }
         },
     ],
 ]
 
 ext.std_libs = [
-    // https://android.googlesource.com/platform/prebuilts/sdk/+/refs/tags/android-11.0.0_r3/current/androidx/Android.bp#610
-    androidx_core: dependencies.create('androidx.core:core-ktx') {
-        version { strictly '1.5.0-alpha01' }
-    },
-    // https://android.googlesource.com/platform/prebuilts/sdk/+/refs/tags/android-11.0.0_r3/current/androidx/Android.bp#930
+    androidx_core: [
+        // https://android.googlesource.com/platform/prebuilts/sdk/+/refs/tags/android-12.0.0_r2/current/androidx/Android.bp#867
+        dependencies.create('androidx.core:core') {
+            version { strictly '1.6.0' } // should be 1.6.0-beta03, but that is not even released, yet
+        },
+        // https://android.googlesource.com/platform/prebuilts/sdk/+/refs/tags/android-12.0.0_r2/current/androidx/Android.bp#833
+        dependencies.create('androidx.core:core-ktx') {
+            version { strictly '1.5.0-beta02' }
+        },
+    ],
+    // https://android.googlesource.com/platform/prebuilts/sdk/+/refs/tags/android-12.0.0_r2/current/androidx/Android.bp#1189
     androidx_fragment: dependencies.create('androidx.fragment:fragment-ktx') {
-        version { strictly '1.3.0-alpha07' }
+        version { strictly '1.4.0-alpha01' }
     },
-    // https://android.googlesource.com/platform/prebuilts/sdk/+/refs/tags/android-11.0.0_r3/current/androidx/Android.bp#2412
+    // https://android.googlesource.com/platform/prebuilts/sdk/+/refs/tags/android-12.0.0_r2/current/androidx/Android.bp#20
+    androidx_activity: dependencies.create('androidx.activity:activity-ktx') {
+        version { strictly '1.3.0-alpha03' }
+    },
+    // https://android.googlesource.com/platform/prebuilts/sdk/+/refs/tags/android-12.0.0_r2/current/androidx/Android.bp#2695
     androidx_preference: dependencies.create('androidx.preference:preference') {
         version { strictly '1.1.1' } // should be 1.2.0-alpha01, but that is not even released, yet
     },
-    // https://android.googlesource.com/platform/prebuilts/sdk/+/refs/tags/android-11.0.0_r3/current/androidx/Android.bp#1553
+    // https://android.googlesource.com/platform/prebuilts/sdk/+/refs/tags/android-12.0.0_r2/current/androidx/Android.bp#1820
     androidx_lifecycle_viewmodel_ktx: dependencies.create('androidx.lifecycle:lifecycle-viewmodel-ktx') {
-        version { strictly '2.3.0-alpha05' }
+        version { strictly '2.4.0-alpha01' }
     },
-    // https://android.googlesource.com/platform/prebuilts/sdk/+/refs/tags/android-11.0.0_r3/current/androidx/Android.bp#1353
+    // https://android.googlesource.com/platform/prebuilts/sdk/+/refs/tags/android-12.0.0_r2/current/androidx/Android.bp#1618
     androidx_lifecycle_livedata_ktx: dependencies.create('androidx.lifecycle:lifecycle-livedata-ktx') {
-        version { strictly '2.3.0-alpha05' }
+        version { strictly '2.4.0-alpha01' }
     },
-    // https://android.googlesource.com/platform/prebuilts/sdk/+/refs/tags/android-11.0.0_r3/current/extras/constraint-layout-x/Android.bp#30
+    // https://android.googlesource.com/platform/prebuilts/sdk/+/refs/tags/android-12.0.0_r2/current/extras/constraint-layout-x/Android.bp#39
     androidx_constraintlayout: dependencies.create('androidx.constraintlayout:constraintlayout') {
         version { strictly '2.0.0-beta7' }
     },
-    // https://android.googlesource.com/platform/prebuilts/sdk/+/refs/tags/android-11.0.0_r3/current/androidx/Android.bp#708
+    // https://android.googlesource.com/platform/prebuilts/sdk/+/refs/tags/android-12.0.0_r2/current/androidx/Android.bp#969
     androidx_documentfile: dependencies.create('androidx.documentfile:documentfile') {
-        version { strictly '1.0.1' } // should be 1.1.0-alpha01, but that is not even released, yet
+        version { strictly '1.1.0-alpha01' }
     },
-    // https://android.googlesource.com/platform/prebuilts/sdk/+/refs/tags/android-11.0.0_r3/current/extras/material-design-x/Android.bp#6
+    // https://android.googlesource.com/platform/prebuilts/sdk/+/refs/tags/android-12.0.0_r2/current/extras/material-design-x/Android.bp#6
     com_google_android_material: dependencies.create('com.google.android.material:material') {
-        version { strictly '1.1.0-alpha05' }
+        version { strictly '1.4.0' }
     },
 ]
 
 ext.lint_libs = [
-    exceptions: 'com.github.thirdegg:lint-rules:0.0.7-beta'
+    exceptions: 'com.github.thirdegg:lint-rules:0.0.6-beta'
 ]
 
 ext.storage_libs = [
-    // https://android.googlesource.com/platform/prebuilts/sdk/+/refs/tags/android-11.0.0_r3/current/androidx/Android.bp#2711
     androidx_room_runtime: dependencies.create('androidx.room:room-runtime') {
         version { strictly "$room_version" }
     },
-    // http://aosp.opersys.com/xref/android-11.0.0_r27/xref/external/protobuf/java/pom.xml#7
     com_google_protobuf_javalite: dependencies.create('com.google.protobuf:protobuf-javalite') {
         version { strictly "$protobuf_version" }
     },
     com_google_crypto_tink_android: dependencies.create('com.google.crypto.tink:tink-android') {
-        version { strictly '1.5.0' }
+        version { strictly '1.6.1' }
     },
 ]
diff --git a/gradle/ktlint.gradle b/gradle/ktlint.gradle
index 2b6cd8f..10a7cb0 100644
--- a/gradle/ktlint.gradle
+++ b/gradle/ktlint.gradle
@@ -1,11 +1,11 @@
 ktlint {
-    version = "0.40.0"
+    version = "0.42.1"
     android = true
     enableExperimentalRules = false
     verbose = true
     disabledRules = [
             "import-ordering",
             "no-blank-line-before-rbrace",
-            "indent", // remove in 0.41 https://github.com/pinterest/ktlint/issues/764
+            "indent",
     ]
 }
diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties
index 43550d3..20d1c07 100644
--- a/gradle/wrapper/gradle-wrapper.properties
+++ b/gradle/wrapper/gradle-wrapper.properties
@@ -3,5 +3,5 @@
 distributionPath=wrapper/dists
 zipStoreBase=GRADLE_USER_HOME
 zipStorePath=wrapper/dists
-distributionUrl=https\://services.gradle.org/distributions/gradle-6.7.1-all.zip
-distributionSha256Sum=22449f5231796abd892c98b2a07c9ceebe4688d192cd2d6763f8e3bf8acbedeb
+distributionUrl=https\://services.gradle.org/distributions/gradle-7.2-all.zip
+distributionSha256Sum=a8da5b02437a60819cad23e10fc7e9cf32bcb57029d9cb277e26eeff76ce014b
diff --git a/libs/koin-android/Android.bp b/libs/koin-android/Android.bp
index a57460e..1df86bb 100644
--- a/libs/koin-android/Android.bp
+++ b/libs/koin-android/Android.bp
@@ -1,17 +1,11 @@
 android_library_import {
-    name: "seedvault-lib-koin-androidx-viewmodel",
-    aars: ["koin-androidx-viewmodel-2.1.1.aar"],
-    sdk_version: "current",
-}
-
-android_library_import {
     name: "seedvault-lib-koin-android",
-    aars: ["koin-android-2.1.1.aar"],
+    aars: ["koin-android-3.1.2.aar"],
     sdk_version: "current",
 }
 
 java_import {
-    name: "seedvault-lib-koin-core",
-    jars: ["koin-core-2.1.1.jar"],
+    name: "seedvault-lib-koin-core-jvm",
+    jars: ["koin-core-jvm-3.1.2.jar"],
     sdk_version: "current",
 }
diff --git a/libs/koin-android/koin-android-2.1.1.aar b/libs/koin-android/koin-android-2.1.1.aar
deleted file mode 100644
index 9d27100..0000000
--- a/libs/koin-android/koin-android-2.1.1.aar
+++ /dev/null
Binary files differ
diff --git a/libs/koin-android/koin-android-3.1.2.aar b/libs/koin-android/koin-android-3.1.2.aar
new file mode 100644
index 0000000..be74b75
--- /dev/null
+++ b/libs/koin-android/koin-android-3.1.2.aar
Binary files differ
diff --git a/libs/koin-android/koin-androidx-viewmodel-2.1.1.aar b/libs/koin-android/koin-androidx-viewmodel-2.1.1.aar
deleted file mode 100644
index fcd6876..0000000
--- a/libs/koin-android/koin-androidx-viewmodel-2.1.1.aar
+++ /dev/null
Binary files differ
diff --git a/libs/koin-android/koin-core-2.1.1.jar b/libs/koin-android/koin-core-2.1.1.jar
deleted file mode 100644
index 1e7ee56..0000000
--- a/libs/koin-android/koin-core-2.1.1.jar
+++ /dev/null
Binary files differ
diff --git a/libs/koin-android/koin-core-jvm-3.1.2.jar b/libs/koin-android/koin-core-jvm-3.1.2.jar
new file mode 100644
index 0000000..0efd173
--- /dev/null
+++ b/libs/koin-android/koin-core-jvm-3.1.2.jar
Binary files differ
diff --git a/storage/demo/build.gradle b/storage/demo/build.gradle
index 1d4c63e..6950ebc 100644
--- a/storage/demo/build.gradle
+++ b/storage/demo/build.gradle
@@ -34,6 +34,10 @@
         jvmTarget = '1.8'
         freeCompilerArgs += "-Xopt-in=kotlin.RequiresOptIn"
     }
+    lintOptions {
+        disable "DialogFragmentCallbacksDetector",
+                "InvalidFragmentVersionForActivityResult"
+    }
     packagingOptions {
         exclude 'META-INF/*.kotlin_module'
         exclude 'META-INF/androidx.*.version'
@@ -45,9 +49,12 @@
 dependencies {
     implementation project(':storage:lib')
 
+    implementation rootProject.ext.kotlin_libs.std
+
     implementation rootProject.ext.std_libs.androidx_core
     // A newer version gets pulled in with AOSP via core, so we include fragment here explicitly
     implementation rootProject.ext.std_libs.androidx_fragment
+    implementation rootProject.ext.std_libs.androidx_activity
     implementation rootProject.ext.std_libs.androidx_lifecycle_viewmodel_ktx
     implementation rootProject.ext.std_libs.androidx_lifecycle_livedata_ktx
     implementation rootProject.ext.std_libs.androidx_constraintlayout
diff --git a/storage/demo/src/main/AndroidManifest.xml b/storage/demo/src/main/AndroidManifest.xml
index 6846fa3..43a2b25 100644
--- a/storage/demo/src/main/AndroidManifest.xml
+++ b/storage/demo/src/main/AndroidManifest.xml
@@ -11,7 +11,9 @@
         android:supportsRtl="true"
         android:theme="@style/Theme.StorageBackupTester">
 
-        <activity android:name=".MainActivity">
+        <activity
+            android:name=".MainActivity"
+            android:exported="true">
             <intent-filter>
                 <action android:name="android.intent.action.MAIN" />
 
diff --git a/storage/lib/Android.bp b/storage/lib/Android.bp
index b5f8679..53927dd 100644
--- a/storage/lib/Android.bp
+++ b/storage/lib/Android.bp
@@ -10,6 +10,6 @@
 
 java_import {
     name: "seedvault-lib-tink-android",
-    jars: ["libs/tink-android-1.5.0.jar"],
+    jars: ["libs/tink-android-1.6.1.jar"],
     sdk_version: "current",
 }
diff --git a/storage/lib/build.gradle b/storage/lib/build.gradle
index 5702127..1384e5d 100644
--- a/storage/lib/build.gradle
+++ b/storage/lib/build.gradle
@@ -3,7 +3,7 @@
     id 'com.google.protobuf'
     id 'kotlin-android'
     id 'kotlin-kapt'
-    id "org.jlleitschuh.gradle.ktlint" version "9.4.0"
+    id "org.jlleitschuh.gradle.ktlint" version "10.2.0"
     id 'org.jetbrains.dokka' version '1.4.20'
 }
 
@@ -14,8 +14,6 @@
     defaultConfig {
         minSdkVersion rootProject.ext.minSdkVersion
         targetSdkVersion rootProject.ext.targetSdkVersion
-        versionCode 1
-        versionName "0.1"
 
         testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
         testInstrumentationRunnerArguments disableAnalytics: 'true'
@@ -40,6 +38,7 @@
     }
     kotlinOptions {
         jvmTarget = '1.8'
+        languageVersion = "1.4"
         freeCompilerArgs += '-Xopt-in=kotlin.RequiresOptIn'
         freeCompilerArgs += '-Xexplicit-api=strict'
     }
@@ -57,6 +56,11 @@
             }
         }
     }
+    lintOptions {
+        disable "DialogFragmentCallbacksDetector",
+                "InvalidFragmentVersionForActivityResult",
+                "CheckedExceptions"
+    }
 }
 
 kotlin {
@@ -64,11 +68,12 @@
 }
 
 dependencies {
-    implementation "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version"
+    implementation rootProject.ext.kotlin_libs.std
 
     implementation rootProject.ext.std_libs.androidx_core
     // A newer version gets pulled in with AOSP via core, so we include fragment here explicitly
     implementation rootProject.ext.std_libs.androidx_fragment
+    implementation rootProject.ext.std_libs.androidx_activity
     implementation rootProject.ext.std_libs.androidx_lifecycle_viewmodel_ktx
     implementation rootProject.ext.std_libs.androidx_lifecycle_livedata_ktx
     implementation rootProject.ext.std_libs.androidx_constraintlayout
@@ -88,7 +93,7 @@
     testImplementation "io.mockk:mockk:$mockk_version"
     testImplementation "org.jetbrains.kotlin:kotlin-test-junit:$kotlin_version"
 
-    androidTestImplementation 'androidx.test.ext:junit:1.1.2'
+    androidTestImplementation 'androidx.test.ext:junit:1.1.3'
     androidTestImplementation "androidx.test.espresso:espresso-core:$espresso_version"
 }
 
diff --git a/storage/lib/build/outputs/aar/lib-release.aar b/storage/lib/build/outputs/aar/lib-release.aar
index 974a8e1..942397d 100644
--- a/storage/lib/build/outputs/aar/lib-release.aar
+++ b/storage/lib/build/outputs/aar/lib-release.aar
Binary files differ
diff --git a/storage/lib/libs/tink-android-1.5.0.jar b/storage/lib/libs/tink-android-1.5.0.jar
deleted file mode 100644
index 626846e..0000000
--- a/storage/lib/libs/tink-android-1.5.0.jar
+++ /dev/null
Binary files differ
diff --git a/storage/lib/libs/tink-android-1.6.1.jar b/storage/lib/libs/tink-android-1.6.1.jar
new file mode 100644
index 0000000..4929a0c
--- /dev/null
+++ b/storage/lib/libs/tink-android-1.6.1.jar
Binary files differ