diff --git a/Corona-Warn-App/build.gradle b/Corona-Warn-App/build.gradle
index 78fd7e894078a33843cccfa962432e91964eb350..58504f84efee070a02cb853a3df817c25ae4faaa 100644
--- a/Corona-Warn-App/build.gradle
+++ b/Corona-Warn-App/build.gradle
@@ -43,7 +43,7 @@ android {
         versionCode 43
         versionName "1.5.0"
 
-        testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
+        testInstrumentationRunner "testhelpers.TestApplicationUIRunner"
 
         resConfigs "de", "en", "tr", "bg", "pl", "ro"
 
@@ -166,6 +166,12 @@ android {
                 srcDirs = ['src/device']
             }
         }
+        test {
+            java.srcDirs += "$projectDir/src/testShared/java"
+        }
+        androidTest {
+            java.srcDirs += "$projectDir/src/testShared/java"
+        }
     }
 
 }
@@ -237,6 +243,7 @@ dependencies {
     implementation 'com.google.dagger:dagger-android-support:2.28.1'
     kapt 'com.google.dagger:dagger-compiler:2.28.1'
     kapt 'com.google.dagger:dagger-android-processor:2.28.1'
+    kaptAndroidTest 'com.google.dagger:dagger-compiler:2.28.1'
 
     compileOnly 'com.squareup.inject:assisted-inject-annotations-dagger2:0.5.2'
     kapt 'com.squareup.inject:assisted-inject-processor-dagger2:0.5.2'
@@ -274,6 +281,7 @@ dependencies {
     androidTestImplementation "io.kotest:kotest-property-jvm:4.2.0"
 
     // Testing - Instrumentation
+    androidTestImplementation 'junit:junit:4.13'
     androidTestImplementation 'androidx.test:runner:1.2.0'
     androidTestImplementation 'androidx.test.ext:junit:1.1.1'
     androidTestImplementation 'androidx.test.espresso:espresso-core:3.2.0'
@@ -282,7 +290,7 @@ dependencies {
     androidTestImplementation 'androidx.test.ext:junit:1.1.1'
     androidTestImplementation 'androidx.work:work-testing:2.3.4'
     androidTestImplementation "io.mockk:mockk-android:1.10.0"
-    debugImplementation 'androidx.fragment:fragment-testing:1.2.4'
+    debugImplementation 'androidx.fragment:fragment-testing:1.2.5'
 
     // Play Services
     implementation 'com.google.android.play:core:1.7.3'
diff --git a/Corona-Warn-App/src/androidTest/java/de/rki/coronawarnapp/ui/main/home/HomeFragmentTest.kt b/Corona-Warn-App/src/androidTest/java/de/rki/coronawarnapp/ui/main/home/HomeFragmentTest.kt
new file mode 100644
index 0000000000000000000000000000000000000000..baca08057b15de030d15f00903646f5e75497ea9
--- /dev/null
+++ b/Corona-Warn-App/src/androidTest/java/de/rki/coronawarnapp/ui/main/home/HomeFragmentTest.kt
@@ -0,0 +1,46 @@
+package de.rki.coronawarnapp.ui.main.home
+
+import androidx.fragment.app.testing.launchFragment
+import androidx.test.ext.junit.runners.AndroidJUnit4
+import dagger.Module
+import dagger.android.ContributesAndroidInjector
+import io.mockk.MockKAnnotations
+import io.mockk.impl.annotations.MockK
+import org.junit.After
+import org.junit.Before
+import org.junit.Test
+import org.junit.runner.RunWith
+import testhelpers.BaseUITest
+
+@RunWith(AndroidJUnit4::class)
+class HomeFragmentTest : BaseUITest() {
+
+    @MockK lateinit var viewModel: HomeFragmentViewModel
+
+    @Before
+    fun setup() {
+        MockKAnnotations.init(this, relaxed = true)
+
+        setupMockViewModel(object : HomeFragmentViewModel.Factory {
+            override fun create(): HomeFragmentViewModel = viewModel
+        })
+    }
+
+    @After
+    fun teardown() {
+        clearAllViewModels()
+    }
+
+    @Test
+    fun launch_fragment() {
+        launchFragment<HomeFragment>()
+
+        // ...
+    }
+}
+
+@Module
+abstract class HomeFragmentTestModule {
+    @ContributesAndroidInjector
+    abstract fun homeScreen(): HomeFragment
+}
diff --git a/Corona-Warn-App/src/androidTest/java/testhelpers/BaseUITest.kt b/Corona-Warn-App/src/androidTest/java/testhelpers/BaseUITest.kt
new file mode 100644
index 0000000000000000000000000000000000000000..8f487ee1d746d8f6a6ce44f5696e225333269392
--- /dev/null
+++ b/Corona-Warn-App/src/androidTest/java/testhelpers/BaseUITest.kt
@@ -0,0 +1,16 @@
+package testhelpers
+
+import de.rki.coronawarnapp.util.viewmodel.CWAViewModel
+import de.rki.coronawarnapp.util.viewmodel.SimpleCWAViewModelFactory
+import testhelpers.viewmodels.MockViewModelModule
+
+abstract class BaseUITest : BaseTest() {
+
+    inline fun <reified T : CWAViewModel> setupMockViewModel(factory: SimpleCWAViewModelFactory<T>) {
+        MockViewModelModule.CREATORS[T::class.java] = factory
+    }
+
+    fun clearAllViewModels() {
+        MockViewModelModule.CREATORS.clear()
+    }
+}
diff --git a/Corona-Warn-App/src/androidTest/java/testhelpers/FragmentTestModuleRegistrar.kt b/Corona-Warn-App/src/androidTest/java/testhelpers/FragmentTestModuleRegistrar.kt
new file mode 100644
index 0000000000000000000000000000000000000000..310356920dc95d8dd8b244950ff0e93bb796fd2e
--- /dev/null
+++ b/Corona-Warn-App/src/androidTest/java/testhelpers/FragmentTestModuleRegistrar.kt
@@ -0,0 +1,11 @@
+package testhelpers
+
+import dagger.Module
+import de.rki.coronawarnapp.ui.main.home.HomeFragmentTestModule
+
+@Module(
+    includes = [
+        HomeFragmentTestModule::class
+    ]
+)
+class FragmentTestModuleRegistrar
diff --git a/Corona-Warn-App/src/androidTest/java/testhelpers/TestAppComponent.kt b/Corona-Warn-App/src/androidTest/java/testhelpers/TestAppComponent.kt
new file mode 100644
index 0000000000000000000000000000000000000000..53c3c747ce83f218775dd3176b7479f25ed127b7
--- /dev/null
+++ b/Corona-Warn-App/src/androidTest/java/testhelpers/TestAppComponent.kt
@@ -0,0 +1,24 @@
+package testhelpers
+
+import dagger.BindsInstance
+import dagger.Component
+import dagger.android.AndroidInjector
+import dagger.android.support.AndroidSupportInjectionModule
+import testhelpers.viewmodels.MockViewModelModule
+import javax.inject.Singleton
+
+@Component(
+    modules = [
+        AndroidSupportInjectionModule::class,
+        MockViewModelModule::class,
+        FragmentTestModuleRegistrar::class
+    ]
+)
+@Singleton
+interface TestAppComponent : AndroidInjector<TestApplication> {
+
+    @Component.Factory
+    interface Factory {
+        fun create(@BindsInstance app: TestApplication): TestAppComponent
+    }
+}
diff --git a/Corona-Warn-App/src/androidTest/java/testhelpers/TestApplication.kt b/Corona-Warn-App/src/androidTest/java/testhelpers/TestApplication.kt
new file mode 100644
index 0000000000000000000000000000000000000000..dc215f0144b1ab17d0d34e59634b69a206e08784
--- /dev/null
+++ b/Corona-Warn-App/src/androidTest/java/testhelpers/TestApplication.kt
@@ -0,0 +1,72 @@
+package testhelpers
+
+import android.app.Activity
+import android.app.Application
+import android.content.Context
+import android.os.Bundle
+import androidx.fragment.app.Fragment
+import androidx.fragment.app.FragmentActivity
+import androidx.fragment.app.FragmentManager
+import dagger.android.AndroidInjector
+import dagger.android.DispatchingAndroidInjector
+import dagger.android.HasAndroidInjector
+import dagger.android.support.AndroidSupportInjection
+import de.rki.coronawarnapp.util.di.AutoInject
+import timber.log.Timber
+import javax.inject.Inject
+
+class TestApplication : Application(), HasAndroidInjector {
+    @Inject lateinit var androidInjector: DispatchingAndroidInjector<Any>
+    override fun androidInjector(): AndroidInjector<Any> = androidInjector
+
+    private lateinit var component: TestAppComponent
+
+    override fun onCreate() {
+        super.onCreate()
+        component = DaggerTestAppComponent.factory().create(this)
+        component.inject(this)
+        setupActivityHook()
+    }
+
+    private fun setupActivityHook() {
+        registerActivityLifecycleCallbacks(object : ActivityLifecycleCallbacks {
+            override fun onActivityPreCreated(activity: Activity, savedInstanceState: Bundle?) {
+                setupFragmentHook(activity)
+            }
+
+            override fun onActivityCreated(activity: Activity, savedInstanceState: Bundle?) = Unit
+
+            override fun onActivityStarted(activity: Activity) = Unit
+
+            override fun onActivityResumed(activity: Activity) = Unit
+
+            override fun onActivityPaused(activity: Activity) = Unit
+
+            override fun onActivityStopped(activity: Activity) = Unit
+
+            override fun onActivitySaveInstanceState(activity: Activity, outState: Bundle?) = Unit
+
+            override fun onActivityDestroyed(activity: Activity) = Unit
+        })
+    }
+
+    private fun setupFragmentHook(activity: Activity) {
+        if (activity is FragmentActivity) {
+            activity.supportFragmentManager
+                .registerFragmentLifecycleCallbacks(object :
+                    FragmentManager.FragmentLifecycleCallbacks() {
+                    override fun onFragmentPreAttached(
+                        fm: FragmentManager,
+                        f: Fragment,
+                        context: Context
+                    ) {
+                        if (f is AutoInject) {
+                            Timber.d("Injecting %s", f)
+                            AndroidSupportInjection.inject(f)
+                        }
+                        super.onFragmentPreAttached(fm, f, context)
+                    }
+                }, true)
+        }
+    }
+}
diff --git a/Corona-Warn-App/src/androidTest/java/testhelpers/TestApplicationUIRunner.kt b/Corona-Warn-App/src/androidTest/java/testhelpers/TestApplicationUIRunner.kt
new file mode 100644
index 0000000000000000000000000000000000000000..1576aab58848a3aea939e1c69ba19cc597238522
--- /dev/null
+++ b/Corona-Warn-App/src/androidTest/java/testhelpers/TestApplicationUIRunner.kt
@@ -0,0 +1,12 @@
+package testhelpers
+
+import android.app.Application
+import android.content.Context
+import androidx.test.runner.AndroidJUnitRunner
+
+class TestApplicationUIRunner : AndroidJUnitRunner() {
+
+    override fun newApplication(cl: ClassLoader, className: String, context: Context): Application {
+        return super.newApplication(cl, TestApplication::class.java.name, context)
+    }
+}
diff --git a/Corona-Warn-App/src/androidTest/java/testhelpers/viewmodels/MockViewModelModule.kt b/Corona-Warn-App/src/androidTest/java/testhelpers/viewmodels/MockViewModelModule.kt
new file mode 100644
index 0000000000000000000000000000000000000000..1a4527b7915608bcdfc0614792b1b70f972edd53
--- /dev/null
+++ b/Corona-Warn-App/src/androidTest/java/testhelpers/viewmodels/MockViewModelModule.kt
@@ -0,0 +1,38 @@
+package testhelpers.viewmodels
+
+import android.os.Bundle
+import androidx.lifecycle.SavedStateHandle
+import androidx.savedstate.SavedStateRegistryOwner
+import dagger.Module
+import dagger.Provides
+import de.rki.coronawarnapp.util.viewmodel.CWAViewModel
+import de.rki.coronawarnapp.util.viewmodel.CWAViewModelFactory
+import de.rki.coronawarnapp.util.viewmodel.CWAViewModelFactoryProvider
+
+@Module
+class MockViewModelModule {
+
+    @Provides
+    fun viewmodelFactoryProvider(): CWAViewModelFactoryProvider.Factory {
+        val factory = object : CWAViewModelFactoryProvider.Factory {
+            override fun create(
+                savedStateOwner: SavedStateRegistryOwner,
+                defaultSavedState: Bundle?,
+                assistAction: ((CWAViewModelFactory<out CWAViewModel>, SavedStateHandle) -> CWAViewModel)?
+            ): CWAViewModelFactoryProvider {
+                return CWAViewModelFactoryProvider(
+                    CREATORS,
+                    savedStateOwner,
+                    defaultSavedState,
+                    assistAction
+                )
+            }
+        }
+        return factory
+    }
+
+    companion object {
+        val CREATORS: MutableMap<Class<out CWAViewModel>, CWAViewModelFactory<out CWAViewModel>> =
+            mutableMapOf()
+    }
+}
diff --git a/Corona-Warn-App/src/deviceForTesters/java/de/rki/coronawarnapp/test/api/ui/TestForApiFragmentViewModel.kt b/Corona-Warn-App/src/deviceForTesters/java/de/rki/coronawarnapp/test/api/ui/TestForApiFragmentViewModel.kt
index 5593009bb47d1ae831c2a115032e0c8577a22119..47f89e72e1b79d80d0973fb172ea81db548b18bb 100644
--- a/Corona-Warn-App/src/deviceForTesters/java/de/rki/coronawarnapp/test/api/ui/TestForApiFragmentViewModel.kt
+++ b/Corona-Warn-App/src/deviceForTesters/java/de/rki/coronawarnapp/test/api/ui/TestForApiFragmentViewModel.kt
@@ -15,6 +15,7 @@ import de.rki.coronawarnapp.test.api.ui.EnvironmentState.Companion.toEnvironment
 import de.rki.coronawarnapp.test.api.ui.LoggerState.Companion.toLoggerState
 import de.rki.coronawarnapp.transaction.RiskLevelTransaction
 import de.rki.coronawarnapp.util.CWADebug
+import de.rki.coronawarnapp.util.di.AppContext
 import de.rki.coronawarnapp.util.ui.SingleLiveEvent
 import de.rki.coronawarnapp.util.ui.smartLiveData
 import de.rki.coronawarnapp.util.viewmodel.CWAViewModel
@@ -24,7 +25,7 @@ import kotlinx.coroutines.launch
 import java.io.File
 
 class TestForApiFragmentViewModel @AssistedInject constructor(
-    private val context: Context,
+    @AppContext private val context: Context,
     private val envSetup: EnvironmentSetup
 ) : CWAViewModel() {
 
diff --git a/Corona-Warn-App/src/deviceForTesters/java/de/rki/coronawarnapp/test/risklevel/ui/TestRiskLevelCalculationFragmentCWAViewModel.kt b/Corona-Warn-App/src/deviceForTesters/java/de/rki/coronawarnapp/test/risklevel/ui/TestRiskLevelCalculationFragmentCWAViewModel.kt
index 7ba08ef6d67382d462fb1beca3af4f1519a90491..cd0b93eeb58ea136f14eeeca9da7cd6385275737 100644
--- a/Corona-Warn-App/src/deviceForTesters/java/de/rki/coronawarnapp/test/risklevel/ui/TestRiskLevelCalculationFragmentCWAViewModel.kt
+++ b/Corona-Warn-App/src/deviceForTesters/java/de/rki/coronawarnapp/test/risklevel/ui/TestRiskLevelCalculationFragmentCWAViewModel.kt
@@ -23,6 +23,7 @@ import de.rki.coronawarnapp.storage.RiskLevelRepository
 import de.rki.coronawarnapp.transaction.RetrieveDiagnosisKeysTransaction
 import de.rki.coronawarnapp.transaction.RiskLevelTransaction
 import de.rki.coronawarnapp.util.KeyFileHelper
+import de.rki.coronawarnapp.util.di.AppContext
 import de.rki.coronawarnapp.util.security.SecurityHelper
 import de.rki.coronawarnapp.util.ui.SingleLiveEvent
 import de.rki.coronawarnapp.util.viewmodel.CWAViewModel
@@ -41,7 +42,7 @@ import kotlin.coroutines.suspendCoroutine
 class TestRiskLevelCalculationFragmentCWAViewModel @AssistedInject constructor(
     @Assisted private val handle: SavedStateHandle,
     @Assisted private val exampleArg: String?,
-    private val context: Context, // App context
+    @AppContext private val context: Context, // App context
     private val enfClient: ENFClient,
     private val keyCacheRepository: KeyCacheRepository
 ) : CWAViewModel() {
diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/appconfig/AppConfigModule.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/appconfig/AppConfigModule.kt
index aa295a3523210e13dec27ad6f9338ed67c3efe6e..d742d73703505fd64f5655b46f5e85b7d38f0d0a 100644
--- a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/appconfig/AppConfigModule.kt
+++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/appconfig/AppConfigModule.kt
@@ -5,6 +5,7 @@ import dagger.Module
 import dagger.Provides
 import de.rki.coronawarnapp.environment.download.DownloadCDNHttpClient
 import de.rki.coronawarnapp.environment.download.DownloadCDNServerUrl
+import de.rki.coronawarnapp.util.di.AppContext
 import okhttp3.Cache
 import okhttp3.OkHttpClient
 import org.joda.time.Duration
@@ -20,7 +21,7 @@ class AppConfigModule {
     @Singleton
     @Provides
     fun provideAppConfigApi(
-        context: Context,
+        @AppContext context: Context,
         @DownloadCDNHttpClient client: OkHttpClient,
         @DownloadCDNServerUrl url: String,
         gsonConverterFactory: GsonConverterFactory
diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/appconfig/AppConfigStorage.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/appconfig/AppConfigStorage.kt
index 44edccd9c44b9163bcb367cd070e64fe7c4e38fb..f81d9bee07200b2d7669e67a0bd1cfe2bdf738c6 100644
--- a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/appconfig/AppConfigStorage.kt
+++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/appconfig/AppConfigStorage.kt
@@ -1,6 +1,7 @@
 package de.rki.coronawarnapp.appconfig
 
 import android.content.Context
+import de.rki.coronawarnapp.util.di.AppContext
 import timber.log.Timber
 import java.io.File
 import javax.inject.Inject
@@ -8,7 +9,7 @@ import javax.inject.Singleton
 
 @Singleton
 class AppConfigStorage @Inject constructor(
-    context: Context
+    @AppContext context: Context
 ) {
     private val configDir = File(context.filesDir, "appconfig_storage")
     private val configFile = File(configDir, "appconfig")
diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/diagnosiskeys/DiagnosisKeysModule.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/diagnosiskeys/DiagnosisKeysModule.kt
index 213c479c350ccd82d1d66325577d4db521362772..c106f0a7efcee86ec5362cda32960171c3064ae9 100644
--- a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/diagnosiskeys/DiagnosisKeysModule.kt
+++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/diagnosiskeys/DiagnosisKeysModule.kt
@@ -8,6 +8,7 @@ import de.rki.coronawarnapp.diagnosiskeys.storage.legacy.KeyCacheLegacyDao
 import de.rki.coronawarnapp.environment.download.DownloadCDNHttpClient
 import de.rki.coronawarnapp.environment.download.DownloadCDNServerUrl
 import de.rki.coronawarnapp.storage.AppDatabase
+import de.rki.coronawarnapp.util.di.AppContext
 import okhttp3.OkHttpClient
 import retrofit2.Retrofit
 import retrofit2.converter.gson.GsonConverterFactory
@@ -31,7 +32,7 @@ class DiagnosisKeysModule {
 
     @Singleton
     @Provides
-    fun legacyKeyCacheDao(context: Context): KeyCacheLegacyDao {
+    fun legacyKeyCacheDao(@AppContext context: Context): KeyCacheLegacyDao {
         return AppDatabase.getInstance(context).dateDao()
     }
 }
diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/diagnosiskeys/storage/KeyCacheDatabase.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/diagnosiskeys/storage/KeyCacheDatabase.kt
index e4be6ba47007ae858c1065509d49f6469bd71e11..ec23391b1878354a29a391cc3b30b111c3662563 100644
--- a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/diagnosiskeys/storage/KeyCacheDatabase.kt
+++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/diagnosiskeys/storage/KeyCacheDatabase.kt
@@ -12,6 +12,7 @@ import androidx.room.RoomDatabase
 import androidx.room.TypeConverters
 import androidx.room.Update
 import de.rki.coronawarnapp.util.database.CommonConverters
+import de.rki.coronawarnapp.util.di.AppContext
 import javax.inject.Inject
 
 @Database(
@@ -45,7 +46,7 @@ abstract class KeyCacheDatabase : RoomDatabase() {
         suspend fun updateDownloadState(update: CachedKeyInfo.DownloadUpdate)
     }
 
-    class Factory @Inject constructor(private val context: Context) {
+    class Factory @Inject constructor(@AppContext private val context: Context) {
         /**
          * The fallback behavior is to reset the app as we only store exposure summaries
          * and cached references that are non-critical to app operation.
diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/diagnosiskeys/storage/KeyCacheRepository.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/diagnosiskeys/storage/KeyCacheRepository.kt
index 4336c7ac87ff9de1ee0ef0052e0150a673a83f69..c6f42e84ed9982d3764161f5ebfb3f35babc161d 100644
--- a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/diagnosiskeys/storage/KeyCacheRepository.kt
+++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/diagnosiskeys/storage/KeyCacheRepository.kt
@@ -23,6 +23,7 @@ import android.content.Context
 import android.database.sqlite.SQLiteConstraintException
 import de.rki.coronawarnapp.diagnosiskeys.server.LocationCode
 import de.rki.coronawarnapp.util.TimeStamper
+import de.rki.coronawarnapp.util.di.AppContext
 import kotlinx.coroutines.sync.Mutex
 import kotlinx.coroutines.sync.withLock
 import org.joda.time.LocalDate
@@ -35,7 +36,7 @@ import javax.inject.Singleton
 
 @Singleton
 class KeyCacheRepository @Inject constructor(
-    private val context: Context,
+    @AppContext private val context: Context,
     private val databaseFactory: KeyCacheDatabase.Factory,
     private val timeStamper: TimeStamper
 ) {
diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/diagnosiskeys/storage/legacy/LegacyKeyCacheMigration.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/diagnosiskeys/storage/legacy/LegacyKeyCacheMigration.kt
index ca2cf95867b371a37bf8875325410289009ed0bd..b7b4113d75a8bba9d27107abee15f67cfe268ad7 100644
--- a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/diagnosiskeys/storage/legacy/LegacyKeyCacheMigration.kt
+++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/diagnosiskeys/storage/legacy/LegacyKeyCacheMigration.kt
@@ -5,6 +5,7 @@ import dagger.Lazy
 import de.rki.coronawarnapp.risk.TimeVariables
 import de.rki.coronawarnapp.util.HashExtensions.hashToMD5
 import de.rki.coronawarnapp.util.TimeStamper
+import de.rki.coronawarnapp.util.di.AppContext
 import kotlinx.coroutines.sync.Mutex
 import kotlinx.coroutines.sync.withLock
 import org.joda.time.Duration
@@ -14,7 +15,7 @@ import java.io.File
 import javax.inject.Inject
 
 class LegacyKeyCacheMigration @Inject constructor(
-    private val context: Context,
+    @AppContext private val context: Context,
     private val legacyDao: Lazy<KeyCacheLegacyDao>,
     private val timeStamper: TimeStamper
 ) {
diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/environment/EnvironmentSetup.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/environment/EnvironmentSetup.kt
index ea54dfb6d1bdb8cafc9683885ac6eb6e6001fd10..f8937d9b95530940f8c01fd36e34e3542f165abd 100644
--- a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/environment/EnvironmentSetup.kt
+++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/environment/EnvironmentSetup.kt
@@ -12,13 +12,14 @@ import de.rki.coronawarnapp.environment.EnvironmentSetup.EnvKey.VERIFICATION
 import de.rki.coronawarnapp.environment.EnvironmentSetup.EnvKey.VERIFICATION_KEYS
 import de.rki.coronawarnapp.environment.EnvironmentSetup.Type.Companion.toEnvironmentType
 import de.rki.coronawarnapp.util.CWADebug
+import de.rki.coronawarnapp.util.di.AppContext
 import timber.log.Timber
 import javax.inject.Inject
 import javax.inject.Singleton
 
 @Singleton
 class EnvironmentSetup @Inject constructor(
-    private val context: Context
+    @AppContext private val context: Context
 ) {
 
     enum class EnvKey(val rawKey: String) {
diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/nearby/ENFClientLocalData.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/nearby/ENFClientLocalData.kt
index 26564ab4af748c81731269262f78141e6b43c7de..91d977c961e1441e1fcfb932e7042411674080e2 100644
--- a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/nearby/ENFClientLocalData.kt
+++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/nearby/ENFClientLocalData.kt
@@ -2,13 +2,14 @@ package de.rki.coronawarnapp.nearby
 
 import android.content.Context
 import androidx.core.content.edit
+import de.rki.coronawarnapp.util.di.AppContext
 import org.joda.time.Instant
 import javax.inject.Inject
 import javax.inject.Singleton
 
 @Singleton
 class ENFClientLocalData @Inject constructor(
-    private val context: Context
+    @AppContext private val context: Context
 ) {
 
     private val prefs by lazy {
diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/nearby/ENFModule.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/nearby/ENFModule.kt
index 4b7094c8f709b45f7765061d8078771d5a0ec118..af07ccda5782ae2c1f3675b76b236a59813d1ff8 100644
--- a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/nearby/ENFModule.kt
+++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/nearby/ENFModule.kt
@@ -7,6 +7,7 @@ import dagger.Module
 import dagger.Provides
 import de.rki.coronawarnapp.nearby.modules.diagnosiskeyprovider.DefaultDiagnosisKeyProvider
 import de.rki.coronawarnapp.nearby.modules.diagnosiskeyprovider.DiagnosisKeyProvider
+import de.rki.coronawarnapp.util.di.AppContext
 import javax.inject.Singleton
 
 @Module
@@ -14,7 +15,7 @@ class ENFModule {
 
     @Singleton
     @Provides
-    fun exposureNotificationClient(context: Context): ExposureNotificationClient =
+    fun exposureNotificationClient(@AppContext context: Context): ExposureNotificationClient =
         Nearby.getExposureNotificationClient(context)
 
     @Singleton
diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/storage/DeviceStorage.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/storage/DeviceStorage.kt
index 412d5900f12b40b7dfff4b50163f5ef2351c03a6..5fd8d4b515fa97896907270b6e8769910511c67d 100644
--- a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/storage/DeviceStorage.kt
+++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/storage/DeviceStorage.kt
@@ -8,6 +8,7 @@ import android.os.storage.StorageManager
 import android.text.format.Formatter
 import dagger.Reusable
 import de.rki.coronawarnapp.util.ApiLevel
+import de.rki.coronawarnapp.util.di.AppContext
 import de.rki.coronawarnapp.util.storage.StatsFsProvider
 import kotlinx.coroutines.Dispatchers
 import kotlinx.coroutines.withContext
@@ -19,7 +20,7 @@ import javax.inject.Inject
 
 @Reusable
 class DeviceStorage @Inject constructor(
-    private val context: Context,
+    @AppContext private val context: Context,
     private val apiLevel: ApiLevel,
     private val statsFsProvider: StatsFsProvider
 ) {
diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/storage/SettingsRepository.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/storage/SettingsRepository.kt
index 54c2f41509a6404770d42a4d3aad856622cd4570..37b9e7c6770c57e4e7a4c1edd4786cfb06413cc7 100644
--- a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/storage/SettingsRepository.kt
+++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/storage/SettingsRepository.kt
@@ -5,6 +5,7 @@ import androidx.core.app.NotificationManagerCompat
 import androidx.lifecycle.MutableLiveData
 import de.rki.coronawarnapp.util.BackgroundPrioritization
 import de.rki.coronawarnapp.util.ConnectivityHelper
+import de.rki.coronawarnapp.util.di.AppContext
 import javax.inject.Inject
 import javax.inject.Singleton
 
@@ -18,7 +19,7 @@ import javax.inject.Singleton
  */
 @Singleton
 class SettingsRepository @Inject constructor(
-    private val context: Context,
+    @AppContext private val context: Context,
     private val backgroundPrioritization: BackgroundPrioritization
 ) {
 
diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/submission/SubmissionModule.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/submission/SubmissionModule.kt
index 437d565d657aa7035b039d102e247bff779f6ee8..cb5fd7406cc612452c1c8184e44cb76bb07e8589 100644
--- a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/submission/SubmissionModule.kt
+++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/submission/SubmissionModule.kt
@@ -9,6 +9,7 @@ import de.rki.coronawarnapp.http.HttpClientDefault
 import de.rki.coronawarnapp.http.RestrictedConnectionSpecs
 import de.rki.coronawarnapp.submission.server.SubmissionApiV1
 import de.rki.coronawarnapp.submission.server.SubmissionHttpClient
+import de.rki.coronawarnapp.util.di.AppContext
 import okhttp3.Cache
 import okhttp3.ConnectionSpec
 import okhttp3.OkHttpClient
@@ -33,7 +34,7 @@ class SubmissionModule {
     @Singleton
     @Provides
     fun provideSubmissionApi(
-        context: Context,
+        @AppContext context: Context,
         @SubmissionHttpClient client: OkHttpClient,
         @SubmissionCDNServerUrl url: String,
         protoConverterFactory: ProtoConverterFactory,
diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/main/MainActivityModule.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/main/MainActivityModule.kt
index 689223bc1972be310d9440d3bc6653e299602c28..4db9d98e17c9bf0959e1d159127dbf9b2d06f5d9 100644
--- a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/main/MainActivityModule.kt
+++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/main/MainActivityModule.kt
@@ -4,9 +4,17 @@ import dagger.Module
 import dagger.android.ContributesAndroidInjector
 import de.rki.coronawarnapp.ui.interoperability.InteroperabilityConfigurationFragment
 import de.rki.coronawarnapp.ui.interoperability.InteroperabilityConfigurationFragmentModule
+import de.rki.coronawarnapp.ui.main.home.HomeFragmentModule
 import de.rki.coronawarnapp.ui.onboarding.OnboardingDeltaInteroperabilityModule
+import de.rki.coronawarnapp.ui.riskdetails.RiskDetailsFragmentModule
 
-@Module(includes = [OnboardingDeltaInteroperabilityModule::class])
+@Module(
+    includes = [
+        OnboardingDeltaInteroperabilityModule::class,
+        HomeFragmentModule::class,
+        RiskDetailsFragmentModule::class
+    ]
+)
 abstract class MainActivityModule {
 
     // activity specific injection module for future dependencies
diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/main/MainFragment.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/main/MainFragment.kt
deleted file mode 100644
index db82cafc9c5b7084710bd046145f62b75eb560dd..0000000000000000000000000000000000000000
--- a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/main/MainFragment.kt
+++ /dev/null
@@ -1,234 +0,0 @@
-package de.rki.coronawarnapp.ui.main
-
-import android.os.Bundle
-import android.view.View
-import android.view.accessibility.AccessibilityEvent
-import android.widget.PopupMenu
-import androidx.fragment.app.Fragment
-import androidx.fragment.app.activityViewModels
-import androidx.lifecycle.lifecycleScope
-import androidx.navigation.fragment.findNavController
-import de.rki.coronawarnapp.R
-import de.rki.coronawarnapp.databinding.FragmentMainBinding
-import de.rki.coronawarnapp.risk.TimeVariables
-import de.rki.coronawarnapp.storage.LocalData
-import de.rki.coronawarnapp.timer.TimerHelper
-import de.rki.coronawarnapp.ui.doNavigate
-import de.rki.coronawarnapp.ui.viewmodel.SettingsViewModel
-import de.rki.coronawarnapp.ui.viewmodel.SubmissionViewModel
-import de.rki.coronawarnapp.ui.viewmodel.TracingViewModel
-import de.rki.coronawarnapp.util.CWADebug
-import de.rki.coronawarnapp.util.DialogHelper
-import de.rki.coronawarnapp.util.ExternalActionHelper
-import de.rki.coronawarnapp.util.di.AppInjector
-import de.rki.coronawarnapp.util.errors.RecoveryByResetDialogFactory
-import de.rki.coronawarnapp.util.ui.viewBindingLazy
-import kotlinx.coroutines.Dispatchers
-import kotlinx.coroutines.launch
-import kotlinx.coroutines.withContext
-
-/**
- * After the user has finished the onboarding this fragment will be the heart of the application.
- * Three ViewModels are needed that this fragment shows all relevant information to the user.
- * Also the Menu is set here.
- *
- * @see tracingViewModel
- * @see settingsViewModel
- * @see submissionViewModel
- * @see PopupMenu
- */
-class MainFragment : Fragment(R.layout.fragment_main) {
-
-    private val tracingViewModel: TracingViewModel by activityViewModels()
-    private val settingsViewModel: SettingsViewModel by activityViewModels()
-    private val submissionViewModel: SubmissionViewModel by activityViewModels()
-    private val binding: FragmentMainBinding by viewBindingLazy()
-
-    private val errorResetTool by lazy {
-        AppInjector.component.errorResetTool
-    }
-
-    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
-        super.onViewCreated(view, savedInstanceState)
-        binding.tracingViewModel = tracingViewModel
-        binding.settingsViewModel = settingsViewModel
-        binding.submissionViewModel = submissionViewModel
-
-        setButtonOnClickListener()
-        setContentDescription()
-        checkShouldInteroperabilityBeOpened()
-        showOneTimeTracingExplanationDialog()
-    }
-
-    override fun onActivityCreated(savedInstanceState: Bundle?) {
-        super.onActivityCreated(savedInstanceState)
-
-        if (errorResetTool.isResetNoticeToBeShown) {
-            RecoveryByResetDialogFactory(this).showDialog(
-                detailsLink = R.string.errors_generic_text_catastrophic_error_encryption_failure,
-                onDismiss = {
-                    errorResetTool.isResetNoticeToBeShown = false
-                }
-            )
-        }
-    }
-
-    override fun onResume() {
-        super.onResume()
-        // refresh required data
-        tracingViewModel.refreshRiskLevel()
-        tracingViewModel.refreshExposureSummary()
-        tracingViewModel.refreshLastTimeDiagnosisKeysFetchedDate()
-        tracingViewModel.refreshIsTracingEnabled()
-        tracingViewModel.refreshActiveTracingDaysInRetentionPeriod()
-        TimerHelper.checkManualKeyRetrievalTimer()
-        submissionViewModel.refreshDeviceUIState()
-        tracingViewModel.refreshLastSuccessfullyCalculatedScore()
-        binding.mainScrollview.sendAccessibilityEvent(AccessibilityEvent.TYPE_ANNOUNCEMENT)
-    }
-
-    private fun setContentDescription() {
-        binding.mainHeaderShare.buttonIcon.contentDescription = getString(R.string.button_share)
-        binding.mainHeaderOptionsMenu.buttonIcon.contentDescription =
-            getString(R.string.button_menu)
-        binding.mainAbout.mainCard.contentDescription = getString(R.string.hint_external_webpage)
-    }
-
-    private fun setButtonOnClickListener() {
-        binding.mainTestUnregistered.submissionStatusCardUnregistered.setOnClickListener {
-            toSubmissionIntro()
-        }
-        binding.mainTestUnregistered.submissionStatusCardUnregisteredButton.setOnClickListener {
-            toSubmissionIntro()
-        }
-        binding.mainTestDone.submissionStatusCardDone.setOnClickListener {
-            findNavController().doNavigate(
-                MainFragmentDirections.actionMainFragmentToSubmissionDoneFragment()
-            )
-        }
-        binding.mainTestResult.submissionStatusCardContent.setOnClickListener {
-            toSubmissionResult()
-        }
-        binding.mainTestResult.submissionStatusCardContentButton.setOnClickListener {
-            toSubmissionResult()
-        }
-        binding.mainTestPositive.submissionStatusCardPositive.setOnClickListener {
-            toSubmissionResult()
-        }
-        binding.mainTestPositive.submissionStatusCardPositiveButton.setOnClickListener {
-            toSubmissionResult()
-        }
-        binding.mainTracing.setOnClickListener {
-            findNavController().doNavigate(MainFragmentDirections.actionMainFragmentToSettingsTracingFragment())
-        }
-        binding.mainRisk.riskCard.setOnClickListener {
-            findNavController().doNavigate(MainFragmentDirections.actionMainFragmentToRiskDetailsFragment())
-        }
-        binding.mainRisk.riskCardButtonUpdate.setOnClickListener {
-            tracingViewModel.refreshDiagnosisKeys()
-            settingsViewModel.updateManualKeyRetrievalEnabled(false)
-        }
-        binding.mainRisk.riskCardButtonEnableTracing.setOnClickListener {
-            findNavController().doNavigate(MainFragmentDirections.actionMainFragmentToSettingsTracingFragment())
-        }
-        binding.mainAbout.mainCard.setOnClickListener {
-            ExternalActionHelper.openUrl(this, requireContext().getString(R.string.main_about_link))
-        }
-        binding.mainHeaderShare.buttonIcon.setOnClickListener {
-            findNavController().doNavigate(MainFragmentDirections.actionMainFragmentToMainSharingFragment())
-        }
-        binding.mainHeaderOptionsMenu.buttonIcon.setOnClickListener {
-            showPopup(it)
-        }
-    }
-
-    private fun toSubmissionResult() {
-        findNavController().doNavigate(
-            MainFragmentDirections.actionMainFragmentToSubmissionResultFragment()
-        )
-    }
-
-    private fun toSubmissionIntro() {
-        findNavController().doNavigate(
-            MainFragmentDirections.actionMainFragmentToSubmissionIntroFragment()
-        )
-    }
-
-    private fun showPopup(view: View) = PopupMenu(requireContext(), view).apply {
-        inflate(R.menu.menu_main)
-        menu.findItem(R.id.menu_test).isVisible = CWADebug.isDeviceForTestersBuild
-        setOnMenuItemClickListener {
-            return@setOnMenuItemClickListener when (it.itemId) {
-                R.id.menu_help -> {
-                    findNavController().doNavigate(MainFragmentDirections.actionMainFragmentToMainOverviewFragment())
-                    true
-                }
-                R.id.menu_information -> {
-                    findNavController().doNavigate(MainFragmentDirections.actionMainFragmentToInformationFragment())
-                    true
-                }
-                R.id.menu_settings -> {
-                    findNavController().doNavigate(MainFragmentDirections.actionMainFragmentToSettingsFragment())
-                    true
-                }
-                R.id.menu_test -> {
-                    findNavController().doNavigate(MainFragmentDirections.actionMainFragmentToTestNavGraph())
-                    true
-                }
-                else -> super.onOptionsItemSelected(it)
-            }
-        }
-    }.show()
-
-    private fun checkShouldInteroperabilityBeOpened() {
-        if (!LocalData.isInteroperabilityShownAtLeastOnce) {
-            navigateToInteroperabilityFeature()
-        }
-    }
-
-    private fun navigateToInteroperabilityFeature() {
-        findNavController().doNavigate(
-            MainFragmentDirections.actionMainFragmentToOnboardingDeltaInteroperabilityFragment()
-        )
-    }
-
-    private fun showOneTimeTracingExplanationDialog() {
-
-        // check if the dialog explaining the tracing time was already shown
-        if (!LocalData.tracingExplanationDialogWasShown()) {
-
-            val activity = this.requireActivity()
-
-            lifecycleScope.launch {
-
-                // get all text strings and the current active tracing time
-                val infoPeriodLogged =
-                    getString(R.string.risk_details_information_body_period_logged)
-                val infoPeriodLoggedAssessment =
-                    getString(
-                        R.string.risk_details_information_body_period_logged_assessment,
-                        (TimeVariables.getActiveTracingDaysInRetentionPeriod()).toString()
-                    )
-                val infoFAQ = getString(R.string.risk_details_explanation_dialog_faq_body)
-
-                withContext(Dispatchers.Main) {
-
-                    // display the dialog
-                    DialogHelper.showDialog(
-                        DialogHelper.DialogInstance(
-                            activity,
-                            getString(R.string.risk_details_explanation_dialog_title),
-                            "$infoPeriodLogged\n\n$infoPeriodLoggedAssessment\n\n$infoFAQ",
-                            getString(R.string.errors_generic_button_positive),
-                            null,
-                            null,
-                            {
-                                LocalData.tracingExplanationDialogWasShown(true)
-                            },
-                            {}
-                        ))
-                }
-            }
-        }
-    }
-}
diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/main/home/HomeFragment.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/main/home/HomeFragment.kt
new file mode 100644
index 0000000000000000000000000000000000000000..da0071854b4fa199c4154706871f5b1cc4937445
--- /dev/null
+++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/main/home/HomeFragment.kt
@@ -0,0 +1,142 @@
+package de.rki.coronawarnapp.ui.main.home
+
+import android.os.Bundle
+import android.view.View
+import android.view.accessibility.AccessibilityEvent
+import androidx.fragment.app.Fragment
+import de.rki.coronawarnapp.R
+import de.rki.coronawarnapp.databinding.FragmentHomeBinding
+import de.rki.coronawarnapp.util.ExternalActionHelper
+import de.rki.coronawarnapp.util.di.AutoInject
+import de.rki.coronawarnapp.util.errors.RecoveryByResetDialogFactory
+import de.rki.coronawarnapp.util.ui.doNavigate
+import de.rki.coronawarnapp.util.ui.observe2
+import de.rki.coronawarnapp.util.ui.viewBindingLazy
+import de.rki.coronawarnapp.util.viewmodel.CWAViewModelFactoryProvider
+import de.rki.coronawarnapp.util.viewmodel.cwaViewModels
+import javax.inject.Inject
+
+/**
+ * After the user has finished the onboarding this fragment will be the heart of the application.
+ * Three ViewModels are needed that this fragment shows all relevant information to the user.
+ * Also the Menu is set here.
+ */
+class HomeFragment : Fragment(R.layout.fragment_home), AutoInject {
+
+    @Inject lateinit var viewModelFactory: CWAViewModelFactoryProvider.Factory
+    private val vm: HomeFragmentViewModel by cwaViewModels { viewModelFactory }
+
+    private val binding: FragmentHomeBinding by viewBindingLazy()
+
+    @Inject lateinit var homeMenu: HomeMenu
+    @Inject lateinit var tracingExplanationDialog: TracingExplanationDialog
+
+    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
+        super.onViewCreated(view, savedInstanceState)
+
+        binding.tracingViewModel = vm.tracingViewModel
+        binding.settingsViewModel = vm.settingsViewModel
+        binding.submissionViewModel = vm.submissionViewModel
+
+        setupToolbar()
+
+        setupTestResultCard()
+
+        binding.mainTracing.setOnClickListener {
+            doNavigate(HomeFragmentDirections.actionMainFragmentToSettingsTracingFragment())
+        }
+
+        setupRiskCard()
+
+        binding.mainAbout.mainCard.apply {
+            setOnClickListener {
+                ExternalActionHelper.openUrl(this@HomeFragment, getString(R.string.main_about_link))
+            }
+            contentDescription = getString(R.string.hint_external_webpage)
+        }
+
+        vm.events.observe2(this) {
+            when (it) {
+                HomeFragmentEvents.ShowInteropDeltaOnboarding -> {
+                    doNavigate(
+                        HomeFragmentDirections.actionMainFragmentToOnboardingDeltaInteroperabilityFragment()
+                    )
+                }
+                is HomeFragmentEvents.ShowTracingExplanation -> {
+                    tracingExplanationDialog.show(it.activeTracingDaysInRetentionPeriod) {
+                        vm.tracingExplanationWasShown()
+                    }
+                }
+                HomeFragmentEvents.ShowErrorResetDialog -> {
+                    RecoveryByResetDialogFactory(this).showDialog(
+                        detailsLink = R.string.errors_generic_text_catastrophic_error_encryption_failure,
+                        onDismiss = { vm.errorResetDialogDismissed() }
+                    )
+                }
+            }
+        }
+    }
+
+    override fun onResume() {
+        super.onResume()
+        vm.refreshRequiredData()
+        binding.mainScrollview.sendAccessibilityEvent(AccessibilityEvent.TYPE_ANNOUNCEMENT)
+    }
+
+    private fun setupRiskCard() {
+        binding.mainRisk.apply {
+            riskCard.setOnClickListener {
+                doNavigate(HomeFragmentDirections.actionMainFragmentToRiskDetailsFragment())
+            }
+            riskCardButtonUpdate.setOnClickListener {
+                vm.tracingViewModel.refreshDiagnosisKeys()
+                vm.settingsViewModel.updateManualKeyRetrievalEnabled(false)
+            }
+            riskCardButtonEnableTracing.setOnClickListener {
+                doNavigate(HomeFragmentDirections.actionMainFragmentToSettingsTracingFragment())
+            }
+        }
+    }
+
+    private fun setupTestResultCard() {
+        binding.apply {
+            val toSubmissionResult = {
+                doNavigate(HomeFragmentDirections.actionMainFragmentToSubmissionResultFragment())
+            }
+            mainTestUnregistered.apply {
+                val toSubmissionIntro = {
+                    doNavigate(HomeFragmentDirections.actionMainFragmentToSubmissionIntroFragment())
+                }
+                submissionStatusCardUnregistered.setOnClickListener { toSubmissionIntro() }
+                submissionStatusCardUnregisteredButton.setOnClickListener { toSubmissionIntro() }
+            }
+
+            mainTestDone.submissionStatusCardDone.setOnClickListener {
+                doNavigate(HomeFragmentDirections.actionMainFragmentToSubmissionDoneFragment())
+            }
+            mainTestResult.apply {
+                submissionStatusCardContent.setOnClickListener { toSubmissionResult() }
+                submissionStatusCardContentButton.setOnClickListener { toSubmissionResult() }
+            }
+
+            mainTestPositive.apply {
+                submissionStatusCardPositive.setOnClickListener { toSubmissionResult() }
+                submissionStatusCardPositiveButton.setOnClickListener { toSubmissionResult() }
+            }
+        }
+    }
+
+    private fun setupToolbar() {
+        binding.mainHeaderShare.buttonIcon.apply {
+            contentDescription = getString(R.string.button_share)
+            setOnClickListener {
+                doNavigate(HomeFragmentDirections.actionMainFragmentToMainSharingFragment())
+            }
+        }
+
+        binding.mainHeaderOptionsMenu.buttonIcon.apply {
+            contentDescription = getString(R.string.button_menu)
+            setOnClickListener { homeMenu.showMenuFor(it) }
+        }
+    }
+}
diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/main/home/HomeFragmentEvents.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/main/home/HomeFragmentEvents.kt
new file mode 100644
index 0000000000000000000000000000000000000000..cb0ea79e38f8265a45527051ca36301c11a41ca2
--- /dev/null
+++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/main/home/HomeFragmentEvents.kt
@@ -0,0 +1,11 @@
+package de.rki.coronawarnapp.ui.main.home
+
+sealed class HomeFragmentEvents {
+    object ShowInteropDeltaOnboarding : HomeFragmentEvents()
+
+    data class ShowTracingExplanation(
+        val activeTracingDaysInRetentionPeriod: Long
+    ) : HomeFragmentEvents()
+
+    object ShowErrorResetDialog : HomeFragmentEvents()
+}
diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/main/home/HomeFragmentModule.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/main/home/HomeFragmentModule.kt
new file mode 100644
index 0000000000000000000000000000000000000000..0032c0aa4595242ea2616ba747f0b30354857d7b
--- /dev/null
+++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/main/home/HomeFragmentModule.kt
@@ -0,0 +1,22 @@
+package de.rki.coronawarnapp.ui.main.home
+
+import dagger.Binds
+import dagger.Module
+import dagger.android.ContributesAndroidInjector
+import dagger.multibindings.IntoMap
+import de.rki.coronawarnapp.util.viewmodel.CWAViewModel
+import de.rki.coronawarnapp.util.viewmodel.CWAViewModelFactory
+import de.rki.coronawarnapp.util.viewmodel.CWAViewModelKey
+
+@Module
+abstract class HomeFragmentModule {
+    @Binds
+    @IntoMap
+    @CWAViewModelKey(HomeFragmentViewModel::class)
+    abstract fun homeFragment(
+        factory: HomeFragmentViewModel.Factory
+    ): CWAViewModelFactory<out CWAViewModel>
+
+    @ContributesAndroidInjector
+    abstract fun homeScreen(): HomeFragment
+}
diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/main/home/HomeFragmentViewModel.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/main/home/HomeFragmentViewModel.kt
new file mode 100644
index 0000000000000000000000000000000000000000..fb2bdc4d2fe9fca6590edd1456120e5394a0d9cd
--- /dev/null
+++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/main/home/HomeFragmentViewModel.kt
@@ -0,0 +1,72 @@
+package de.rki.coronawarnapp.ui.main.home
+
+import com.squareup.inject.assisted.AssistedInject
+import de.rki.coronawarnapp.risk.TimeVariables
+import de.rki.coronawarnapp.storage.LocalData
+import de.rki.coronawarnapp.timer.TimerHelper
+import de.rki.coronawarnapp.ui.main.home.HomeFragmentEvents.ShowErrorResetDialog
+import de.rki.coronawarnapp.ui.main.home.HomeFragmentEvents.ShowInteropDeltaOnboarding
+import de.rki.coronawarnapp.ui.main.home.HomeFragmentEvents.ShowTracingExplanation
+import de.rki.coronawarnapp.ui.viewmodel.SettingsViewModel
+import de.rki.coronawarnapp.ui.viewmodel.SubmissionViewModel
+import de.rki.coronawarnapp.ui.viewmodel.TracingViewModel
+import de.rki.coronawarnapp.util.coroutine.DispatcherProvider
+import de.rki.coronawarnapp.util.security.EncryptionErrorResetTool
+import de.rki.coronawarnapp.util.ui.SingleLiveEvent
+import de.rki.coronawarnapp.util.viewmodel.CWAViewModel
+import de.rki.coronawarnapp.util.viewmodel.SimpleCWAViewModelFactory
+
+class HomeFragmentViewModel @AssistedInject constructor(
+    dispatcherProvider: DispatcherProvider,
+    private val errorResetTool: EncryptionErrorResetTool,
+    val tracingViewModel: TracingViewModel,
+    val settingsViewModel: SettingsViewModel,
+    val submissionViewModel: SubmissionViewModel
+) : CWAViewModel(
+    dispatcherProvider = dispatcherProvider,
+    childViewModels = listOf(tracingViewModel, settingsViewModel, submissionViewModel)
+) {
+
+    val events = SingleLiveEvent<HomeFragmentEvents>()
+
+    init {
+        if (!LocalData.isInteroperabilityShownAtLeastOnce) {
+            events.postValue(ShowInteropDeltaOnboarding)
+        } else {
+            launch {
+                if (!LocalData.tracingExplanationDialogWasShown()) {
+                    events.postValue(
+                        ShowTracingExplanation(TimeVariables.getActiveTracingDaysInRetentionPeriod())
+                    )
+                }
+            }
+            launch {
+                if (errorResetTool.isResetNoticeToBeShown) {
+                    events.postValue(ShowErrorResetDialog)
+                }
+            }
+        }
+    }
+
+    fun errorResetDialogDismissed() {
+        errorResetTool.isResetNoticeToBeShown = false
+    }
+
+    fun refreshRequiredData() {
+        tracingViewModel.refreshRiskLevel()
+        tracingViewModel.refreshExposureSummary()
+        tracingViewModel.refreshLastTimeDiagnosisKeysFetchedDate()
+        tracingViewModel.refreshIsTracingEnabled()
+        tracingViewModel.refreshActiveTracingDaysInRetentionPeriod()
+        TimerHelper.checkManualKeyRetrievalTimer()
+        submissionViewModel.refreshDeviceUIState()
+        tracingViewModel.refreshLastSuccessfullyCalculatedScore()
+    }
+
+    fun tracingExplanationWasShown() {
+        LocalData.tracingExplanationDialogWasShown(true)
+    }
+
+    @AssistedInject.Factory
+    interface Factory : SimpleCWAViewModelFactory<HomeFragmentViewModel>
+}
diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/main/home/HomeMenu.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/main/home/HomeMenu.kt
new file mode 100644
index 0000000000000000000000000000000000000000..a20df5ef40e06adb57d63d57fd50f113c2056dec
--- /dev/null
+++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/main/home/HomeMenu.kt
@@ -0,0 +1,46 @@
+package de.rki.coronawarnapp.ui.main.home
+
+import android.content.Context
+import android.view.View
+import android.widget.PopupMenu
+import androidx.navigation.NavController
+import androidx.navigation.fragment.findNavController
+import de.rki.coronawarnapp.R
+import de.rki.coronawarnapp.ui.doNavigate
+import de.rki.coronawarnapp.util.CWADebug
+import javax.inject.Inject
+
+class HomeMenu @Inject constructor(
+    private val homeFragment: HomeFragment
+) {
+    private val context: Context = homeFragment.requireContext()
+
+    private val navController: NavController
+        get() = homeFragment.findNavController()
+
+    fun showMenuFor(view: View) = PopupMenu(context, view).apply {
+        inflate(R.menu.menu_main)
+        menu.findItem(R.id.menu_test).isVisible = CWADebug.isDeviceForTestersBuild
+        setOnMenuItemClickListener {
+            return@setOnMenuItemClickListener when (it.itemId) {
+                R.id.menu_help -> {
+                    navController.doNavigate(HomeFragmentDirections.actionMainFragmentToMainOverviewFragment())
+                    true
+                }
+                R.id.menu_information -> {
+                    navController.doNavigate(HomeFragmentDirections.actionMainFragmentToInformationFragment())
+                    true
+                }
+                R.id.menu_settings -> {
+                    navController.doNavigate(HomeFragmentDirections.actionMainFragmentToSettingsFragment())
+                    true
+                }
+                R.id.menu_test -> {
+                    navController.doNavigate(HomeFragmentDirections.actionMainFragmentToTestNavGraph())
+                    true
+                }
+                else -> homeFragment.onOptionsItemSelected(it)
+            }
+        }
+    }.show()
+}
diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/main/home/TracingExplanationDialog.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/main/home/TracingExplanationDialog.kt
new file mode 100644
index 0000000000000000000000000000000000000000..a9bdd4dac3dca7cec92de55a1a6c8172cef2b9b5
--- /dev/null
+++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/main/home/TracingExplanationDialog.kt
@@ -0,0 +1,37 @@
+package de.rki.coronawarnapp.ui.main.home
+
+import android.content.Context
+import de.rki.coronawarnapp.R
+import de.rki.coronawarnapp.util.DialogHelper
+import javax.inject.Inject
+
+class TracingExplanationDialog @Inject constructor(
+    private val homeFragment: HomeFragment
+) {
+    private val context: Context
+        get() = homeFragment.requireContext()
+
+    fun show(activeTracingDaysInRetentionPeriod: Long, onPositive: () -> Unit) {
+        // get all text strings and the current active tracing time
+        val infoPeriodLogged =
+            context.getString(R.string.risk_details_information_body_period_logged)
+        val infoPeriodLoggedAssessment =
+            context.getString(
+                R.string.risk_details_information_body_period_logged_assessment,
+                activeTracingDaysInRetentionPeriod.toString()
+            )
+        val infoFAQ = context.getString(R.string.risk_details_explanation_dialog_faq_body)
+
+        val data = DialogHelper.DialogInstance(
+            context = context,
+            title = context.getString(R.string.risk_details_explanation_dialog_title),
+            message = "$infoPeriodLogged\n\n$infoPeriodLoggedAssessment\n\n$infoFAQ",
+            positiveButton = context.getString(R.string.errors_generic_button_positive),
+            negativeButton = null,
+            cancelable = null,
+            positiveButtonFunction = onPositive,
+            negativeButtonFunction = {}
+        )
+        DialogHelper.showDialog(data)
+    }
+}
diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/main/MainOverviewFragment.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/main/overview/MainOverviewFragment.kt
similarity index 92%
rename from Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/main/MainOverviewFragment.kt
rename to Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/main/overview/MainOverviewFragment.kt
index c99a5dba307a8486871d86d3fd8929817ed8fb26..0a4dce381da1918101babbfd72f70007bb19af3e 100644
--- a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/main/MainOverviewFragment.kt
+++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/main/overview/MainOverviewFragment.kt
@@ -1,4 +1,4 @@
-package de.rki.coronawarnapp.ui.main
+package de.rki.coronawarnapp.ui.main.overview
 
 import android.os.Bundle
 import android.view.View
@@ -6,6 +6,7 @@ import android.view.accessibility.AccessibilityEvent
 import androidx.fragment.app.Fragment
 import de.rki.coronawarnapp.R
 import de.rki.coronawarnapp.databinding.FragmentMainOverviewBinding
+import de.rki.coronawarnapp.ui.main.MainActivity
 import de.rki.coronawarnapp.util.ui.viewBindingLazy
 
 /**
diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/main/MainShareFragment.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/main/share/MainShareFragment.kt
similarity index 94%
rename from Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/main/MainShareFragment.kt
rename to Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/main/share/MainShareFragment.kt
index a82e0c320d3edbd0dd6bc5dae69918206681f5c4..6616b55c86c2f059ead270b8c19e3cffa3c2eca9 100644
--- a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/main/MainShareFragment.kt
+++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/main/share/MainShareFragment.kt
@@ -1,4 +1,4 @@
-package de.rki.coronawarnapp.ui.main
+package de.rki.coronawarnapp.ui.main.share
 
 import android.os.Bundle
 import android.view.View
@@ -7,6 +7,7 @@ import androidx.fragment.app.Fragment
 import androidx.fragment.app.activityViewModels
 import de.rki.coronawarnapp.R
 import de.rki.coronawarnapp.databinding.FragmentMainShareBinding
+import de.rki.coronawarnapp.ui.main.MainActivity
 import de.rki.coronawarnapp.ui.viewmodel.TracingViewModel
 import de.rki.coronawarnapp.util.ExternalActionHelper
 import de.rki.coronawarnapp.util.ui.viewBindingLazy
diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/riskdetails/RiskDetailsFragment.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/riskdetails/RiskDetailsFragment.kt
index b3846cbb98c8f33c0c9619151881a6f599fbade5..0d53843a0622365b6e41558f39120a746e460f58 100644
--- a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/riskdetails/RiskDetailsFragment.kt
+++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/riskdetails/RiskDetailsFragment.kt
@@ -4,17 +4,19 @@ import android.os.Bundle
 import android.view.View
 import android.view.accessibility.AccessibilityEvent
 import androidx.fragment.app.Fragment
-import androidx.fragment.app.activityViewModels
 import androidx.navigation.fragment.findNavController
 import de.rki.coronawarnapp.R
 import de.rki.coronawarnapp.databinding.FragmentRiskDetailsBinding
-import de.rki.coronawarnapp.timer.TimerHelper
 import de.rki.coronawarnapp.ui.doNavigate
 import de.rki.coronawarnapp.ui.main.MainActivity
 import de.rki.coronawarnapp.ui.viewmodel.SettingsViewModel
 import de.rki.coronawarnapp.ui.viewmodel.TracingViewModel
-import de.rki.coronawarnapp.util.ui.viewBindingLazy
 import de.rki.coronawarnapp.util.convertToHyperlink
+import de.rki.coronawarnapp.util.di.AutoInject
+import de.rki.coronawarnapp.util.ui.viewBindingLazy
+import de.rki.coronawarnapp.util.viewmodel.CWAViewModelFactoryProvider
+import de.rki.coronawarnapp.util.viewmodel.cwaViewModels
+import javax.inject.Inject
 
 /**
  * This is the detail view of the risk card if additional information for the user.
@@ -22,51 +24,37 @@ import de.rki.coronawarnapp.util.convertToHyperlink
  * @see TracingViewModel
  * @see SettingsViewModel
  */
-class RiskDetailsFragment : Fragment(R.layout.fragment_risk_details) {
+class RiskDetailsFragment : Fragment(R.layout.fragment_risk_details), AutoInject {
+
+    @Inject lateinit var viewModelFactory: CWAViewModelFactoryProvider.Factory
+    private val vm: RiskDetailsFragmentViewModel by cwaViewModels { viewModelFactory }
 
-    private val tracingViewModel: TracingViewModel by activityViewModels()
-    private val settingsViewModel: SettingsViewModel by activityViewModels()
     private val binding: FragmentRiskDetailsBinding by viewBindingLazy()
 
     override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
         super.onViewCreated(view, savedInstanceState)
-        binding.tracingViewModel = tracingViewModel
-        binding.settingsViewModel = settingsViewModel
-        setButtonOnClickListeners()
-        setUpWebLinks()
-    }
+        binding.tracingViewModel = vm.tracingViewModel
+        binding.settingsViewModel = vm.settingsViewModel
 
-    override fun onResume() {
-        super.onResume()
-        // refresh required data
-        tracingViewModel.refreshRiskLevel()
-        tracingViewModel.refreshExposureSummary()
-        tracingViewModel.refreshLastTimeDiagnosisKeysFetchedDate()
-        TimerHelper.checkManualKeyRetrievalTimer()
-        tracingViewModel.refreshActiveTracingDaysInRetentionPeriod()
-        binding.riskDetailsContainer.sendAccessibilityEvent(AccessibilityEvent.TYPE_ANNOUNCEMENT)
-    }
-
-    /**
-     * Make the links clickable and convert to hyperlink
-     */
-    private fun setUpWebLinks() {
-        binding.riskDetailsInformationLowriskBodyUrl
-            .convertToHyperlink(getString(R.string.risk_details_explanation_faq_body_with_link))
-    }
-
-    private fun setButtonOnClickListeners() {
         binding.riskDetailsHeaderButtonBack.setOnClickListener {
             (activity as MainActivity).goBack()
         }
         binding.riskDetailsButtonUpdate.setOnClickListener {
-            tracingViewModel.refreshDiagnosisKeys()
-            settingsViewModel.updateManualKeyRetrievalEnabled(false)
+            vm.updateRiskDetails()
         }
         binding.riskDetailsButtonEnableTracing.setOnClickListener {
             findNavController().doNavigate(
                 RiskDetailsFragmentDirections.actionRiskDetailsFragmentToSettingsTracingFragment()
             )
         }
+
+        binding.riskDetailsInformationLowriskBodyUrl
+            .convertToHyperlink(getString(R.string.risk_details_explanation_faq_body_with_link))
+    }
+
+    override fun onResume() {
+        super.onResume()
+        vm.refreshData()
+        binding.riskDetailsContainer.sendAccessibilityEvent(AccessibilityEvent.TYPE_ANNOUNCEMENT)
     }
 }
diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/riskdetails/RiskDetailsFragmentModule.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/riskdetails/RiskDetailsFragmentModule.kt
new file mode 100644
index 0000000000000000000000000000000000000000..1cf96b5c4ebb6f82c3806cd0f5d28b1d124656d4
--- /dev/null
+++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/riskdetails/RiskDetailsFragmentModule.kt
@@ -0,0 +1,22 @@
+package de.rki.coronawarnapp.ui.riskdetails
+
+import dagger.Binds
+import dagger.Module
+import dagger.android.ContributesAndroidInjector
+import dagger.multibindings.IntoMap
+import de.rki.coronawarnapp.util.viewmodel.CWAViewModel
+import de.rki.coronawarnapp.util.viewmodel.CWAViewModelFactory
+import de.rki.coronawarnapp.util.viewmodel.CWAViewModelKey
+
+@Module
+abstract class RiskDetailsFragmentModule {
+    @Binds
+    @IntoMap
+    @CWAViewModelKey(RiskDetailsFragmentViewModel::class)
+    abstract fun homeFragment(
+        factory: RiskDetailsFragmentViewModel.Factory
+    ): CWAViewModelFactory<out CWAViewModel>
+
+    @ContributesAndroidInjector
+    abstract fun riskDetails(): RiskDetailsFragment
+}
diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/riskdetails/RiskDetailsFragmentViewModel.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/riskdetails/RiskDetailsFragmentViewModel.kt
new file mode 100644
index 0000000000000000000000000000000000000000..cfe5ccd3f50042a40e5416cb055ed96f26ba1f18
--- /dev/null
+++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/riskdetails/RiskDetailsFragmentViewModel.kt
@@ -0,0 +1,35 @@
+package de.rki.coronawarnapp.ui.riskdetails
+
+import com.squareup.inject.assisted.AssistedInject
+import de.rki.coronawarnapp.timer.TimerHelper
+import de.rki.coronawarnapp.ui.viewmodel.SettingsViewModel
+import de.rki.coronawarnapp.ui.viewmodel.TracingViewModel
+import de.rki.coronawarnapp.util.coroutine.DispatcherProvider
+import de.rki.coronawarnapp.util.viewmodel.CWAViewModel
+import de.rki.coronawarnapp.util.viewmodel.SimpleCWAViewModelFactory
+
+class RiskDetailsFragmentViewModel @AssistedInject constructor(
+    dispatcherProvider: DispatcherProvider,
+    val tracingViewModel: TracingViewModel,
+    val settingsViewModel: SettingsViewModel
+) : CWAViewModel(
+    dispatcherProvider = dispatcherProvider,
+    childViewModels = listOf(tracingViewModel, settingsViewModel)
+) {
+
+    fun refreshData() {
+        tracingViewModel.refreshRiskLevel()
+        tracingViewModel.refreshExposureSummary()
+        tracingViewModel.refreshLastTimeDiagnosisKeysFetchedDate()
+        TimerHelper.checkManualKeyRetrievalTimer()
+        tracingViewModel.refreshActiveTracingDaysInRetentionPeriod()
+    }
+
+    fun updateRiskDetails() {
+        tracingViewModel.refreshDiagnosisKeys()
+        settingsViewModel.updateManualKeyRetrievalEnabled(false)
+    }
+
+    @AssistedInject.Factory
+    interface Factory : SimpleCWAViewModelFactory<RiskDetailsFragmentViewModel>
+}
diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/settings/SettingsTracingFragment.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/settings/SettingsTracingFragment.kt
index 7f496e7d23977b22ce93e18b1feecdfa7b676150..e253216328af7d547847384257151d3b07fb780d 100644
--- a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/settings/SettingsTracingFragment.kt
+++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/settings/SettingsTracingFragment.kt
@@ -22,7 +22,6 @@ import de.rki.coronawarnapp.ui.viewmodel.TracingViewModel
 import de.rki.coronawarnapp.util.DialogHelper
 import de.rki.coronawarnapp.util.ExternalActionHelper
 import de.rki.coronawarnapp.util.formatter.formatTracingSwitchEnabled
-import de.rki.coronawarnapp.util.ui.observe2
 import de.rki.coronawarnapp.util.ui.viewBindingLazy
 import de.rki.coronawarnapp.worker.BackgroundWorkScheduler
 import kotlinx.coroutines.launch
@@ -53,12 +52,6 @@ class SettingsTracingFragment : Fragment(R.layout.fragment_settings_tracing),
         binding.tracingViewModel = tracingViewModel
         binding.settingsViewModel = settingsViewModel
 
-        tracingViewModel.navigateToInteroperability.observe2(this) {
-            if (it) {
-                navigateToInteroperability()
-            }
-        }
-
         setButtonOnClickListener()
     }
 
@@ -130,7 +123,7 @@ class SettingsTracingFragment : Fragment(R.layout.fragment_settings_tracing),
             ExternalActionHelper.toMainSettings(requireContext())
         }
         interoperability.setOnClickListener {
-            tracingViewModel.onInteroperabilitySettingPressed()
+            navigateToInteroperability()
         }
     }
 
diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/viewmodel/SettingsViewModel.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/viewmodel/SettingsViewModel.kt
index fa6bde7ffd0c4200c7799a8d23b45f2dd0321fd8..2f9880069718f6b382995476edd623c0122a27d7 100644
--- a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/viewmodel/SettingsViewModel.kt
+++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/viewmodel/SettingsViewModel.kt
@@ -1,16 +1,17 @@
 package de.rki.coronawarnapp.ui.viewmodel
 
 import androidx.lifecycle.LiveData
-import androidx.lifecycle.ViewModel
 import de.rki.coronawarnapp.storage.SettingsRepository
 import de.rki.coronawarnapp.util.di.AppInjector
+import de.rki.coronawarnapp.util.viewmodel.CWAViewModel
+import javax.inject.Inject
 
 /**
  * ViewModel for everything settings related.
  *
  * @see SettingsRepository
  */
-class SettingsViewModel : ViewModel() {
+class SettingsViewModel @Inject constructor() : CWAViewModel() {
 
     private val settingsRepository by lazy {
         AppInjector.component.settingsRepository
diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/viewmodel/SubmissionViewModel.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/viewmodel/SubmissionViewModel.kt
index 5f2c6cbdaa6a8bde5fc4b1fbba7b8e0766eccde5..0d985fe357c6a88a9b95f224692ba5e962e30e3f 100644
--- a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/viewmodel/SubmissionViewModel.kt
+++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/viewmodel/SubmissionViewModel.kt
@@ -2,7 +2,6 @@ package de.rki.coronawarnapp.ui.viewmodel
 
 import androidx.lifecycle.LiveData
 import androidx.lifecycle.MutableLiveData
-import androidx.lifecycle.ViewModel
 import androidx.lifecycle.viewModelScope
 import com.google.android.gms.nearby.exposurenotification.TemporaryExposureKey
 import de.rki.coronawarnapp.exception.ExceptionCategory
@@ -23,12 +22,14 @@ import de.rki.coronawarnapp.ui.submission.SymptomIntroductionEvent
 import de.rki.coronawarnapp.util.DeviceUIState
 import de.rki.coronawarnapp.util.Event
 import de.rki.coronawarnapp.util.di.AppInjector
+import de.rki.coronawarnapp.util.viewmodel.CWAViewModel
 import kotlinx.coroutines.launch
 import org.joda.time.LocalDate
 import timber.log.Timber
 import java.util.Date
+import javax.inject.Inject
 
-class SubmissionViewModel : ViewModel() {
+class SubmissionViewModel @Inject constructor() : CWAViewModel() {
     private val _scanStatus = MutableLiveData(Event(ScanStatus.STARTED))
 
     private val _registrationState = MutableLiveData(Event(ApiRequestState.IDLE))
diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/viewmodel/TracingViewModel.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/viewmodel/TracingViewModel.kt
index 06e3b51238b1d34940eb2c3dbdb8b8253c12ea01..8e347e23431bba7548ab2b72e7aa953e8c22ab53 100644
--- a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/viewmodel/TracingViewModel.kt
+++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/viewmodel/TracingViewModel.kt
@@ -3,7 +3,6 @@ package de.rki.coronawarnapp.ui.viewmodel
 import android.view.View
 import androidx.lifecycle.LiveData
 import androidx.lifecycle.MediatorLiveData
-import androidx.lifecycle.ViewModel
 import androidx.lifecycle.viewModelScope
 import de.rki.coronawarnapp.CoronaWarnApplication
 import de.rki.coronawarnapp.exception.ExceptionCategory.INTERNAL
@@ -19,13 +18,14 @@ import de.rki.coronawarnapp.transaction.RetrieveDiagnosisKeysTransaction
 import de.rki.coronawarnapp.transaction.RiskLevelTransaction
 import de.rki.coronawarnapp.ui.riskdetails.DefaultRiskDetailPresenter
 import de.rki.coronawarnapp.util.ConnectivityHelper
-import de.rki.coronawarnapp.util.ui.SingleLiveEvent
+import de.rki.coronawarnapp.util.viewmodel.CWAViewModel
 import kotlinx.coroutines.launch
 import org.joda.time.DateTime
 import org.joda.time.DateTimeZone
 import org.joda.time.Instant
 import timber.log.Timber
 import java.util.Date
+import javax.inject.Inject
 
 /**
  * Provides all the relevant data for tracing relevant topics and settings.
@@ -36,7 +36,7 @@ import java.util.Date
  * @see TracingRepository
  * @see RiskLevelRepository
  */
-class TracingViewModel : ViewModel() {
+class TracingViewModel @Inject constructor() : CWAViewModel() {
 
     companion object {
         val TAG: String? = TracingViewModel::class.simpleName
@@ -63,9 +63,6 @@ class TracingViewModel : ViewModel() {
     val additionalInformationVisibility = MediatorLiveData<Int>()
     val informationBodyNoticeVisibility = MediatorLiveData<Int>()
 
-    // event for interoperability navigation
-    val navigateToInteroperability = SingleLiveEvent<Boolean>()
-
     init {
         additionalInformationVisibility.addSource(riskLevel) {
             additionalInformationVisibility.value =
@@ -244,8 +241,4 @@ class TracingViewModel : ViewModel() {
     fun refreshLastSuccessfullyCalculatedScore() {
         RiskLevelRepository.refreshLastSuccessfullyCalculatedScore()
     }
-
-    fun onInteroperabilitySettingPressed() {
-        navigateToInteroperability.postValue(true)
-    }
 }
diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/util/DialogHelper.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/util/DialogHelper.kt
index fb3171270995a2804054da8b0a96a7d5743731b0..e7a295a1643aea654def25d0a152bc62bbbf12eb 100644
--- a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/util/DialogHelper.kt
+++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/util/DialogHelper.kt
@@ -1,6 +1,6 @@
 package de.rki.coronawarnapp.util
 
-import android.app.Activity
+import android.content.Context
 import android.text.SpannableString
 import android.text.method.LinkMovementMethod
 import android.text.util.Linkify
@@ -12,7 +12,7 @@ import java.util.regex.Pattern
 object DialogHelper {
 
     data class DialogInstance(
-        val activity: Activity,
+        val context: Context,
         val title: String,
         val message: String?,
         val positiveButton: String,
@@ -22,7 +22,7 @@ object DialogHelper {
         val negativeButtonFunction: () -> Unit? = {}
     ) {
         constructor(
-            activity: Activity,
+            context: Context,
             title: Int,
             message: Int,
             positiveButton: Int,
@@ -31,18 +31,18 @@ object DialogHelper {
             positiveButtonFunction: () -> Unit? = {},
             negativeButtonFunction: () -> Unit? = {}
         ) : this(
-            activity,
-            activity.resources.getString(title),
-            activity.resources.getString(message),
-            activity.resources.getString(positiveButton),
-            negativeButton?.let { activity.resources.getString(it) },
+            context,
+            context.resources.getString(title),
+            context.resources.getString(message),
+            context.resources.getString(positiveButton),
+            negativeButton?.let { context.resources.getString(it) },
             cancelable,
             positiveButtonFunction,
             negativeButtonFunction
         )
 
         constructor(
-            activity: Activity,
+            context: Context,
             title: Int,
             message: String,
             positiveButton: Int,
@@ -51,11 +51,11 @@ object DialogHelper {
             positiveButtonFunction: () -> Unit? = {},
             negativeButtonFunction: () -> Unit? = {}
         ) : this(
-            activity,
-            activity.resources.getString(title),
+            context,
+            context.resources.getString(title),
             message,
-            activity.resources.getString(positiveButton),
-            negativeButton?.let { activity.resources.getString(it) },
+            context.resources.getString(positiveButton),
+            negativeButton?.let { context.resources.getString(it) },
             cancelable,
             positiveButtonFunction,
             negativeButtonFunction
@@ -65,8 +65,8 @@ object DialogHelper {
     fun showDialog(
         dialogInstance: DialogInstance
     ): AlertDialog {
-        val message = getMessage(dialogInstance.activity, dialogInstance.message)
-        val alertDialog: AlertDialog = dialogInstance.activity.let {
+        val message = getMessage(dialogInstance.context, dialogInstance.message)
+        val alertDialog: AlertDialog = dialogInstance.context.let {
             val builder = AlertDialog.Builder(it)
             builder.apply {
                 setTitle(dialogInstance.title)
@@ -91,22 +91,22 @@ object DialogHelper {
         return alertDialog
     }
 
-    private fun getMessage(activity: Activity, message: String?): TextView {
+    private fun getMessage(context: Context, message: String?): TextView {
         // create spannable and add links, removed stack trace links into nowhere
         val spannable = SpannableString(message)
         val httpPattern: Pattern = Pattern.compile("[a-z]+://[^ \\n]*")
         Linkify.addLinks(spannable, httpPattern, "")
         // get padding for all sides
-        val paddingStartEnd = activity.resources.getDimension(R.dimen.spacing_normal).toInt()
-        val paddingLeftRight = activity.resources.getDimension(R.dimen.spacing_small).toInt()
+        val paddingStartEnd = context.resources.getDimension(R.dimen.spacing_normal).toInt()
+        val paddingLeftRight = context.resources.getDimension(R.dimen.spacing_small).toInt()
         // create a textview with clickable links from the spannable
-        val textView = TextView(activity)
+        val textView = TextView(context)
         textView.text = spannable
         textView.linksClickable = true
         textView.movementMethod = LinkMovementMethod.getInstance()
         textView.setPadding(paddingStartEnd, paddingLeftRight, paddingStartEnd, paddingLeftRight)
         textView.setTextAppearance(R.style.body1)
-        textView.setLinkTextColor(activity.getColorStateList(R.color.button_primary))
+        textView.setLinkTextColor(context.getColorStateList(R.color.button_primary))
         return textView
     }
 }
diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/util/WatchdogService.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/util/WatchdogService.kt
index d2e5aa97c9fc787f2874d65145e9c203a8457d9b..93ad141a6257c0f04084b90cae08a3463761fcd6 100644
--- a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/util/WatchdogService.kt
+++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/util/WatchdogService.kt
@@ -7,6 +7,7 @@ import androidx.lifecycle.ProcessLifecycleOwner
 import androidx.lifecycle.lifecycleScope
 import de.rki.coronawarnapp.storage.LocalData
 import de.rki.coronawarnapp.transaction.RetrieveDiagnosisKeysTransaction
+import de.rki.coronawarnapp.util.di.AppContext
 import de.rki.coronawarnapp.worker.BackgroundWorkHelper
 import de.rki.coronawarnapp.worker.BackgroundWorkScheduler
 import kotlinx.coroutines.launch
@@ -16,7 +17,9 @@ import javax.inject.Inject
 import javax.inject.Singleton
 
 @Singleton
-class WatchdogService @Inject constructor(private val context: Context) {
+class WatchdogService @Inject constructor(
+    @AppContext private val context: Context
+) {
 
     private val powerManager by lazy {
         context.getSystemService(Context.POWER_SERVICE) as PowerManager
diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/util/device/DefaultPowerManagement.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/util/device/DefaultPowerManagement.kt
index 12475b33358693e19786dc76b8099e245c7d8f64..9cdd2143af1fa3f7b3a4bb617da4d0c1a9d99af5 100644
--- a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/util/device/DefaultPowerManagement.kt
+++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/util/device/DefaultPowerManagement.kt
@@ -5,10 +5,11 @@ import android.content.Intent
 import android.net.Uri
 import android.os.PowerManager
 import android.provider.Settings
+import de.rki.coronawarnapp.util.di.AppContext
 import javax.inject.Inject
 
 class DefaultPowerManagement @Inject constructor(
-    private val context: Context
+    @AppContext private val context: Context
 ) : PowerManagement {
 
     private val powerManager by lazy {
diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/util/di/AndroidModule.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/util/di/AndroidModule.kt
index 15b4f6a3962f4e95b126bf2eb92a07ff3b3a263d..b5e1e3a248f2fa0c629b7c44c4865bc4cb4327ca 100644
--- a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/util/di/AndroidModule.kt
+++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/util/di/AndroidModule.kt
@@ -16,5 +16,6 @@ class AndroidModule {
 
     @Provides
     @Singleton
+    @AppContext
     fun context(app: Application): Context = app.applicationContext
 }
diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/util/di/AppContext.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/util/di/AppContext.kt
new file mode 100644
index 0000000000000000000000000000000000000000..62a9e570ed2d5746ccb009ce18e19aa63155de70
--- /dev/null
+++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/util/di/AppContext.kt
@@ -0,0 +1,8 @@
+package de.rki.coronawarnapp.util.di
+
+import javax.inject.Qualifier
+
+@Qualifier
+@MustBeDocumented
+@Retention(AnnotationRetention.RUNTIME)
+annotation class AppContext
diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/util/security/EncryptedPreferencesFactory.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/util/security/EncryptedPreferencesFactory.kt
index 34bd1d355880e860bc2c6ce525ffe0d26f62e75b..a352abdb13f9430810b3b5e13f588b934e22b850 100644
--- a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/util/security/EncryptedPreferencesFactory.kt
+++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/util/security/EncryptedPreferencesFactory.kt
@@ -5,6 +5,7 @@ import android.content.SharedPreferences
 import androidx.security.crypto.EncryptedSharedPreferences
 import androidx.security.crypto.MasterKeys
 import de.rki.coronawarnapp.util.RetryMechanism
+import de.rki.coronawarnapp.util.di.AppContext
 import timber.log.Timber
 import java.security.KeyException
 import javax.inject.Inject
@@ -12,7 +13,7 @@ import javax.inject.Singleton
 
 @Singleton
 class EncryptedPreferencesFactory @Inject constructor(
-    private val context: Context
+    @AppContext private val context: Context
 ) {
 
     private val masterKeyAlias by lazy {
diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/util/security/EncryptionErrorResetTool.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/util/security/EncryptionErrorResetTool.kt
index de29ea8f6815868e084d7e29fc6da8f74729620f..329cff723840f516629080ef7a657f29c66595a8 100644
--- a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/util/security/EncryptionErrorResetTool.kt
+++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/util/security/EncryptionErrorResetTool.kt
@@ -4,6 +4,7 @@ import android.content.Context
 import android.content.SharedPreferences
 import androidx.core.content.edit
 import de.rki.coronawarnapp.storage.DATABASE_NAME
+import de.rki.coronawarnapp.util.di.AppContext
 import de.rki.coronawarnapp.util.errors.causes
 import org.joda.time.Instant
 import timber.log.Timber
@@ -22,7 +23,7 @@ import javax.inject.Singleton
  */
 @Singleton
 class EncryptionErrorResetTool @Inject constructor(
-    private val context: Context
+    @AppContext private val context: Context
 ) {
     // https://cs.android.com/android/platform/superproject/+/master:frameworks/base/core/java/android/app/ContextImpl.java;drc=3b8e8d76315f6718a982d5e6a019b3aa4f634bcd;l=626
     private val encryptedPreferencesFile by lazy {
diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/util/ui/FragmentExtensions.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/util/ui/FragmentExtensions.kt
new file mode 100644
index 0000000000000000000000000000000000000000..50e4175deeecb95c7e0dd797962db24f242fdd7d
--- /dev/null
+++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/util/ui/FragmentExtensions.kt
@@ -0,0 +1,8 @@
+package de.rki.coronawarnapp.util.ui
+
+import androidx.fragment.app.Fragment
+import androidx.navigation.NavDirections
+import androidx.navigation.fragment.findNavController
+import de.rki.coronawarnapp.ui.doNavigate
+
+fun Fragment.doNavigate(direction: NavDirections) = findNavController().doNavigate(direction)
diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/util/ui/SmartLiveData.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/util/ui/SmartLiveData.kt
index cdd903d6510f3e194b270797433d9661285dca25..d598cdf5b08af8ac134ffcedd0524206332a9229 100644
--- a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/util/ui/SmartLiveData.kt
+++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/util/ui/SmartLiveData.kt
@@ -11,12 +11,16 @@ import kotlin.reflect.KProperty
 
 fun <T : Any> ViewModel.smartLiveData(
     dispatcher: CoroutineDispatcher = Dispatchers.Default,
+    liveDataFactory: (ViewModel, CoroutineDispatcher) -> SmartLiveData<T> = { vm, disp ->
+        SmartLiveData(vm, disp)
+    },
     initAction: suspend () -> T
-) = SmartLiveDataProperty(dispatcher, initAction)
+) = SmartLiveDataProperty(dispatcher, initAction, liveDataFactory)
 
-class SmartLiveDataProperty<T : Any>(
+class SmartLiveDataProperty<T : Any, LV : SmartLiveData<T>>(
     private val dispatcher: CoroutineDispatcher = Dispatchers.Default,
-    private val initialValueProvider: suspend () -> T
+    private val initialValueProvider: suspend () -> T,
+    private val liveDataFactory: (ViewModel, CoroutineDispatcher) -> LV
 ) : ReadOnlyProperty<ViewModel, SmartLiveData<T>> {
 
     private var liveData: SmartLiveData<T>? = null
@@ -29,7 +33,7 @@ class SmartLiveDataProperty<T : Any>(
             return@getValue it
         }
 
-        return SmartLiveData<T>(thisRef, dispatcher).also {
+        return liveDataFactory(thisRef, dispatcher).also {
             liveData = it
             thisRef.viewModelScope.launch(context = dispatcher) {
                 it.postValue(initialValueProvider())
@@ -38,7 +42,7 @@ class SmartLiveDataProperty<T : Any>(
     }
 }
 
-class SmartLiveData<T : Any>(
+open class SmartLiveData<T : Any>(
     private val viewModel: ViewModel,
     private val dispatcher: CoroutineDispatcher
 ) : MutableLiveData<T>() {
diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/util/viewmodel/CWAViewModel.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/util/viewmodel/CWAViewModel.kt
index deaf4368cafc84eafcd3c6e4a6a5daf4150d93ad..9a61f091a66bd37c3cc379912be07b7be72d511e 100644
--- a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/util/viewmodel/CWAViewModel.kt
+++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/util/viewmodel/CWAViewModel.kt
@@ -3,20 +3,37 @@ package de.rki.coronawarnapp.util.viewmodel
 import androidx.annotation.CallSuper
 import androidx.lifecycle.ViewModel
 import androidx.lifecycle.viewModelScope
-import kotlinx.coroutines.Dispatchers
+import de.rki.coronawarnapp.util.coroutine.DefaultDispatcherProvider
+import de.rki.coronawarnapp.util.coroutine.DispatcherProvider
+import kotlinx.coroutines.CoroutineScope
+import kotlinx.coroutines.Job
 import kotlinx.coroutines.launch
 import timber.log.Timber
+import kotlin.coroutines.CoroutineContext
 
-abstract class CWAViewModel : ViewModel() {
+abstract class CWAViewModel constructor(
+    private val dispatcherProvider: DispatcherProvider = DefaultDispatcherProvider(),
+    private val childViewModels: List<CWAViewModel> = emptyList()
+) : ViewModel() {
+
+    private val tag: String = this::class.simpleName!!
 
     init {
-        Timber.v("Initialized")
+        Timber.tag(tag).v("Initialized")
     }
 
+    fun launch(
+        context: CoroutineContext = dispatcherProvider.Main,
+        block: suspend CoroutineScope.() -> Unit
+    ): Job = viewModelScope.launch(context = context, block = block)
+
     @CallSuper
     override fun onCleared() {
-        viewModelScope.launch(context = Dispatchers.Default) { }
-        Timber.v("onCleared()")
+        Timber.tag(tag).v("onCleared()")
+        childViewModels.forEach {
+            Timber.tag(tag).v("Clearing child VM: %s", it)
+            it.onCleared()
+        }
         super.onCleared()
     }
 }
diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/verification/VerificationModule.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/verification/VerificationModule.kt
index 8bd41f974462a36ff85a6d1d3e3b0560960aa85f..85d2bea5611ab57d9b81613fa80d065c1d6e461e 100644
--- a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/verification/VerificationModule.kt
+++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/verification/VerificationModule.kt
@@ -7,6 +7,7 @@ import dagger.Reusable
 import de.rki.coronawarnapp.environment.verification.VerificationCDNServerUrl
 import de.rki.coronawarnapp.http.HttpClientDefault
 import de.rki.coronawarnapp.http.RestrictedConnectionSpecs
+import de.rki.coronawarnapp.util.di.AppContext
 import de.rki.coronawarnapp.verification.server.VerificationApiV1
 import de.rki.coronawarnapp.verification.server.VerificationHttpClient
 import okhttp3.Cache
@@ -32,7 +33,7 @@ class VerificationModule {
     @Singleton
     @Provides
     fun provideVerificationApi(
-        context: Context,
+        @AppContext context: Context,
         @VerificationHttpClient client: OkHttpClient,
         @VerificationCDNServerUrl url: String,
         gsonConverterFactory: GsonConverterFactory
diff --git a/Corona-Warn-App/src/main/res/layout/fragment_main.xml b/Corona-Warn-App/src/main/res/layout/fragment_home.xml
similarity index 99%
rename from Corona-Warn-App/src/main/res/layout/fragment_main.xml
rename to Corona-Warn-App/src/main/res/layout/fragment_home.xml
index 67452ab83b6fa53faea967a7c73e4d88f1c53fd6..d0330cb93db35b6684f163e744dc164c7a7e6eef 100644
--- a/Corona-Warn-App/src/main/res/layout/fragment_main.xml
+++ b/Corona-Warn-App/src/main/res/layout/fragment_home.xml
@@ -30,7 +30,7 @@
         android:layout_height="match_parent"
         android:contentDescription="@string/main_title"
         android:fillViewport="true"
-        tools:context="de.rki.coronawarnapp.ui.main.MainFragment">
+        tools:context="de.rki.coronawarnapp.ui.main.home.HomeFragment">
 
         <!-- todo apply merge tags through xml when applicable (eod) -->
         <androidx.constraintlayout.widget.ConstraintLayout
diff --git a/Corona-Warn-App/src/main/res/navigation/nav_graph.xml b/Corona-Warn-App/src/main/res/navigation/nav_graph.xml
index ac0bff96c293d40617e2417b5314444020403fc9..0ad00127e569d57ec200855134f3e387ce7fd590 100644
--- a/Corona-Warn-App/src/main/res/navigation/nav_graph.xml
+++ b/Corona-Warn-App/src/main/res/navigation/nav_graph.xml
@@ -10,9 +10,9 @@
     <!-- Main -->
     <fragment
         android:id="@+id/mainFragment"
-        android:name="de.rki.coronawarnapp.ui.main.MainFragment"
+        android:name="de.rki.coronawarnapp.ui.main.home.HomeFragment"
         android:label="MainFragment"
-        tools:layout="@layout/fragment_main">
+        tools:layout="@layout/fragment_home">
         <action
             android:id="@+id/action_mainFragment_to_settingsTracingFragment"
             app:destination="@id/settingsTracingFragment" />
@@ -50,13 +50,13 @@
 
     <fragment
         android:id="@+id/mainSharingFragment"
-        android:name="de.rki.coronawarnapp.ui.main.MainShareFragment"
+        android:name="de.rki.coronawarnapp.ui.main.share.MainShareFragment"
         android:label="@layout/fragment_main_share"
         tools:layout="@layout/fragment_main_share" />
 
     <fragment
         android:id="@+id/mainOverviewFragment"
-        android:name="de.rki.coronawarnapp.ui.main.MainOverviewFragment"
+        android:name="de.rki.coronawarnapp.ui.main.overview.MainOverviewFragment"
         android:label="@layout/fragment_main_overview"
         tools:layout="@layout/fragment_main_overview" />
 
diff --git a/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/ui/main/home/MainFragmentViewModelTest.kt b/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/ui/main/home/MainFragmentViewModelTest.kt
new file mode 100644
index 0000000000000000000000000000000000000000..4d2f97fd4c6bda38b952345fb62ef168853552eb
--- /dev/null
+++ b/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/ui/main/home/MainFragmentViewModelTest.kt
@@ -0,0 +1,2 @@
+package de.rki.coronawarnapp.ui.main.home
+
diff --git a/Corona-Warn-App/src/test/java/testhelpers/BaseTest.kt b/Corona-Warn-App/src/testShared/java/testhelpers/BaseTest.kt
similarity index 100%
rename from Corona-Warn-App/src/test/java/testhelpers/BaseTest.kt
rename to Corona-Warn-App/src/testShared/java/testhelpers/BaseTest.kt
diff --git a/Corona-Warn-App/src/test/java/testhelpers/logging/JUnitTree.kt b/Corona-Warn-App/src/testShared/java/testhelpers/logging/JUnitTree.kt
similarity index 100%
rename from Corona-Warn-App/src/test/java/testhelpers/logging/JUnitTree.kt
rename to Corona-Warn-App/src/testShared/java/testhelpers/logging/JUnitTree.kt