diff --git a/.idea/codeStyles/Project.xml b/.idea/codeStyles/Project.xml
deleted file mode 100644
index 098fe846891336dbe9c4465f59ebbba03506e4f1..0000000000000000000000000000000000000000
--- a/.idea/codeStyles/Project.xml
+++ /dev/null
@@ -1,136 +0,0 @@
-<component name="ProjectCodeStyleConfiguration">
-  <code_scheme name="Project" version="173">
-    <JetCodeStyleSettings>
-      <option name="PACKAGES_TO_USE_STAR_IMPORTS">
-        <value>
-          <package name="kotlinx.android.synthetic" withSubpackages="true" static="false" />
-        </value>
-      </option>
-      <option name="NAME_COUNT_TO_USE_STAR_IMPORT" value="99" />
-      <option name="NAME_COUNT_TO_USE_STAR_IMPORT_FOR_MEMBERS" value="99" />
-      <option name="CODE_STYLE_DEFAULTS" value="KOTLIN_OFFICIAL" />
-    </JetCodeStyleSettings>
-    <codeStyleSettings language="XML">
-      <indentOptions>
-        <option name="CONTINUATION_INDENT_SIZE" value="4" />
-      </indentOptions>
-      <arrangement>
-        <rules>
-          <section>
-            <rule>
-              <match>
-                <AND>
-                  <NAME>xmlns:android</NAME>
-                  <XML_ATTRIBUTE />
-                  <XML_NAMESPACE>^$</XML_NAMESPACE>
-                </AND>
-              </match>
-            </rule>
-          </section>
-          <section>
-            <rule>
-              <match>
-                <AND>
-                  <NAME>xmlns:.*</NAME>
-                  <XML_ATTRIBUTE />
-                  <XML_NAMESPACE>^$</XML_NAMESPACE>
-                </AND>
-              </match>
-              <order>BY_NAME</order>
-            </rule>
-          </section>
-          <section>
-            <rule>
-              <match>
-                <AND>
-                  <NAME>.*:id</NAME>
-                  <XML_ATTRIBUTE />
-                  <XML_NAMESPACE>http://schemas.android.com/apk/res/android</XML_NAMESPACE>
-                </AND>
-              </match>
-            </rule>
-          </section>
-          <section>
-            <rule>
-              <match>
-                <AND>
-                  <NAME>.*:name</NAME>
-                  <XML_ATTRIBUTE />
-                  <XML_NAMESPACE>http://schemas.android.com/apk/res/android</XML_NAMESPACE>
-                </AND>
-              </match>
-            </rule>
-          </section>
-          <section>
-            <rule>
-              <match>
-                <AND>
-                  <NAME>name</NAME>
-                  <XML_ATTRIBUTE />
-                  <XML_NAMESPACE>^$</XML_NAMESPACE>
-                </AND>
-              </match>
-            </rule>
-          </section>
-          <section>
-            <rule>
-              <match>
-                <AND>
-                  <NAME>style</NAME>
-                  <XML_ATTRIBUTE />
-                  <XML_NAMESPACE>^$</XML_NAMESPACE>
-                </AND>
-              </match>
-            </rule>
-          </section>
-          <section>
-            <rule>
-              <match>
-                <AND>
-                  <NAME>.*</NAME>
-                  <XML_ATTRIBUTE />
-                  <XML_NAMESPACE>^$</XML_NAMESPACE>
-                </AND>
-              </match>
-              <order>BY_NAME</order>
-            </rule>
-          </section>
-          <section>
-            <rule>
-              <match>
-                <AND>
-                  <NAME>.*</NAME>
-                  <XML_ATTRIBUTE />
-                  <XML_NAMESPACE>http://schemas.android.com/apk/res/android</XML_NAMESPACE>
-                </AND>
-              </match>
-              <order>ANDROID_ATTRIBUTE_ORDER</order>
-            </rule>
-          </section>
-          <section>
-            <rule>
-              <match>
-                <AND>
-                  <NAME>.*</NAME>
-                  <XML_ATTRIBUTE />
-                  <XML_NAMESPACE>.*</XML_NAMESPACE>
-                </AND>
-              </match>
-              <order>BY_NAME</order>
-            </rule>
-          </section>
-        </rules>
-      </arrangement>
-    </codeStyleSettings>
-    <codeStyleSettings language="kotlin">
-      <option name="CODE_STYLE_DEFAULTS" value="KOTLIN_OFFICIAL" />
-      <option name="KEEP_BLANK_LINES_IN_DECLARATIONS" value="1" />
-      <option name="KEEP_BLANK_LINES_IN_CODE" value="1" />
-      <option name="KEEP_BLANK_LINES_BEFORE_RBRACE" value="0" />
-      <option name="FIELD_ANNOTATION_WRAP" value="1" />
-      <indentOptions>
-        <option name="CONTINUATION_INDENT_SIZE" value="4" />
-      </indentOptions>
-    </codeStyleSettings>
-  </code_scheme>
-</component>
\ No newline at end of file
diff --git a/Corona-Warn-App/build.gradle b/Corona-Warn-App/build.gradle
index 33df807a140424a015990b7fca42410ee8d0bfb4..fabe098fea718602e1ef9b3473034211b41e0181 100644
--- a/Corona-Warn-App/build.gradle
+++ b/Corona-Warn-App/build.gradle
@@ -31,6 +31,17 @@ def environmentExtractor = { File path ->
     return "\"${escapedJson}\""
 }
 
+def getHash = { ->
+    def stdout = new ByteArrayOutputStream()
+    exec {
+        commandLine 'git', 'rev-parse', '--short', 'HEAD'
+        standardOutput = stdout
+    }
+    def result = stdout.toString().trim()
+    return result
+}
+
+
 android {
     println("Current VERSION_MAJOR: ${VERSION_MAJOR}")
     println("Current VERSION_MINOR: ${VERSION_MINOR}")
@@ -64,6 +75,7 @@ android {
 
         def prodEnvJson = environmentExtractor(file("../prod_environments.json"))
         buildConfigField "String", "ENVIRONMENT_JSONDATA", prodEnvJson
+        buildConfigField "String", "GIT_COMMIT_SHORT_HASH", "\"${getHash()}\""
 
         def devEnvironmentFile = file("../test_environments.json")
         if (devEnvironmentFile.exists()) {
diff --git a/Corona-Warn-App/schemas/de.rki.coronawarnapp.bugreporting.storage.BugDatabase/1.json b/Corona-Warn-App/schemas/de.rki.coronawarnapp.bugreporting.storage.BugDatabase/1.json
new file mode 100644
index 0000000000000000000000000000000000000000..2ce12fa899dae6730452501187001e24c798eb79
--- /dev/null
+++ b/Corona-Warn-App/schemas/de.rki.coronawarnapp.bugreporting.storage.BugDatabase/1.json
@@ -0,0 +1,112 @@
+{
+  "formatVersion": 1,
+  "database": {
+    "version": 1,
+    "identityHash": "0e8995814e331e0253eb0276f2e946a7",
+    "entities": [
+      {
+        "tableName": "BugEventEntity",
+        "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` TEXT NOT NULL, `createdAt` TEXT NOT NULL, `tag` TEXT, `info` TEXT, `exceptionClass` TEXT NOT NULL, `exceptionMessage` TEXT, `stackTrace` TEXT NOT NULL, `deviceInfo` TEXT NOT NULL, `appVersionName` TEXT NOT NULL, `appVersionCode` INTEGER NOT NULL, `apiLevel` INTEGER NOT NULL, `androidVersion` TEXT NOT NULL, `shortCommitHash` TEXT NOT NULL, `logHistory` TEXT NOT NULL, PRIMARY KEY(`id`))",
+        "fields": [
+          {
+            "fieldPath": "id",
+            "columnName": "id",
+            "affinity": "TEXT",
+            "notNull": true
+          },
+          {
+            "fieldPath": "createdAt",
+            "columnName": "createdAt",
+            "affinity": "TEXT",
+            "notNull": true
+          },
+          {
+            "fieldPath": "tag",
+            "columnName": "tag",
+            "affinity": "TEXT",
+            "notNull": false
+          },
+          {
+            "fieldPath": "info",
+            "columnName": "info",
+            "affinity": "TEXT",
+            "notNull": false
+          },
+          {
+            "fieldPath": "exceptionClass",
+            "columnName": "exceptionClass",
+            "affinity": "TEXT",
+            "notNull": true
+          },
+          {
+            "fieldPath": "exceptionMessage",
+            "columnName": "exceptionMessage",
+            "affinity": "TEXT",
+            "notNull": false
+          },
+          {
+            "fieldPath": "stackTrace",
+            "columnName": "stackTrace",
+            "affinity": "TEXT",
+            "notNull": true
+          },
+          {
+            "fieldPath": "deviceInfo",
+            "columnName": "deviceInfo",
+            "affinity": "TEXT",
+            "notNull": true
+          },
+          {
+            "fieldPath": "appVersionName",
+            "columnName": "appVersionName",
+            "affinity": "TEXT",
+            "notNull": true
+          },
+          {
+            "fieldPath": "appVersionCode",
+            "columnName": "appVersionCode",
+            "affinity": "INTEGER",
+            "notNull": true
+          },
+          {
+            "fieldPath": "apiLevel",
+            "columnName": "apiLevel",
+            "affinity": "INTEGER",
+            "notNull": true
+          },
+          {
+            "fieldPath": "androidVersion",
+            "columnName": "androidVersion",
+            "affinity": "TEXT",
+            "notNull": true
+          },
+          {
+            "fieldPath": "shortCommitHash",
+            "columnName": "shortCommitHash",
+            "affinity": "TEXT",
+            "notNull": true
+          },
+          {
+            "fieldPath": "logHistory",
+            "columnName": "logHistory",
+            "affinity": "TEXT",
+            "notNull": true
+          }
+        ],
+        "primaryKey": {
+          "columnNames": [
+            "id"
+          ],
+          "autoGenerate": false
+        },
+        "indices": [],
+        "foreignKeys": []
+      }
+    ],
+    "views": [],
+    "setupQueries": [
+      "CREATE TABLE IF NOT EXISTS room_master_table (id INTEGER PRIMARY KEY,identity_hash TEXT)",
+      "INSERT OR REPLACE INTO room_master_table (id,identity_hash) VALUES(42, '0e8995814e331e0253eb0276f2e946a7')"
+    ]
+  }
+}
\ No newline at end of file
diff --git a/Corona-Warn-App/schemas/de.rki.coronawarnapp.storage.AppDatabase/2.json b/Corona-Warn-App/schemas/de.rki.coronawarnapp.storage.AppDatabase/2.json
new file mode 100644
index 0000000000000000000000000000000000000000..a53d24a6c224fdae463d0afa90b6665929f5a580
--- /dev/null
+++ b/Corona-Warn-App/schemas/de.rki.coronawarnapp.storage.AppDatabase/2.json
@@ -0,0 +1,231 @@
+{
+  "formatVersion": 1,
+  "database": {
+    "version": 2,
+    "identityHash": "afee4b1ca6ab9abd7117fe308784bc99",
+    "entities": [
+      {
+        "tableName": "exposure_summary",
+        "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `daysSinceLastExposure` INTEGER NOT NULL, `matchedKeyCount` INTEGER NOT NULL, `maximumRiskScore` INTEGER NOT NULL, `summationRiskScore` INTEGER NOT NULL, `attenuationDurationsInMinutes` TEXT NOT NULL)",
+        "fields": [
+          {
+            "fieldPath": "id",
+            "columnName": "id",
+            "affinity": "INTEGER",
+            "notNull": true
+          },
+          {
+            "fieldPath": "daysSinceLastExposure",
+            "columnName": "daysSinceLastExposure",
+            "affinity": "INTEGER",
+            "notNull": true
+          },
+          {
+            "fieldPath": "matchedKeyCount",
+            "columnName": "matchedKeyCount",
+            "affinity": "INTEGER",
+            "notNull": true
+          },
+          {
+            "fieldPath": "maximumRiskScore",
+            "columnName": "maximumRiskScore",
+            "affinity": "INTEGER",
+            "notNull": true
+          },
+          {
+            "fieldPath": "summationRiskScore",
+            "columnName": "summationRiskScore",
+            "affinity": "INTEGER",
+            "notNull": true
+          },
+          {
+            "fieldPath": "attenuationDurationsInMinutes",
+            "columnName": "attenuationDurationsInMinutes",
+            "affinity": "TEXT",
+            "notNull": true
+          }
+        ],
+        "primaryKey": {
+          "columnNames": [
+            "id"
+          ],
+          "autoGenerate": true
+        },
+        "indices": [
+          {
+            "name": "index_exposure_summary_id",
+            "unique": false,
+            "columnNames": [
+              "id"
+            ],
+            "createSql": "CREATE INDEX IF NOT EXISTS `index_exposure_summary_id` ON `${TABLE_NAME}` (`id`)"
+          }
+        ],
+        "foreignKeys": []
+      },
+      {
+        "tableName": "date",
+        "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` TEXT NOT NULL, `path` TEXT NOT NULL, `type` INTEGER NOT NULL, PRIMARY KEY(`id`))",
+        "fields": [
+          {
+            "fieldPath": "id",
+            "columnName": "id",
+            "affinity": "TEXT",
+            "notNull": true
+          },
+          {
+            "fieldPath": "path",
+            "columnName": "path",
+            "affinity": "TEXT",
+            "notNull": true
+          },
+          {
+            "fieldPath": "type",
+            "columnName": "type",
+            "affinity": "INTEGER",
+            "notNull": true
+          }
+        ],
+        "primaryKey": {
+          "columnNames": [
+            "id"
+          ],
+          "autoGenerate": false
+        },
+        "indices": [
+          {
+            "name": "index_date_id",
+            "unique": false,
+            "columnNames": [
+              "id"
+            ],
+            "createSql": "CREATE INDEX IF NOT EXISTS `index_date_id` ON `${TABLE_NAME}` (`id`)"
+          }
+        ],
+        "foreignKeys": []
+      },
+      {
+        "tableName": "tracing_interval",
+        "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`from` INTEGER NOT NULL, `to` INTEGER NOT NULL, PRIMARY KEY(`from`, `to`))",
+        "fields": [
+          {
+            "fieldPath": "from",
+            "columnName": "from",
+            "affinity": "INTEGER",
+            "notNull": true
+          },
+          {
+            "fieldPath": "to",
+            "columnName": "to",
+            "affinity": "INTEGER",
+            "notNull": true
+          }
+        ],
+        "primaryKey": {
+          "columnNames": [
+            "from",
+            "to"
+          ],
+          "autoGenerate": false
+        },
+        "indices": [
+          {
+            "name": "index_tracing_interval_from_to",
+            "unique": false,
+            "columnNames": [
+              "from",
+              "to"
+            ],
+            "createSql": "CREATE INDEX IF NOT EXISTS `index_tracing_interval_from_to` ON `${TABLE_NAME}` (`from`, `to`)"
+          }
+        ],
+        "foreignKeys": []
+      },
+      {
+        "tableName": "CrashReportEntity",
+        "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `deviceInfo` TEXT NOT NULL, `appVersionName` TEXT NOT NULL, `appVersionCode` INTEGER NOT NULL, `apiLevel` INTEGER NOT NULL, `androidVersion` TEXT NOT NULL, `shortID` TEXT NOT NULL, `message` TEXT NOT NULL, `stackTrace` TEXT NOT NULL, `tag` TEXT, `crashedAt` INTEGER NOT NULL)",
+        "fields": [
+          {
+            "fieldPath": "id",
+            "columnName": "id",
+            "affinity": "INTEGER",
+            "notNull": true
+          },
+          {
+            "fieldPath": "deviceInfo",
+            "columnName": "deviceInfo",
+            "affinity": "TEXT",
+            "notNull": true
+          },
+          {
+            "fieldPath": "appVersionName",
+            "columnName": "appVersionName",
+            "affinity": "TEXT",
+            "notNull": true
+          },
+          {
+            "fieldPath": "appVersionCode",
+            "columnName": "appVersionCode",
+            "affinity": "INTEGER",
+            "notNull": true
+          },
+          {
+            "fieldPath": "apiLevel",
+            "columnName": "apiLevel",
+            "affinity": "INTEGER",
+            "notNull": true
+          },
+          {
+            "fieldPath": "androidVersion",
+            "columnName": "androidVersion",
+            "affinity": "TEXT",
+            "notNull": true
+          },
+          {
+            "fieldPath": "shortID",
+            "columnName": "shortID",
+            "affinity": "TEXT",
+            "notNull": true
+          },
+          {
+            "fieldPath": "message",
+            "columnName": "message",
+            "affinity": "TEXT",
+            "notNull": true
+          },
+          {
+            "fieldPath": "stackTrace",
+            "columnName": "stackTrace",
+            "affinity": "TEXT",
+            "notNull": true
+          },
+          {
+            "fieldPath": "tag",
+            "columnName": "tag",
+            "affinity": "TEXT",
+            "notNull": false
+          },
+          {
+            "fieldPath": "crashedAt",
+            "columnName": "crashedAt",
+            "affinity": "INTEGER",
+            "notNull": true
+          }
+        ],
+        "primaryKey": {
+          "columnNames": [
+            "id"
+          ],
+          "autoGenerate": true
+        },
+        "indices": [],
+        "foreignKeys": []
+      }
+    ],
+    "views": [],
+    "setupQueries": [
+      "CREATE TABLE IF NOT EXISTS room_master_table (id INTEGER PRIMARY KEY,identity_hash TEXT)",
+      "INSERT OR REPLACE INTO room_master_table (id,identity_hash) VALUES(42, 'afee4b1ca6ab9abd7117fe308784bc99')"
+    ]
+  }
+}
\ No newline at end of file
diff --git a/Corona-Warn-App/src/device/java/de/rki/coronawarnapp/bugreporting/BugReportingModule.kt b/Corona-Warn-App/src/device/java/de/rki/coronawarnapp/bugreporting/BugReportingModule.kt
new file mode 100644
index 0000000000000000000000000000000000000000..769b9e9e78558992d255b9eaaaec8358041761ae
--- /dev/null
+++ b/Corona-Warn-App/src/device/java/de/rki/coronawarnapp/bugreporting/BugReportingModule.kt
@@ -0,0 +1,28 @@
+package de.rki.coronawarnapp.bugreporting
+
+import dagger.Module
+import dagger.Provides
+import de.rki.coronawarnapp.bugreporting.loghistory.LogHistoryTree
+import timber.log.Timber
+import javax.inject.Singleton
+
+@Module
+class BugReportingModule {
+
+    @Singleton
+    @Provides
+    fun reporter(): BugReporter = object : BugReporter {
+        override fun report(throwable: Throwable, tag: String?, info: String?) {
+            // NOOP
+        }
+    }
+
+    @Singleton
+    @LogHistoryTree
+    @Provides
+    fun loggingHistory(): Timber.Tree = object : Timber.Tree() {
+        override fun log(priority: Int, tag: String?, message: String, t: Throwable?) {
+            // NOOP
+        }
+    }
+}
diff --git a/Corona-Warn-App/src/deviceForTesters/java/de/rki/coronawarnapp/bugreporting/BugReportingModule.kt b/Corona-Warn-App/src/deviceForTesters/java/de/rki/coronawarnapp/bugreporting/BugReportingModule.kt
new file mode 100644
index 0000000000000000000000000000000000000000..90bdfde710ad6101dc80a6af94421b954eb19997
--- /dev/null
+++ b/Corona-Warn-App/src/deviceForTesters/java/de/rki/coronawarnapp/bugreporting/BugReportingModule.kt
@@ -0,0 +1,41 @@
+package de.rki.coronawarnapp.bugreporting
+
+import dagger.Module
+import dagger.Provides
+import de.rki.coronawarnapp.bugreporting.loghistory.LogHistoryTree
+import de.rki.coronawarnapp.bugreporting.loghistory.RollingLogHistory
+import de.rki.coronawarnapp.bugreporting.processor.BugProcessor
+import de.rki.coronawarnapp.bugreporting.processor.DefaultBugProcessor
+import de.rki.coronawarnapp.bugreporting.reporter.DefaultBugReporter
+import de.rki.coronawarnapp.bugreporting.storage.BugDatabase
+import de.rki.coronawarnapp.bugreporting.storage.dao.DefaultBugDao
+import de.rki.coronawarnapp.bugreporting.storage.repository.BugRepository
+import de.rki.coronawarnapp.bugreporting.storage.repository.DefaultBugRepository
+import timber.log.Timber
+import javax.inject.Singleton
+
+@Module
+class BugReportingModule {
+
+    @Singleton
+    @Provides
+    fun reporter(reporter: DefaultBugReporter): BugReporter = reporter
+
+    @Singleton
+    @Provides
+    fun repository(repository: DefaultBugRepository): BugRepository = repository
+
+    @Singleton
+    @Provides
+    fun processor(processor: DefaultBugProcessor): BugProcessor = processor
+
+    @Singleton
+    @LogHistoryTree
+    @Provides
+    fun loggingHistory(loggingHistory: RollingLogHistory): Timber.Tree = loggingHistory
+
+    @Singleton
+    @Provides
+    fun bugEventDao(bugDatabaseFactory: BugDatabase.Factory): DefaultBugDao =
+        bugDatabaseFactory.create().defaultBugDao()
+}
diff --git a/Corona-Warn-App/src/deviceForTesters/java/de/rki/coronawarnapp/bugreporting/event/BugEvent.kt b/Corona-Warn-App/src/deviceForTesters/java/de/rki/coronawarnapp/bugreporting/event/BugEvent.kt
new file mode 100644
index 0000000000000000000000000000000000000000..80603278fe0a59f7043f69e1bb41f695bb0f0429
--- /dev/null
+++ b/Corona-Warn-App/src/deviceForTesters/java/de/rki/coronawarnapp/bugreporting/event/BugEvent.kt
@@ -0,0 +1,21 @@
+package de.rki.coronawarnapp.bugreporting.event
+
+import org.joda.time.Instant
+import java.util.UUID
+
+interface BugEvent {
+    val id: UUID
+    val createdAt: Instant
+    val tag: String?
+    val info: String?
+    val exceptionClass: String
+    val exceptionMessage: String?
+    val stackTrace: String
+    val appVersionName: String
+    val appVersionCode: Long
+    val deviceInfo: String
+    val apiLevel: Int
+    val androidVersion: String
+    val shortCommitHash: String
+    val logHistory: List<String>
+}
diff --git a/Corona-Warn-App/src/deviceForTesters/java/de/rki/coronawarnapp/bugreporting/event/BugEventEntity.kt b/Corona-Warn-App/src/deviceForTesters/java/de/rki/coronawarnapp/bugreporting/event/BugEventEntity.kt
new file mode 100644
index 0000000000000000000000000000000000000000..5585cac6ed7d761a29d4d9ed71f1e33a100657b3
--- /dev/null
+++ b/Corona-Warn-App/src/deviceForTesters/java/de/rki/coronawarnapp/bugreporting/event/BugEventEntity.kt
@@ -0,0 +1,24 @@
+package de.rki.coronawarnapp.bugreporting.event
+
+import androidx.room.Entity
+import androidx.room.PrimaryKey
+import org.joda.time.Instant
+import java.util.UUID
+
+@Entity
+data class BugEventEntity(
+    @PrimaryKey override var id: UUID = UUID.randomUUID(),
+    override val createdAt: Instant = Instant.now(),
+    override var tag: String? = null,
+    override val info: String? = null,
+    override val exceptionClass: String,
+    override val exceptionMessage: String? = null,
+    override val stackTrace: String,
+    override val deviceInfo: String,
+    override val appVersionName: String,
+    override val appVersionCode: Long,
+    override val apiLevel: Int,
+    override val androidVersion: String,
+    override val shortCommitHash: String,
+    override val logHistory: List<String>
+) : BugEvent
diff --git a/Corona-Warn-App/src/deviceForTesters/java/de/rki/coronawarnapp/bugreporting/event/DefaultBugEvent.kt b/Corona-Warn-App/src/deviceForTesters/java/de/rki/coronawarnapp/bugreporting/event/DefaultBugEvent.kt
new file mode 100644
index 0000000000000000000000000000000000000000..d9a0d010623fd30a392927ec89da4a4b6094c06f
--- /dev/null
+++ b/Corona-Warn-App/src/deviceForTesters/java/de/rki/coronawarnapp/bugreporting/event/DefaultBugEvent.kt
@@ -0,0 +1,21 @@
+package de.rki.coronawarnapp.bugreporting.event
+
+import org.joda.time.Instant
+import java.util.UUID
+
+class DefaultBugEvent(
+    override val id: UUID = UUID.randomUUID(),
+    override val createdAt: Instant,
+    override val tag: String?,
+    override val info: String?,
+    override val exceptionClass: String,
+    override val exceptionMessage: String?,
+    override val stackTrace: String,
+    override val deviceInfo: String,
+    override val appVersionName: String,
+    override val appVersionCode: Long,
+    override val apiLevel: Int,
+    override val androidVersion: String,
+    override val shortCommitHash: String,
+    override val logHistory: List<String>
+) : BugEvent
diff --git a/Corona-Warn-App/src/deviceForTesters/java/de/rki/coronawarnapp/bugreporting/loghistory/RollingLogHistory.kt b/Corona-Warn-App/src/deviceForTesters/java/de/rki/coronawarnapp/bugreporting/loghistory/RollingLogHistory.kt
new file mode 100644
index 0000000000000000000000000000000000000000..97696cca28e4abd2f57f2d7cdf30c8bf17d8343e
--- /dev/null
+++ b/Corona-Warn-App/src/deviceForTesters/java/de/rki/coronawarnapp/bugreporting/loghistory/RollingLogHistory.kt
@@ -0,0 +1,64 @@
+package de.rki.coronawarnapp.bugreporting.loghistory
+
+import android.util.Log
+import de.rki.coronawarnapp.util.coroutine.AppScope
+import de.rki.coronawarnapp.util.coroutine.DispatcherProvider
+import kotlinx.coroutines.CoroutineScope
+import kotlinx.coroutines.flow.MutableStateFlow
+import kotlinx.coroutines.flow.filter
+import kotlinx.coroutines.flow.launchIn
+import kotlinx.coroutines.flow.onEach
+import kotlinx.coroutines.plus
+import kotlinx.coroutines.sync.Mutex
+import kotlinx.coroutines.sync.withLock
+import timber.log.Timber
+import javax.inject.Inject
+import javax.inject.Singleton
+import kotlin.math.min
+
+@Singleton
+class RollingLogHistory @Inject constructor(
+    @AppScope private val scope: CoroutineScope,
+    dispatcherProvider: DispatcherProvider
+) : Timber.DebugTree() {
+
+    private val bufferLock = Mutex()
+    private val buffer: ArrayDeque<String> = ArrayDeque(BUFFER_SIZE)
+    private val logQueue = MutableStateFlow("")
+
+    init {
+        logQueue
+            .filter { it.isNotBlank() }
+            .onEach {
+                bufferLock.withLock {
+                    buffer.addFirst(it)
+                    if (buffer.size >= BUFFER_SIZE) {
+                        buffer.removeLast()
+                    }
+                }
+            }
+            .launchIn(scope + dispatcherProvider.IO)
+    }
+
+    suspend fun getLoglines(count: Int): List<String> = bufferLock.withLock {
+        buffer.subList(0, min(count, buffer.size))
+    }
+
+    override fun log(priority: Int, tag: String?, message: String, t: Throwable?) {
+        val formatLine =
+            "${System.currentTimeMillis()}  ${priorityToString(priority)}/$tag: $message\n"
+        logQueue.value = formatLine
+    }
+
+    companion object {
+        private const val BUFFER_SIZE = 100
+        private fun priorityToString(priority: Int): String = when (priority) {
+            Log.ERROR -> "E"
+            Log.WARN -> "W"
+            Log.INFO -> "I"
+            Log.DEBUG -> "D"
+            Log.VERBOSE -> "V"
+            else -> priority.toString()
+        }
+    }
+}
diff --git a/Corona-Warn-App/src/deviceForTesters/java/de/rki/coronawarnapp/bugreporting/processor/BugProcessor.kt b/Corona-Warn-App/src/deviceForTesters/java/de/rki/coronawarnapp/bugreporting/processor/BugProcessor.kt
new file mode 100644
index 0000000000000000000000000000000000000000..e9365038253e5d66611358ff6d241216d9b11fe5
--- /dev/null
+++ b/Corona-Warn-App/src/deviceForTesters/java/de/rki/coronawarnapp/bugreporting/processor/BugProcessor.kt
@@ -0,0 +1,7 @@
+package de.rki.coronawarnapp.bugreporting.processor
+
+import de.rki.coronawarnapp.bugreporting.event.BugEvent
+
+interface BugProcessor {
+    suspend fun processor(throwable: Throwable, tag: String?, info: String?): BugEvent
+}
diff --git a/Corona-Warn-App/src/deviceForTesters/java/de/rki/coronawarnapp/bugreporting/processor/DefaultBugProcessor.kt b/Corona-Warn-App/src/deviceForTesters/java/de/rki/coronawarnapp/bugreporting/processor/DefaultBugProcessor.kt
new file mode 100644
index 0000000000000000000000000000000000000000..12c569990d6ca9a63ebccfaa7651240997557846
--- /dev/null
+++ b/Corona-Warn-App/src/deviceForTesters/java/de/rki/coronawarnapp/bugreporting/processor/DefaultBugProcessor.kt
@@ -0,0 +1,52 @@
+package de.rki.coronawarnapp.bugreporting.processor
+
+import android.content.Context
+import android.os.Build
+import android.util.Log
+import de.rki.coronawarnapp.BuildConfig
+import de.rki.coronawarnapp.bugreporting.event.BugEvent
+import de.rki.coronawarnapp.bugreporting.event.DefaultBugEvent
+import de.rki.coronawarnapp.bugreporting.loghistory.RollingLogHistory
+import de.rki.coronawarnapp.util.TimeStamper
+import de.rki.coronawarnapp.util.di.AppContext
+import de.rki.coronawarnapp.util.tryFormattedError
+import javax.inject.Inject
+import javax.inject.Singleton
+
+@Singleton
+class DefaultBugProcessor @Inject constructor(
+    @AppContext private val context: Context,
+    private val timeStamper: TimeStamper,
+    private val rollingLogHistory: RollingLogHistory
+) : BugProcessor {
+
+    override suspend fun processor(throwable: Throwable, tag: String?, info: String?): BugEvent {
+        val crashedAt = timeStamper.nowUTC
+        val exceptionMessage = throwable.tryFormattedError(context)
+        val exceptionClass = throwable::class.java.simpleName
+        val stacktrace = Log.getStackTraceString(throwable)
+        val deviceInfo = "${Build.MANUFACTURER} ${Build.MODEL} (${Build.DEVICE})"
+        val appVersionName = BuildConfig.VERSION_NAME
+        val appVersionCode = BuildConfig.VERSION_CODE
+        val apiLevel = Build.VERSION.SDK_INT
+        val androidVersion = Build.VERSION.RELEASE
+        val shortID = BuildConfig.GIT_COMMIT_SHORT_HASH
+        val logHistory = rollingLogHistory.getLoglines(50)
+
+        return DefaultBugEvent(
+            createdAt = crashedAt,
+            tag = tag,
+            info = info,
+            exceptionClass = exceptionClass,
+            exceptionMessage = exceptionMessage,
+            stackTrace = stacktrace,
+            deviceInfo = deviceInfo,
+            appVersionName = appVersionName,
+            appVersionCode = appVersionCode.toLong(),
+            apiLevel = apiLevel,
+            androidVersion = androidVersion,
+            shortCommitHash = shortID,
+            logHistory = logHistory
+        )
+    }
+}
diff --git a/Corona-Warn-App/src/deviceForTesters/java/de/rki/coronawarnapp/bugreporting/reporter/DefaultBugReporter.kt b/Corona-Warn-App/src/deviceForTesters/java/de/rki/coronawarnapp/bugreporting/reporter/DefaultBugReporter.kt
new file mode 100644
index 0000000000000000000000000000000000000000..50bf3b51d4bdd295fc4b0d231ddbf9b0d86d5a86
--- /dev/null
+++ b/Corona-Warn-App/src/deviceForTesters/java/de/rki/coronawarnapp/bugreporting/reporter/DefaultBugReporter.kt
@@ -0,0 +1,29 @@
+package de.rki.coronawarnapp.bugreporting.reporter
+
+import de.rki.coronawarnapp.bugreporting.BugReporter
+import de.rki.coronawarnapp.bugreporting.processor.BugProcessor
+import de.rki.coronawarnapp.bugreporting.storage.repository.BugRepository
+import de.rki.coronawarnapp.util.coroutine.AppScope
+import de.rki.coronawarnapp.util.coroutine.DispatcherProvider
+import kotlinx.coroutines.CoroutineScope
+import kotlinx.coroutines.launch
+import timber.log.Timber
+import javax.inject.Inject
+import javax.inject.Singleton
+
+@Singleton
+class DefaultBugReporter @Inject constructor(
+    private val repository: BugRepository,
+    private val processor: BugProcessor,
+    @AppScope private val scope: CoroutineScope,
+    private val dispatcherProvider: DispatcherProvider
+) : BugReporter {
+
+    override fun report(throwable: Throwable, tag: String?, info: String?) {
+        Timber.e(throwable, "Processing reported bug (info=$info) from $tag.")
+        scope.launch(context = dispatcherProvider.IO) {
+            val event = processor.processor(throwable, tag, info)
+            repository.save(event)
+        }
+    }
+}
diff --git a/Corona-Warn-App/src/deviceForTesters/java/de/rki/coronawarnapp/bugreporting/storage/BugDatabase.kt b/Corona-Warn-App/src/deviceForTesters/java/de/rki/coronawarnapp/bugreporting/storage/BugDatabase.kt
new file mode 100644
index 0000000000000000000000000000000000000000..ab7bd2db9206c736664b68352a1e5b7d2f64561b
--- /dev/null
+++ b/Corona-Warn-App/src/deviceForTesters/java/de/rki/coronawarnapp/bugreporting/storage/BugDatabase.kt
@@ -0,0 +1,33 @@
+package de.rki.coronawarnapp.bugreporting.storage
+
+import android.content.Context
+import androidx.room.Database
+import androidx.room.Room
+import androidx.room.RoomDatabase
+import androidx.room.TypeConverters
+import de.rki.coronawarnapp.bugreporting.event.BugEventEntity
+import de.rki.coronawarnapp.bugreporting.storage.dao.DefaultBugDao
+import de.rki.coronawarnapp.util.database.CommonConverters
+import de.rki.coronawarnapp.util.di.AppContext
+import javax.inject.Inject
+
+@Database(
+    entities = [BugEventEntity::class],
+    version = 1,
+    exportSchema = true
+)
+@TypeConverters(CommonConverters::class)
+abstract class BugDatabase : RoomDatabase() {
+
+    abstract fun defaultBugDao(): DefaultBugDao
+
+    class Factory @Inject constructor(@AppContext private val context: Context) {
+        fun create(): BugDatabase = Room
+            .databaseBuilder(context, BugDatabase::class.java, BUG_DATABASE_NAME)
+            .build()
+    }
+
+    companion object {
+        private const val BUG_DATABASE_NAME = "bugreport-db"
+    }
+}
diff --git a/Corona-Warn-App/src/deviceForTesters/java/de/rki/coronawarnapp/bugreporting/storage/dao/BugDao.kt b/Corona-Warn-App/src/deviceForTesters/java/de/rki/coronawarnapp/bugreporting/storage/dao/BugDao.kt
new file mode 100644
index 0000000000000000000000000000000000000000..f613d95fa604929430388c6cbb1e838592a3cfc5
--- /dev/null
+++ b/Corona-Warn-App/src/deviceForTesters/java/de/rki/coronawarnapp/bugreporting/storage/dao/BugDao.kt
@@ -0,0 +1,12 @@
+package de.rki.coronawarnapp.bugreporting.storage.dao
+
+import de.rki.coronawarnapp.bugreporting.event.BugEvent
+import kotlinx.coroutines.flow.Flow
+
+interface BugDao<T : BugEvent> {
+    suspend fun insertBugEvent(bugEvent: T)
+    fun getBugEvent(id: Long): Flow<T>
+    fun getAllBugEvents(): Flow<List<T>>
+    suspend fun deleteBugEvent(id: Long)
+    suspend fun deleteAllBugEvents()
+}
diff --git a/Corona-Warn-App/src/deviceForTesters/java/de/rki/coronawarnapp/bugreporting/storage/dao/DefaultBugDao.kt b/Corona-Warn-App/src/deviceForTesters/java/de/rki/coronawarnapp/bugreporting/storage/dao/DefaultBugDao.kt
new file mode 100644
index 0000000000000000000000000000000000000000..1162899c79aa29c394261bf171d57a2a46aead73
--- /dev/null
+++ b/Corona-Warn-App/src/deviceForTesters/java/de/rki/coronawarnapp/bugreporting/storage/dao/DefaultBugDao.kt
@@ -0,0 +1,26 @@
+package de.rki.coronawarnapp.bugreporting.storage.dao
+
+import androidx.room.Dao
+import androidx.room.Insert
+import androidx.room.Query
+import de.rki.coronawarnapp.bugreporting.event.BugEventEntity
+import kotlinx.coroutines.flow.Flow
+
+@Dao
+interface DefaultBugDao : BugDao<BugEventEntity> {
+
+    @Insert
+    override suspend fun insertBugEvent(bugEvent: BugEventEntity)
+
+    @Query("SELECT * FROM BugEventEntity WHERE id = :id")
+    override fun getBugEvent(id: Long): Flow<BugEventEntity>
+
+    @Query("SELECT * FROM BugEventEntity")
+    override fun getAllBugEvents(): Flow<List<BugEventEntity>>
+
+    @Query("DELETE FROM BugEventEntity")
+    override suspend fun deleteAllBugEvents()
+
+    @Query("DELETE FROM BugEventEntity WHERE id = :id")
+    override suspend fun deleteBugEvent(id: Long)
+}
diff --git a/Corona-Warn-App/src/deviceForTesters/java/de/rki/coronawarnapp/bugreporting/storage/repository/BugRepository.kt b/Corona-Warn-App/src/deviceForTesters/java/de/rki/coronawarnapp/bugreporting/storage/repository/BugRepository.kt
new file mode 100644
index 0000000000000000000000000000000000000000..3b06c71d828d09518ddd4270d5813f5dd6a2045b
--- /dev/null
+++ b/Corona-Warn-App/src/deviceForTesters/java/de/rki/coronawarnapp/bugreporting/storage/repository/BugRepository.kt
@@ -0,0 +1,11 @@
+package de.rki.coronawarnapp.bugreporting.storage.repository
+
+import de.rki.coronawarnapp.bugreporting.event.BugEvent
+import kotlinx.coroutines.flow.Flow
+
+interface BugRepository {
+    fun getAll(): Flow<List<BugEvent>>
+    fun get(id: Long): Flow<BugEvent>
+    suspend fun save(bugEvent: BugEvent)
+    suspend fun clear()
+}
diff --git a/Corona-Warn-App/src/deviceForTesters/java/de/rki/coronawarnapp/bugreporting/storage/repository/DefaultBugRepository.kt b/Corona-Warn-App/src/deviceForTesters/java/de/rki/coronawarnapp/bugreporting/storage/repository/DefaultBugRepository.kt
new file mode 100644
index 0000000000000000000000000000000000000000..4b75a49be75c0a60712b6ecf636123e702b456fb
--- /dev/null
+++ b/Corona-Warn-App/src/deviceForTesters/java/de/rki/coronawarnapp/bugreporting/storage/repository/DefaultBugRepository.kt
@@ -0,0 +1,50 @@
+package de.rki.coronawarnapp.bugreporting.storage.repository
+
+import de.rki.coronawarnapp.bugreporting.event.BugEvent
+import de.rki.coronawarnapp.bugreporting.event.BugEventEntity
+import de.rki.coronawarnapp.bugreporting.storage.dao.DefaultBugDao
+import kotlinx.coroutines.flow.Flow
+import timber.log.Timber
+import javax.inject.Inject
+import javax.inject.Singleton
+
+@Singleton
+class DefaultBugRepository @Inject constructor(
+    private val bugDao: DefaultBugDao
+) : BugRepository {
+
+    override fun getAll(): Flow<List<BugEvent>> = bugDao.getAllBugEvents()
+
+    override fun get(id: Long): Flow<BugEvent> = bugDao.getBugEvent(id)
+
+    override suspend fun save(bugEvent: BugEvent) {
+        val bugEventEntity: BugEventEntity = bugEvent.mapToBugEventEntity()
+        bugDao.insertBugEvent(bugEventEntity)
+    }
+
+    private fun BugEvent.mapToBugEventEntity(): BugEventEntity =
+        when (this is BugEventEntity) {
+            true -> this
+            else -> BugEventEntity(
+                id = id,
+                createdAt = createdAt,
+                tag = tag,
+                info = info,
+                exceptionClass = exceptionClass,
+                exceptionMessage = exceptionMessage,
+                stackTrace = stackTrace,
+                deviceInfo = deviceInfo,
+                appVersionName = appVersionName,
+                appVersionCode = appVersionCode,
+                apiLevel = apiLevel,
+                androidVersion = androidVersion,
+                shortCommitHash = shortCommitHash,
+                logHistory = logHistory
+            )
+        }
+
+    override suspend fun clear() {
+        Timber.d("Deleting all bug events!")
+        bugDao.deleteAllBugEvents()
+    }
+}
diff --git a/Corona-Warn-App/src/deviceForTesters/java/de/rki/coronawarnapp/test/DeviceForTestersModule.kt b/Corona-Warn-App/src/deviceForTesters/java/de/rki/coronawarnapp/test/DeviceForTestersModule.kt
index 554f4f82c58966fb0969199dfa6d349e060af6b2..64f9befbc354757dc3b60b3c3b3bec8131853e39 100644
--- a/Corona-Warn-App/src/deviceForTesters/java/de/rki/coronawarnapp/test/DeviceForTestersModule.kt
+++ b/Corona-Warn-App/src/deviceForTesters/java/de/rki/coronawarnapp/test/DeviceForTestersModule.kt
@@ -1,11 +1,13 @@
 package de.rki.coronawarnapp.test
 
 import dagger.Module
+import de.rki.coronawarnapp.test.crash.ui.SettingsCrashReportFragmentModule
 import de.rki.coronawarnapp.test.tasks.TaskControllerTestModule
 
 @Module(
     includes = [
-        TaskControllerTestModule::class
+        TaskControllerTestModule::class,
+        SettingsCrashReportFragmentModule::class
     ]
 )
 class DeviceForTestersModule
diff --git a/Corona-Warn-App/src/deviceForTesters/java/de/rki/coronawarnapp/test/crash.ui/CrashReportAdapter.kt b/Corona-Warn-App/src/deviceForTesters/java/de/rki/coronawarnapp/test/crash.ui/CrashReportAdapter.kt
new file mode 100644
index 0000000000000000000000000000000000000000..afdfb4358aa590da76289fb57cf592c9b0efc2f1
--- /dev/null
+++ b/Corona-Warn-App/src/deviceForTesters/java/de/rki/coronawarnapp/test/crash.ui/CrashReportAdapter.kt
@@ -0,0 +1,47 @@
+package de.rki.coronawarnapp.test.crash.ui
+
+import android.view.LayoutInflater
+import android.view.ViewGroup
+import androidx.recyclerview.widget.RecyclerView
+import de.rki.coronawarnapp.bugreporting.event.BugEvent
+
+import de.rki.coronawarnapp.databinding.ViewCrashreportListItemBinding
+import org.joda.time.DateTimeZone
+
+class CrashReportAdapter(private val itemClickListener: (bugEvent: BugEvent) -> Unit) :
+    RecyclerView.Adapter<CrashReportAdapter.CrashHolder>() {
+
+    private var crashReports = listOf<BugEvent>()
+
+    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): CrashHolder {
+        val inflater = LayoutInflater.from(parent.context)
+        val binding = ViewCrashreportListItemBinding.inflate(inflater)
+        return CrashHolder(
+            binding
+        )
+    }
+
+    override fun onBindViewHolder(holder: CrashHolder, position: Int) {
+        val crashReport = crashReports[position]
+        holder.bind(crashReport, position)
+        holder.itemView.setOnClickListener { itemClickListener(crashReport) }
+    }
+
+    override fun getItemCount() = crashReports.size
+
+    fun updateCrashReports(crashReportList: List<BugEvent>) {
+        crashReports = crashReportList
+        notifyDataSetChanged()
+    }
+
+    class CrashHolder(private val binding: ViewCrashreportListItemBinding) :
+        RecyclerView.ViewHolder(binding.root) {
+        fun bind(bugEvent: BugEvent, pos: Int) {
+            binding.crashReportTitle = "Error #${pos + 1}"
+            binding.message = bugEvent.exceptionMessage
+            binding.crashReportDateFormatted =
+                bugEvent.createdAt.toDateTime(DateTimeZone.getDefault()).toString()
+                    .replace("T", "  ")
+        }
+    }
+}
diff --git a/Corona-Warn-App/src/deviceForTesters/java/de/rki/coronawarnapp/test/crash.ui/SettingsCrashReportDetailsFragment.kt b/Corona-Warn-App/src/deviceForTesters/java/de/rki/coronawarnapp/test/crash.ui/SettingsCrashReportDetailsFragment.kt
new file mode 100644
index 0000000000000000000000000000000000000000..f7b9ce4dbc002399282e8297029ed970fa3ec50b
--- /dev/null
+++ b/Corona-Warn-App/src/deviceForTesters/java/de/rki/coronawarnapp/test/crash.ui/SettingsCrashReportDetailsFragment.kt
@@ -0,0 +1,55 @@
+package de.rki.coronawarnapp.test.crash.ui
+
+import android.os.Bundle
+import android.view.View
+import androidx.core.app.ShareCompat
+import androidx.fragment.app.Fragment
+import de.rki.coronawarnapp.R
+import de.rki.coronawarnapp.databinding.FragmentSettingsCrashReportDetailsBinding
+import de.rki.coronawarnapp.util.di.AutoInject
+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
+
+class SettingsCrashReportDetailsFragment :
+    Fragment(R.layout.fragment_settings_crash_report_details), AutoInject {
+
+    @Inject lateinit var viewModelFactory: CWAViewModelFactoryProvider.Factory
+    private val vm: SettingsCrashReportViewModel by cwaViewModels(
+        ownerProducer = { requireActivity().viewModelStore },
+        factoryProducer = { viewModelFactory }
+    )
+    private val fragmentSettingsCrashReportDetailsBinding: FragmentSettingsCrashReportDetailsBinding by viewBindingLazy()
+
+    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
+        super.onViewCreated(view, savedInstanceState)
+        vm.selectedCrashReport.observe2(this) {
+            fragmentSettingsCrashReportDetailsBinding.buttonCrashReportShare.visibility = View.VISIBLE
+            fragmentSettingsCrashReportDetailsBinding.buttonCrashReportShare.setOnClickListener { shareCrashReport() }
+        }
+
+        vm.selectedCrashReportFormattedText.observe2(this) {
+            fragmentSettingsCrashReportDetailsBinding.selectedCrashReportFormattedText = it
+        }
+    }
+
+    private fun shareCrashReport() {
+        activity?.let { activity ->
+            val shareIntent = ShareCompat.IntentBuilder
+                .from(activity)
+                .setType("text/plain")
+                .setText(fragmentSettingsCrashReportDetailsBinding.textViewCrashReportDetails.text)
+                .createChooserIntent()
+
+            if (shareIntent.resolveActivity(activity.packageManager) != null) {
+                startActivity(shareIntent)
+            }
+        }
+    }
+
+    companion object {
+        private val TAG = SettingsCrashReportDetailsFragment::class.java.simpleName
+    }
+}
diff --git a/Corona-Warn-App/src/deviceForTesters/java/de/rki/coronawarnapp/test/crash.ui/SettingsCrashReportFragment.kt b/Corona-Warn-App/src/deviceForTesters/java/de/rki/coronawarnapp/test/crash.ui/SettingsCrashReportFragment.kt
new file mode 100644
index 0000000000000000000000000000000000000000..9268d0cdefb3d4c4250d39ae10dea7bced9c412d
--- /dev/null
+++ b/Corona-Warn-App/src/deviceForTesters/java/de/rki/coronawarnapp/test/crash.ui/SettingsCrashReportFragment.kt
@@ -0,0 +1,67 @@
+package de.rki.coronawarnapp.test.crash.ui
+
+import android.os.Bundle
+import android.view.View
+import androidx.fragment.app.Fragment
+import de.rki.coronawarnapp.R
+import de.rki.coronawarnapp.bugreporting.event.BugEvent
+import de.rki.coronawarnapp.databinding.FragmentCrashreporterOverviewBinding
+import de.rki.coronawarnapp.test.menu.ui.TestMenuItem
+import de.rki.coronawarnapp.util.di.AutoInject
+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 timber.log.Timber
+import javax.inject.Inject
+
+class SettingsCrashReportFragment : Fragment(R.layout.fragment_crashreporter_overview), AutoInject {
+
+    @Inject lateinit var viewModelFactory: CWAViewModelFactoryProvider.Factory
+    private val vm: SettingsCrashReportViewModel by cwaViewModels(
+        ownerProducer = { requireActivity().viewModelStore },
+        factoryProducer = { viewModelFactory }
+    )
+
+    private val fragmentCrashreporterOverviewBinding: FragmentCrashreporterOverviewBinding by viewBindingLazy()
+    private lateinit var adapter: CrashReportAdapter
+
+    override fun onCreate(savedInstanceState: Bundle?) {
+        super.onCreate(savedInstanceState)
+
+        adapter = CrashReportAdapter { crashReportClicked(it) }
+    }
+
+    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
+        super.onViewCreated(view, savedInstanceState)
+        fragmentCrashreporterOverviewBinding.list.adapter = adapter
+
+        vm.crashReports.observe2(this) {
+            adapter.updateCrashReports(it)
+        }
+
+        fragmentCrashreporterOverviewBinding.buttonClearCrashReportList.setOnClickListener {
+            vm.deleteAllCrashReports()
+        }
+
+        fragmentCrashreporterOverviewBinding.buttonTestItemForCrashReport.setOnClickListener {
+            vm.simulateException()
+        }
+    }
+
+    private fun crashReportClicked(crashReport: BugEvent) {
+        Timber.d("Clicked on crash report ${crashReport.id}")
+        vm.selectCrashReport(crashReport)
+        doNavigate(SettingsCrashReportFragmentDirections.actionCrashReportFragmentToSettingsCrashReportDetailsFragment())
+    }
+
+    companion object {
+        val TAG = SettingsCrashReportFragment::class.java.simpleName
+        val MENU_ITEM = TestMenuItem(
+            title = "Bug & Problem Reporter",
+            description = "List of Bugs & Exceptions with share option.",
+            targetId = R.id.action_testMenuFragment_to_settingsCrashReportFragment
+        )
+    }
+}
diff --git a/Corona-Warn-App/src/deviceForTesters/java/de/rki/coronawarnapp/test/crash.ui/SettingsCrashReportFragmentModule.kt b/Corona-Warn-App/src/deviceForTesters/java/de/rki/coronawarnapp/test/crash.ui/SettingsCrashReportFragmentModule.kt
new file mode 100644
index 0000000000000000000000000000000000000000..ecde683f1ec9ec04ed81cf9eb5002894d0c2fd78
--- /dev/null
+++ b/Corona-Warn-App/src/deviceForTesters/java/de/rki/coronawarnapp/test/crash.ui/SettingsCrashReportFragmentModule.kt
@@ -0,0 +1,24 @@
+package de.rki.coronawarnapp.test.crash.ui
+
+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 SettingsCrashReportFragmentModule {
+
+    @Binds
+    @IntoMap
+    @CWAViewModelKey(SettingsCrashReportViewModel::class)
+    abstract fun settingsCrashReportFragment(factory: SettingsCrashReportViewModel.Factory): CWAViewModelFactory<out CWAViewModel>
+
+    @ContributesAndroidInjector
+    abstract fun settingsCrashReportFragment(): SettingsCrashReportFragment
+
+    @ContributesAndroidInjector
+    abstract fun settingsCrashReportDetailsFragment(): SettingsCrashReportDetailsFragment
+}
diff --git a/Corona-Warn-App/src/deviceForTesters/java/de/rki/coronawarnapp/test/crash.ui/SettingsCrashReportViewModel.kt b/Corona-Warn-App/src/deviceForTesters/java/de/rki/coronawarnapp/test/crash.ui/SettingsCrashReportViewModel.kt
new file mode 100644
index 0000000000000000000000000000000000000000..234022907e2c603253e6ac70c8abffa1dd72143d
--- /dev/null
+++ b/Corona-Warn-App/src/deviceForTesters/java/de/rki/coronawarnapp/test/crash.ui/SettingsCrashReportViewModel.kt
@@ -0,0 +1,62 @@
+package de.rki.coronawarnapp.test.crash.ui
+
+import androidx.lifecycle.LiveData
+import androidx.lifecycle.MutableLiveData
+import androidx.lifecycle.asLiveData
+import androidx.lifecycle.map
+import androidx.lifecycle.viewModelScope
+import com.squareup.inject.assisted.AssistedInject
+import de.rki.coronawarnapp.bugreporting.event.BugEvent
+import de.rki.coronawarnapp.bugreporting.reportProblem
+import de.rki.coronawarnapp.bugreporting.storage.repository.BugRepository
+import de.rki.coronawarnapp.util.viewmodel.CWAViewModel
+import de.rki.coronawarnapp.util.viewmodel.SimpleCWAViewModelFactory
+import kotlinx.coroutines.Dispatchers
+import kotlinx.coroutines.launch
+import timber.log.Timber
+import java.lang.Exception
+
+class SettingsCrashReportViewModel @AssistedInject constructor(
+    private val crashReportRepository: BugRepository
+) : CWAViewModel() {
+
+    val crashReports = crashReportRepository.getAll().asLiveData()
+
+    private val selectedCrashReportMutable: MutableLiveData<BugEvent> = MutableLiveData()
+    val selectedCrashReport: LiveData<BugEvent> = selectedCrashReportMutable
+    val selectedCrashReportFormattedText: LiveData<String> = selectedCrashReportMutable.map {
+        createBugEventFormattedText(it)
+    }
+
+    fun deleteAllCrashReports() = viewModelScope.launch(Dispatchers.IO) {
+        crashReportRepository.clear()
+    }
+
+    fun simulateException() {
+        try {
+            val a = 2 / 0
+        } catch (e: Exception) {
+            Timber.e(e, "Msg: ${e.message}")
+            e.reportProblem(SettingsCrashReportViewModel::class.java.simpleName, e.message)
+        }
+    }
+
+    fun selectCrashReport(bugEvent: BugEvent) {
+        selectedCrashReportMutable.postValue(bugEvent)
+    }
+
+    private fun createBugEventFormattedText(bugEvent: BugEvent): String =
+        "Selected crash report ${bugEvent.id} \n" +
+            " # appeared at: ${bugEvent.createdAt} \n\n" +
+            " # Device: ${bugEvent.deviceInfo} \n" +
+            " # Android Version ${bugEvent.androidVersion} \n" +
+            " # Android API-Level ${bugEvent.apiLevel} \n\n" +
+            " # AppVersion: ${bugEvent.appVersionName} \n" +
+            " # AppVersionCode ${bugEvent.appVersionCode} \n" +
+            " # C-Hash ${bugEvent.shortCommitHash} \n\n\n" +
+            " ${bugEvent.stackTrace}\n\n" +
+            " # Corresponding Log: \n\n ${bugEvent.logHistory}"
+
+    @AssistedInject.Factory
+    interface Factory : SimpleCWAViewModelFactory<SettingsCrashReportViewModel>
+}
diff --git a/Corona-Warn-App/src/deviceForTesters/java/de/rki/coronawarnapp/test/menu/ui/TestMenuFragmentViewModel.kt b/Corona-Warn-App/src/deviceForTesters/java/de/rki/coronawarnapp/test/menu/ui/TestMenuFragmentViewModel.kt
index 7e6439dae9d7c53260b5bf13a10c8915c9c17f8f..aa58711c95116a6c9629216464e667b16fc3a9ce 100644
--- a/Corona-Warn-App/src/deviceForTesters/java/de/rki/coronawarnapp/test/menu/ui/TestMenuFragmentViewModel.kt
+++ b/Corona-Warn-App/src/deviceForTesters/java/de/rki/coronawarnapp/test/menu/ui/TestMenuFragmentViewModel.kt
@@ -3,6 +3,7 @@ package de.rki.coronawarnapp.test.menu.ui
 import androidx.lifecycle.MutableLiveData
 import com.squareup.inject.assisted.AssistedInject
 import de.rki.coronawarnapp.test.api.ui.TestForAPIFragment
+import de.rki.coronawarnapp.test.crash.ui.SettingsCrashReportFragment
 import de.rki.coronawarnapp.test.risklevel.ui.TestRiskLevelCalculationFragment
 import de.rki.coronawarnapp.test.tasks.ui.TestTaskControllerFragment
 import de.rki.coronawarnapp.util.ui.SingleLiveEvent
@@ -13,6 +14,7 @@ class TestMenuFragmentViewModel @AssistedInject constructor() : CWAViewModel() {
 
     val testMenuData by lazy {
         listOf(
+            SettingsCrashReportFragment.MENU_ITEM,
             TestForAPIFragment.MENU_ITEM,
             TestRiskLevelCalculationFragment.MENU_ITEM,
             TestTaskControllerFragment.MENU_ITEM
diff --git a/Corona-Warn-App/src/deviceForTesters/res/layout/fragment_crashreporter_overview.xml b/Corona-Warn-App/src/deviceForTesters/res/layout/fragment_crashreporter_overview.xml
new file mode 100644
index 0000000000000000000000000000000000000000..31bd7395a73e64aa03d8909449f5adf2d9ae243a
--- /dev/null
+++ b/Corona-Warn-App/src/deviceForTesters/res/layout/fragment_crashreporter_overview.xml
@@ -0,0 +1,74 @@
+<?xml version="1.0" encoding="utf-8"?>
+<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:app="http://schemas.android.com/apk/res-auto"
+    xmlns:tools="http://schemas.android.com/tools"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent"
+    tools:context=".ui.main.MainActivity">
+
+    <androidx.appcompat.widget.Toolbar
+        android:id="@+id/toolbarErrorReport"
+        style="@style/Widget.AppCompat.Toolbar"
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        app:layout_constraintEnd_toEndOf="parent"
+        app:layout_constraintStart_toStartOf="parent"
+        app:layout_constraintTop_toTopOf="parent"
+        app:navigationIcon="@drawable/ic_bug"
+        app:subtitle="For testers and developers"
+        app:title="Error Report" />
+
+    <Button
+        android:id="@+id/buttonClearCrashReportList"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:layout_marginStart="8dp"
+        android:text="Clear List"
+        app:layout_constraintEnd_toEndOf="parent"
+        app:layout_constraintHorizontal_chainStyle="packed"
+        app:layout_constraintStart_toEndOf="@+id/buttonTestItemForCrashReport"
+        app:layout_constraintTop_toBottomOf="@+id/toolbarErrorReport"
+        app:layout_constraintVertical_chainStyle="packed" />
+
+    <Button
+        android:id="@+id/buttonTestItemForCrashReport"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:layout_marginEnd="1dp"
+        android:text="Test Item (+1)"
+        app:layout_constraintEnd_toStartOf="@+id/buttonClearCrashReportList"
+        app:layout_constraintHorizontal_chainStyle="packed"
+        app:layout_constraintStart_toStartOf="parent"
+        app:layout_constraintTop_toBottomOf="@+id/toolbarErrorReport"
+        app:layout_constraintVertical_chainStyle="packed" />
+
+    <TextView
+        android:id="@+id/topinfo"
+        style="@style/TextAppearance.AppCompat.Caption"
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:background="@color/colorCalendarLayoutFocusOn"
+        android:gravity="center"
+        android:padding="8dp"
+        android:text="Note: Select a card to view and share details."
+        android:textColor="@color/colorTextSixteenWhite"
+        app:layout_constraintEnd_toEndOf="parent"
+        app:layout_constraintStart_toStartOf="parent"
+        app:layout_constraintTop_toBottomOf="@+id/buttonTestItemForCrashReport" />
+
+    <androidx.recyclerview.widget.RecyclerView
+        android:id="@+id/list"
+        android:layout_width="match_parent"
+        android:layout_height="0dp"
+        android:background="@color/colorCalendarLayoutFocusOn"
+        android:paddingBottom="8dp"
+        app:layoutManager="LinearLayoutManager"
+        app:layout_constraintBottom_toBottomOf="parent"
+        app:layout_constraintEnd_toEndOf="parent"
+        app:layout_constraintStart_toStartOf="parent"
+        app:layout_constraintTop_toBottomOf="@+id/topinfo"
+        tools:context="SettingsCrashReporterFragment"
+        tools:listitem="@layout/view_crashreport_list_item" />
+
+
+</androidx.constraintlayout.widget.ConstraintLayout>
\ No newline at end of file
diff --git a/Corona-Warn-App/src/deviceForTesters/res/layout/fragment_settings_crash_report_details.xml b/Corona-Warn-App/src/deviceForTesters/res/layout/fragment_settings_crash_report_details.xml
new file mode 100644
index 0000000000000000000000000000000000000000..d5d49dc2094f7bf586f72876918e04b9802a9f50
--- /dev/null
+++ b/Corona-Warn-App/src/deviceForTesters/res/layout/fragment_settings_crash_report_details.xml
@@ -0,0 +1,50 @@
+<?xml version="1.0" encoding="utf-8"?>
+<layout
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:app="http://schemas.android.com/apk/res-auto"
+    xmlns:tools="http://schemas.android.com/tools">
+
+    <data>
+        <variable
+            name="selectedCrashReportFormattedText"
+            type="String" />
+    </data>
+
+    <androidx.constraintlayout.widget.ConstraintLayout
+        android:layout_width="match_parent"
+        android:layout_height="match_parent"
+        tools:context=".test.crash.ui.SettingsCrashReportDetailsFragment">
+
+
+        <ScrollView
+            android:layout_width="match_parent"
+            android:layout_height="0dp"
+            android:layout_margin="5dp"
+            android:scrollbars="vertical"
+            app:layout_constraintBottom_toTopOf="@+id/buttonCrashReportShare"
+            app:layout_constraintEnd_toEndOf="parent"
+            app:layout_constraintStart_toStartOf="parent"
+            app:layout_constraintTop_toTopOf="parent">
+
+            <TextView
+                android:id="@+id/textViewCrashReportDetails"
+                android:layout_width="match_parent"
+                android:layout_height="wrap_content"
+                android:text="@{selectedCrashReportFormattedText}" />
+
+        </ScrollView>
+
+        <Button
+            android:id="@+id/buttonCrashReportShare"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:layout_margin="10dp"
+            android:text="Share"
+            android:background="@color/colorCalendarLayoutFocusOn"
+            android:visibility="invisible"
+            app:layout_constraintBottom_toBottomOf="parent"
+            app:layout_constraintEnd_toEndOf="parent"
+            app:layout_constraintStart_toStartOf="parent" />
+
+    </androidx.constraintlayout.widget.ConstraintLayout>
+</layout>
diff --git a/Corona-Warn-App/src/deviceForTesters/res/layout/fragment_test_menu.xml b/Corona-Warn-App/src/deviceForTesters/res/layout/fragment_test_menu.xml
index 32e387a62f941248a3155341818bf9ad30c82d6c..1746c0c05c91002998bef221502d0b3b8b009abd 100644
--- a/Corona-Warn-App/src/deviceForTesters/res/layout/fragment_test_menu.xml
+++ b/Corona-Warn-App/src/deviceForTesters/res/layout/fragment_test_menu.xml
@@ -10,16 +10,17 @@
         android:layout_width="match_parent"
         android:layout_height="wrap_content"
         app:layout_constraintEnd_toEndOf="parent"
-        app:navigationIcon="@drawable/ic_coffee"
         app:layout_constraintStart_toStartOf="parent"
-        app:subtitle="For testers ;)"
         app:layout_constraintTop_toTopOf="parent"
+        app:navigationIcon="@drawable/ic_coffee"
+        app:subtitle="For testers ;)"
         app:title="Test Menu" />
 
     <androidx.recyclerview.widget.RecyclerView
         android:id="@+id/test_menu_list"
         android:layout_width="match_parent"
         android:layout_height="0dp"
+        android:layout_marginTop="12dp"
         app:layout_constraintBottom_toBottomOf="parent"
         app:layout_constraintEnd_toEndOf="parent"
         app:layout_constraintStart_toStartOf="parent"
diff --git a/Corona-Warn-App/src/deviceForTesters/res/layout/view_crashreport_list_item.xml b/Corona-Warn-App/src/deviceForTesters/res/layout/view_crashreport_list_item.xml
new file mode 100644
index 0000000000000000000000000000000000000000..d820d54e752ee1ab99c20c29f5fcf07054638567
--- /dev/null
+++ b/Corona-Warn-App/src/deviceForTesters/res/layout/view_crashreport_list_item.xml
@@ -0,0 +1,74 @@
+<?xml version="1.0" encoding="utf-8"?>
+<layout xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:app="http://schemas.android.com/apk/res-auto">
+
+    <data>
+
+        <variable
+            name="crashReportTitle"
+            type="String" />
+
+        <variable
+            name="crashReportDateFormatted"
+            type="String" />
+
+        <variable
+            name="message"
+            type="String" />
+    </data>
+
+    <LinearLayout
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:layout_margin="8dp"
+        android:orientation="vertical"
+        android:paddingBottom="2dp">
+
+        <androidx.constraintlayout.widget.ConstraintLayout
+            style="@style/card"
+            android:layout_width="390dp"
+            android:layout_height="wrap_content"
+            android:layout_margin="@dimen/spacing_tiny"
+            android:orientation="vertical">
+
+            <TextView
+                android:id="@+id/textViewCrashReportTitle"
+                style="@style/body1"
+                android:layout_width="0dp"
+                android:layout_height="wrap_content"
+                android:text="@{crashReportTitle}"
+                android:textStyle="bold"
+                app:layout_constraintEnd_toEndOf="parent"
+                app:layout_constraintStart_toStartOf="parent"
+                app:layout_constraintTop_toTopOf="parent" />
+
+            <TextView
+                android:id="@+id/textViewCrashReportDate"
+                style="@style/body1"
+                android:layout_width="@dimen/match_constraint"
+                android:layout_height="wrap_content"
+                android:layout_marginTop="4dp"
+                android:text="@{crashReportDateFormatted}"
+                android:textAppearance="?attr/textAppearanceListItem"
+                android:textStyle="italic"
+                app:layout_constraintEnd_toEndOf="parent"
+                app:layout_constraintStart_toStartOf="parent"
+                app:layout_constraintTop_toBottomOf="@+id/textViewCrashReportTitle" />
+
+            <TextView
+                android:id="@+id/textViewCrashReportShortMessage"
+                style="@style/body1"
+                android:layout_width="0dp"
+                android:layout_height="wrap_content"
+                android:layout_marginTop="24dp"
+                android:ellipsize="end"
+                android:inputType="none"
+                android:maxLines="1"
+                android:text="@{message}"
+                app:layout_constraintEnd_toEndOf="parent"
+                app:layout_constraintStart_toStartOf="parent"
+                app:layout_constraintTop_toBottomOf="@+id/textViewCrashReportDate" />
+
+        </androidx.constraintlayout.widget.ConstraintLayout>
+    </LinearLayout>
+</layout>
\ No newline at end of file
diff --git a/Corona-Warn-App/src/deviceForTesters/res/navigation/test_nav_graph.xml b/Corona-Warn-App/src/deviceForTesters/res/navigation/test_nav_graph.xml
index b86da2f4908b0bd7958f4fb0091f1c46adafcaf0..3aff7a83c201775dc37583d1da61ee3844b3eb99 100644
--- a/Corona-Warn-App/src/deviceForTesters/res/navigation/test_nav_graph.xml
+++ b/Corona-Warn-App/src/deviceForTesters/res/navigation/test_nav_graph.xml
@@ -9,6 +9,9 @@
         android:id="@+id/test_menu_fragment"
         android:name="de.rki.coronawarnapp.test.menu.ui.TestMenuFragment"
         android:label="TestMenuFragment">
+        <action
+            android:id="@+id/action_testMenuFragment_to_settingsCrashReportFragment"
+            app:destination="@id/test_bug_report_fragment" />
         <action
             android:id="@+id/action_testMenuFragment_to_testForAPIFragment"
             app:destination="@id/test_for_api_fragment" />
@@ -26,6 +29,22 @@
         android:label="@layout/fragment_test_for_a_p_i"
         tools:layout="@layout/fragment_test_for_a_p_i" />
 
+    <fragment
+        android:id="@+id/test_bug_report_fragment"
+        android:name="de.rki.coronawarnapp.test.crash.ui.SettingsCrashReportFragment"
+        android:label="crashreporter"
+        tools:layout="@layout/fragment_crashreporter_overview">
+        <action
+            android:id="@+id/action_crashReportFragment_to_settingsCrashReportDetailsFragment"
+            app:destination="@id/settingsCrashReportDetailsFragment" />
+    </fragment>
+
+    <fragment
+        android:id="@+id/settingsCrashReportDetailsFragment"
+        android:name="de.rki.coronawarnapp.test.crash.ui.SettingsCrashReportDetailsFragment"
+        android:label="fragment_settings_crash_report_details"
+        tools:layout="@layout/fragment_settings_crash_report_details" />
+
     <fragment
         android:id="@+id/test_risklevel_calculation_fragment"
         android:name="de.rki.coronawarnapp.test.risklevel.ui.TestRiskLevelCalculationFragment"
@@ -33,15 +52,14 @@
         tools:layout="@layout/fragment_test_risk_level_calculation">
         <argument
             android:name="exampleArgument"
-            app:argType="string"
             android:defaultValue="null"
+            app:argType="string"
             app:nullable="true" />
     </fragment>
     <fragment
         android:id="@+id/test_taskcontroller_fragment"
         android:name="de.rki.coronawarnapp.test.tasks.ui.TestTaskControllerFragment"
-
-        tools:layout="@layout/fragment_test_task_controller"
-        android:label="TestTaskControllerFragment" />
+        android:label="TestTaskControllerFragment"
+        tools:layout="@layout/fragment_test_task_controller" />
 
 </navigation>
diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/CoronaWarnApplication.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/CoronaWarnApplication.kt
index 922c0ab30e5db8e345fe228a722d3b54ff73a9af..fa995ee845809e391c5c5da7e4623f779febc009 100644
--- a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/CoronaWarnApplication.kt
+++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/CoronaWarnApplication.kt
@@ -12,6 +12,7 @@ import androidx.work.WorkManager
 import dagger.android.AndroidInjector
 import dagger.android.DispatchingAndroidInjector
 import dagger.android.HasAndroidInjector
+import de.rki.coronawarnapp.bugreporting.loghistory.LogHistoryTree
 import de.rki.coronawarnapp.exception.reporting.ErrorReportReceiver
 import de.rki.coronawarnapp.exception.reporting.ReportingConstants.ERROR_REPORT_LOCAL_BROADCAST_CHANNEL
 import de.rki.coronawarnapp.notification.NotificationHelper
@@ -35,11 +36,13 @@ class CoronaWarnApplication : Application(), HasAndroidInjector {
     @Inject lateinit var component: ApplicationComponent
 
     @Inject lateinit var androidInjector: DispatchingAndroidInjector<Any>
+
     override fun androidInjector(): AndroidInjector<Any> = androidInjector
 
     @Inject lateinit var watchdogService: WatchdogService
     @Inject lateinit var taskController: TaskController
     @Inject lateinit var foregroundState: ForegroundState
+    @LogHistoryTree @Inject lateinit var rollingLogHistory: Timber.Tree
 
     override fun onCreate() {
         instance = this
@@ -49,6 +52,8 @@ class CoronaWarnApplication : Application(), HasAndroidInjector {
         Timber.v("onCreate(): Initializing Dagger")
         AppInjector.init(this)
 
+        Timber.plant(rollingLogHistory)
+
         Timber.v("onCreate(): Initializing WorkManager")
         Configuration.Builder()
             .apply { setMinimumLoggingLevel(android.util.Log.DEBUG) }.build()
diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/bugreporting/BugReporter.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/bugreporting/BugReporter.kt
new file mode 100644
index 0000000000000000000000000000000000000000..d3ae63b5936f0cb30d67f227d1640aef9603d987
--- /dev/null
+++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/bugreporting/BugReporter.kt
@@ -0,0 +1,12 @@
+package de.rki.coronawarnapp.bugreporting
+
+import de.rki.coronawarnapp.util.di.AppInjector
+
+interface BugReporter {
+    fun report(throwable: Throwable, tag: String? = null, info: String? = null)
+}
+
+fun Throwable.reportProblem(tag: String? = null, info: String? = null) {
+    val reporter = AppInjector.component.bugReporter
+    reporter.report(this, tag, info)
+}
diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/bugreporting/loghistory/LogHistoryTree.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/bugreporting/loghistory/LogHistoryTree.kt
new file mode 100644
index 0000000000000000000000000000000000000000..0852ac4c9530ceb72ebc44cfa96ad21cdedea88f
--- /dev/null
+++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/bugreporting/loghistory/LogHistoryTree.kt
@@ -0,0 +1,8 @@
+package de.rki.coronawarnapp.bugreporting.loghistory
+
+import javax.inject.Qualifier
+
+@Qualifier
+@MustBeDocumented
+@Retention(AnnotationRetention.RUNTIME)
+annotation class LogHistoryTree
diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/exception/reporting/ExceptionReporter.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/exception/reporting/ExceptionReporter.kt
index a29ddabf3f4b86efdebbae8310fae5952be4600e..8f602075d2af674dfa4b9853c9d9c22428e36777 100644
--- a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/exception/reporting/ExceptionReporter.kt
+++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/exception/reporting/ExceptionReporter.kt
@@ -5,6 +5,7 @@ import androidx.localbroadcastmanager.content.LocalBroadcastManager
 import com.google.android.gms.common.api.ApiException
 import de.rki.coronawarnapp.CoronaWarnApplication
 import de.rki.coronawarnapp.R
+import de.rki.coronawarnapp.bugreporting.reportProblem
 import de.rki.coronawarnapp.exception.ExceptionCategory
 import de.rki.coronawarnapp.exception.reporting.ReportingConstants.STATUS_CODE_GOOGLE_API_FAIL
 import de.rki.coronawarnapp.exception.reporting.ReportingConstants.STATUS_CODE_GOOGLE_UPDATE_NEEDED
@@ -21,6 +22,7 @@ fun Throwable.report(
     prefix: String?,
     suffix: String?
 ) {
+    reportProblem(tag = prefix, info = suffix)
     val context = CoronaWarnApplication.getAppContext()
 
     val intent = Intent(ReportingConstants.ERROR_REPORT_LOCAL_BROADCAST_CHANNEL)
diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/storage/AppDatabase.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/storage/AppDatabase.kt
index 454055162dc1c14c57945c1ae1b3e3b97f177631..66fc87e9d7b3b18e41d0a565b070c6c8e4eb2ad4 100644
--- a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/storage/AppDatabase.kt
+++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/storage/AppDatabase.kt
@@ -20,7 +20,11 @@ import net.sqlcipher.database.SupportFactory
 import java.io.File
 
 @Database(
-    entities = [ExposureSummaryEntity::class, KeyCacheLegacyEntity::class, TracingIntervalEntity::class],
+    entities = [
+        ExposureSummaryEntity::class,
+        KeyCacheLegacyEntity::class,
+        TracingIntervalEntity::class
+    ],
     version = 1,
     exportSchema = true
 )
diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/util/database/CommonConverters.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/util/database/CommonConverters.kt
index cbbf8366f3d47ce6b05c2917b8a471ab7e685d91..9e5ce2d20f6407093dc93fcd451926eeed9a6813 100644
--- a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/util/database/CommonConverters.kt
+++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/util/database/CommonConverters.kt
@@ -23,6 +23,7 @@ import androidx.room.TypeConverter
 import com.google.gson.Gson
 import com.google.gson.reflect.TypeToken
 import de.rki.coronawarnapp.diagnosiskeys.server.LocationCode
+import de.rki.coronawarnapp.util.gson.fromJson
 import org.joda.time.Instant
 import org.joda.time.LocalDate
 import org.joda.time.LocalTime
@@ -43,6 +44,14 @@ class CommonConverters {
         return gson.toJson(list)
     }
 
+    @TypeConverter
+    fun toStringList(string: String?): List<String>? =
+        string?.let { gson.fromJson(it) }
+
+    @TypeConverter
+    fun fromStringList(strings: List<String>?): String? =
+        strings?.let { gson.toJson(it) }
+
     @TypeConverter
     fun toUUID(value: String?): UUID? = value?.let { UUID.fromString(it) }
 
diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/util/di/ApplicationComponent.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/util/di/ApplicationComponent.kt
index bfb0644bf67a04882cfe9e716c514ef51b2e2f32..1e6ce322a1190b8d56172992a4b3281bde9fb965 100644
--- a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/util/di/ApplicationComponent.kt
+++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/util/di/ApplicationComponent.kt
@@ -7,6 +7,8 @@ import dagger.android.support.AndroidSupportInjectionModule
 import de.rki.coronawarnapp.CoronaWarnApplication
 import de.rki.coronawarnapp.appconfig.AppConfigModule
 import de.rki.coronawarnapp.appconfig.AppConfigProvider
+import de.rki.coronawarnapp.bugreporting.BugReporter
+import de.rki.coronawarnapp.bugreporting.BugReportingModule
 import de.rki.coronawarnapp.diagnosiskeys.DiagnosisKeysModule
 import de.rki.coronawarnapp.diagnosiskeys.download.KeyFileDownloader
 import de.rki.coronawarnapp.diagnosiskeys.storage.KeyCacheRepository
@@ -63,7 +65,9 @@ import javax.inject.Singleton
         PlaybookModule::class,
         TaskModule::class,
         DeviceForTestersModule::class,
+        BugReportingModule::class,
         SerializationModule::class
+
     ]
 )
 interface ApplicationComponent : AndroidInjector<CoronaWarnApplication> {
@@ -93,6 +97,8 @@ interface ApplicationComponent : AndroidInjector<CoronaWarnApplication> {
 
     @AppScope val appScope: AppCoroutineScope
 
+    val bugReporter: BugReporter
+
     @Component.Factory
     interface Factory {
         fun create(@BindsInstance app: CoronaWarnApplication): ApplicationComponent
diff --git a/Corona-Warn-App/src/main/res/menu/menu_main.xml b/Corona-Warn-App/src/main/res/menu/menu_main.xml
index 811d32f472235221f4f0022d1c690fe4883b126b..8fdae95ebad8a9f6d7f61889fa6b69008dab6321 100644
--- a/Corona-Warn-App/src/main/res/menu/menu_main.xml
+++ b/Corona-Warn-App/src/main/res/menu/menu_main.xml
@@ -1,5 +1,5 @@
-<menu xmlns:tools="http://schemas.android.com/tools"
-    xmlns:android="http://schemas.android.com/apk/res/android">
+<menu xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:tools="http://schemas.android.com/tools">
     <item
         android:id="@+id/menu_help"
         android:title="@string/menu_help" />
@@ -11,7 +11,7 @@
         android:title="@string/menu_settings" />
     <item
         android:id="@+id/menu_test"
-        android:visible="false"
         android:title="Test Menu"
+        android:visible="false"
         tools:ignore="HardcodedText" />
 </menu>
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 c5dbb30805719b2d3a7f9cee9404d2189cf76b45..6d734cbc2904ca373f763df1ffa89578a6648666 100644
--- a/Corona-Warn-App/src/main/res/navigation/nav_graph.xml
+++ b/Corona-Warn-App/src/main/res/navigation/nav_graph.xml
@@ -96,7 +96,7 @@
     <fragment
         android:id="@+id/onboardingDeltaInteroperabilityFragment"
         android:name="de.rki.coronawarnapp.ui.onboarding.OnboardingDeltaInteroperabilityFragment"
-        android:label="OnboardingDeltaInteroperabilityFragment" >
+        android:label="OnboardingDeltaInteroperabilityFragment">
         <action
             android:id="@+id/action_onboardingDeltaInteroperabilityFragment_to_informationTermsFragment"
             app:destination="@id/informationTermsFragment" />
@@ -359,6 +359,7 @@
         android:id="@+id/submissionSymptomIntroductionFragment"
         android:name="de.rki.coronawarnapp.ui.submission.fragment.SubmissionSymptomIntroductionFragment"
         android:label="SubmissionSymptomIntroductionFragment" >
+
         <action
             android:id="@+id/action_submissionSymptomIntroductionFragment_to_submissionSymptomCalendarFragment"
             app:destination="@id/submissionSymptomCalendarFragment" />
@@ -381,4 +382,5 @@
             app:destination="@id/submissionResultPositiveOtherWarningFragment" />
     </fragment>
 
+
 </navigation>
diff --git a/Corona-Warn-App/src/main/res/values/strings.xml b/Corona-Warn-App/src/main/res/values/strings.xml
index ff0ae9749ef306cf35e9a1cdd891dade56734fa8..923b29cb40751c9d778f7a7e9a70c595e7e68836 100644
--- a/Corona-Warn-App/src/main/res/values/strings.xml
+++ b/Corona-Warn-App/src/main/res/values/strings.xml
@@ -1398,4 +1398,6 @@
     <string name="interoperability_onboarding_list_subtitle_failrequest_no_network">"Your Internet connection may have been lost. Please ensure that you are connected to the Internet."</string>
     <!-- XBUT: Title for the interoperability onboarding Settings-Button if no network is available -->
     <string name="interoperability_onboarding_list_button_title_no_network">"Open Device Settings"</string>
+
+
 </resources>
\ No newline at end of file
diff --git a/gradle.properties b/gradle.properties
index 053c4359772c1f8f3f1d6de5dafbef0553327916..9de4cffa4778ef74a87f615dc794885569704cf4 100644
--- a/gradle.properties
+++ b/gradle.properties
@@ -18,6 +18,6 @@ org.gradle.parallel=true
 org.gradle.dependency.verification.console=verbose
 # Versioning, this is used by the app & pipelines to calculate the current versionCode & versionName
 VERSION_MAJOR=1
-VERSION_MINOR=6
+VERSION_MINOR=7
 VERSION_PATCH=0
-VERSION_BUILD=5
+VERSION_BUILD=1