diff --git a/Corona-Warn-App/build.gradle b/Corona-Warn-App/build.gradle
index 8d171f01a6c52ebe765decdb0e71fca18448d15f..3890c320df812b9069753361f669a7c76d676d4a 100644
--- a/Corona-Warn-App/build.gradle
+++ b/Corona-Warn-App/build.gradle
@@ -33,8 +33,8 @@ android {
         applicationId 'de.rki.coronawarnapp'
         minSdkVersion 23
         targetSdkVersion 29
-        versionCode 36
-        versionName "1.2.1"
+        versionCode 37
+        versionName "1.3.0"
 
         testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
         
@@ -235,6 +235,7 @@ dependencies {
     implementation 'androidx.preference:preference:1.1.1'
     implementation 'androidx.work:work-runtime-ktx:2.3.4'
     implementation 'android.arch.lifecycle:extensions:1.1.1'
+    implementation 'androidx.annotation:annotation:1.1.0'
 
     // QR
     implementation('com.journeyapps:zxing-android-embedded:4.1.0') { transitive = false }
@@ -249,6 +250,7 @@ dependencies {
         exclude group: 'com.google.protobuf'
     }
     testImplementation "io.mockk:mockk:1.10.0"
+    testImplementation "com.squareup.okhttp3:mockwebserver:4.8.0"
     testImplementation 'org.hamcrest:hamcrest-library:2.2'
     androidTestImplementation 'androidx.test:runner:1.2.0'
     androidTestImplementation 'androidx.test.ext:junit:1.1.1'
diff --git a/Corona-Warn-App/src/deviceForTesters/java/de.rki.coronawarnapp/TestRiskLevelCalculation.kt b/Corona-Warn-App/src/deviceForTesters/java/de.rki.coronawarnapp/TestRiskLevelCalculation.kt
index 76e9833d49ca35e56d83de2497aeaea468ae938a..b19611425cfbda1a0d01fc54ff97434843aabb51 100644
--- a/Corona-Warn-App/src/deviceForTesters/java/de.rki.coronawarnapp/TestRiskLevelCalculation.kt
+++ b/Corona-Warn-App/src/deviceForTesters/java/de.rki.coronawarnapp/TestRiskLevelCalculation.kt
@@ -107,10 +107,10 @@ class TestRiskLevelCalculation : Fragment() {
             tracingViewModel.viewModelScope.launch {
                 withContext(Dispatchers.IO) {
                     try {
-                        // Database Reset
-                        AppDatabase.getInstance(requireContext()).clearAllTables()
-                        // Delete Database Instance
+                        // Preference reset
                         SecurityHelper.resetSharedPrefs()
+                        // Database Reset
+                        AppDatabase.reset(requireContext())
                         // Export File Reset
                         FileStorageHelper.getAllFilesInKeyExportDirectory().forEach { it.delete() }
 
@@ -124,7 +124,7 @@ class TestRiskLevelCalculation : Fragment() {
                 }
                 RiskLevelTransaction.start()
                 Toast.makeText(
-                    requireContext(), "Resetted, please fetch diagnosis keys from server again",
+                    requireContext(), "Reset done, please fetch diagnosis keys from server again",
                     Toast.LENGTH_SHORT
                 ).show()
             }
diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/exception/reporting/ErrorReportReceiver.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/exception/reporting/ErrorReportReceiver.kt
index 22654e28d1960cbc788aae94329d94370a4ae348..0a3b9d44532039c17c95455fa644159fecb7d854 100644
--- a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/exception/reporting/ErrorReportReceiver.kt
+++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/exception/reporting/ErrorReportReceiver.kt
@@ -49,7 +49,7 @@ class ErrorReportReceiver(private val activity: Activity) : BroadcastReceiver()
                 ErrorCodes.REPORTED_EXCEPTION_UNKNOWN_PROBLEM.code
             )
 
-            message += "($apiStatusCode)"
+            message += " ($apiStatusCode)"
         }
 
         val errorTitle = context.resources.getString(R.string.errors_generic_details_headline)
diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/http/WebRequestBuilder.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/http/WebRequestBuilder.kt
index 5c6de861a4595467ebe46e513ed752cdf53d03d1..b6dc003eb623b8e2a9bdf2a5a0119498d1dfbc2e 100644
--- a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/http/WebRequestBuilder.kt
+++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/http/WebRequestBuilder.kt
@@ -20,22 +20,24 @@
 package de.rki.coronawarnapp.http
 
 import KeyExportFormat
+import com.google.protobuf.ByteString
 import com.google.protobuf.InvalidProtocolBufferException
 import de.rki.coronawarnapp.exception.ApplicationConfigurationCorruptException
 import de.rki.coronawarnapp.exception.ApplicationConfigurationInvalidException
-import de.rki.coronawarnapp.http.requests.RegistrationTokenRequest
 import de.rki.coronawarnapp.http.requests.RegistrationRequest
+import de.rki.coronawarnapp.http.requests.RegistrationTokenRequest
 import de.rki.coronawarnapp.http.requests.TanRequestBody
 import de.rki.coronawarnapp.http.service.DistributionService
 import de.rki.coronawarnapp.http.service.SubmissionService
 import de.rki.coronawarnapp.http.service.VerificationService
 import de.rki.coronawarnapp.server.protocols.ApplicationConfigurationOuterClass.ApplicationConfiguration
 import de.rki.coronawarnapp.service.diagnosiskey.DiagnosisKeyConstants
+import de.rki.coronawarnapp.service.submission.KeyType
 import de.rki.coronawarnapp.service.submission.SubmissionConstants
 import de.rki.coronawarnapp.storage.FileStorageHelper
 import de.rki.coronawarnapp.util.TimeAndDateExtensions.toServerFormat
 import de.rki.coronawarnapp.util.ZipHelper.unzip
-import de.rki.coronawarnapp.util.security.SecurityHelper
+import de.rki.coronawarnapp.util.security.HashHelper
 import de.rki.coronawarnapp.util.security.VerificationKeys
 import kotlinx.coroutines.Dispatchers
 import kotlinx.coroutines.withContext
@@ -43,6 +45,7 @@ import timber.log.Timber
 import java.io.File
 import java.util.Date
 import java.util.UUID
+import kotlin.math.max
 
 class WebRequestBuilder(
     private val distributionService: DistributionService,
@@ -136,17 +139,24 @@ class WebRequestBuilder(
 
     suspend fun asyncGetRegistrationToken(
         key: String,
-        keyType: String
+        keyType: KeyType
     ): String = withContext(Dispatchers.IO) {
-        val keyStr = if (keyType == SubmissionConstants.QR_CODE_KEY_TYPE) {
-            SecurityHelper.hash256(key)
+        val keyStr = if (keyType == KeyType.GUID) {
+            HashHelper.hash256(key)
         } else {
             key
         }
+
+        val paddingLength = when (keyType) {
+            KeyType.GUID -> SubmissionConstants.PADDING_LENGTH_BODY_REGISTRATION_TOKEN_GUID
+            KeyType.TELETAN -> SubmissionConstants.PADDING_LENGTH_BODY_REGISTRATION_TOKEN_TELETAN
+        }
+
         verificationService.getRegistrationToken(
             SubmissionConstants.REGISTRATION_TOKEN_URL,
             "0",
-            RegistrationTokenRequest(keyType, keyStr)
+            requestPadding(SubmissionConstants.PADDING_LENGTH_HEADER_REGISTRATION_TOKEN),
+            RegistrationTokenRequest(keyType.name, keyStr, requestPadding(paddingLength))
         ).registrationToken
     }
 
@@ -155,7 +165,12 @@ class WebRequestBuilder(
     ): Int = withContext(Dispatchers.IO) {
         verificationService.getTestResult(
             SubmissionConstants.TEST_RESULT_URL,
-            "0", RegistrationRequest(registrationToken)
+            "0",
+            requestPadding(SubmissionConstants.PADDING_LENGTH_HEADER_TEST_RESULT),
+            RegistrationRequest(
+                registrationToken,
+                requestPadding(SubmissionConstants.PADDING_LENGTH_BODY_TEST_RESULT)
+            )
         ).testResult
     }
 
@@ -163,30 +178,78 @@ class WebRequestBuilder(
         registrationToken: String
     ): String = withContext(Dispatchers.IO) {
         verificationService.getTAN(
-            SubmissionConstants.TAN_REQUEST_URL, "0",
+            SubmissionConstants.TAN_REQUEST_URL,
+            "0",
+            requestPadding(SubmissionConstants.PADDING_LENGTH_HEADER_TAN),
             TanRequestBody(
-                registrationToken
+                registrationToken,
+                requestPadding(SubmissionConstants.PADDING_LENGTH_BODY_TAN)
             )
         ).tan
     }
 
+    suspend fun asyncFakeVerification() = withContext(Dispatchers.IO) {
+        verificationService.getTAN(
+            SubmissionConstants.TAN_REQUEST_URL,
+            "1",
+            requestPadding(SubmissionConstants.PADDING_LENGTH_HEADER_TAN),
+            TanRequestBody(
+                registrationToken = SubmissionConstants.DUMMY_REGISTRATION_TOKEN,
+                requestPadding = requestPadding(SubmissionConstants.PADDING_LENGTH_BODY_TAN_FAKE)
+            )
+        )
+    }
+
     suspend fun asyncSubmitKeysToServer(
         authCode: String,
-        faked: Boolean,
         keyList: List<KeyExportFormat.TemporaryExposureKey>
     ) = withContext(Dispatchers.IO) {
         Timber.d("Writing ${keyList.size} Keys to the Submission Payload.")
+
+        val randomAdditions = 0 // prepare for random addition of keys
+        val fakeKeyCount =
+            max(SubmissionConstants.minKeyCountForSubmission + randomAdditions - keyList.size, 0)
+        val fakeKeyPadding = requestPadding(SubmissionConstants.fakeKeySize * fakeKeyCount)
+
         val submissionPayload = KeyExportFormat.SubmissionPayload.newBuilder()
             .addAllKeys(keyList)
+            .setPadding(ByteString.copyFromUtf8(fakeKeyPadding))
             .build()
-        var fakeHeader = "0"
-        if (faked) fakeHeader = Math.random().toInt().toString()
         submissionService.submitKeys(
             DiagnosisKeyConstants.DIAGNOSIS_KEYS_SUBMISSION_URL,
             authCode,
-            fakeHeader,
+            "0",
+            SubmissionConstants.EMPTY_HEADER,
             submissionPayload
         )
         return@withContext
     }
+
+    suspend fun asyncFakeSubmission() = withContext(Dispatchers.IO) {
+
+        val randomAdditions = 0 // prepare for random addition of keys
+        val fakeKeyCount = SubmissionConstants.minKeyCountForSubmission + randomAdditions
+
+        val fakeKeyPadding =
+            requestPadding(SubmissionConstants.fakeKeySize * fakeKeyCount)
+
+        val submissionPayload = KeyExportFormat.SubmissionPayload.newBuilder()
+            .setPadding(ByteString.copyFromUtf8(fakeKeyPadding))
+            .build()
+
+        submissionService.submitKeys(
+            DiagnosisKeyConstants.DIAGNOSIS_KEYS_SUBMISSION_URL,
+            SubmissionConstants.EMPTY_HEADER,
+            "1",
+            requestPadding(SubmissionConstants.PADDING_LENGTH_HEADER_SUBMISSION_FAKE),
+            submissionPayload
+        )
+    }
+
+    private fun requestPadding(length: Int): String {
+        val allowedChars = ('A'..'Z') + ('a'..'z') + ('0'..'9')
+        return (1..length)
+            .map { allowedChars.random() }
+            .joinToString("")
+    }
 }
diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/http/playbook/BackgroundNoise.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/http/playbook/BackgroundNoise.kt
new file mode 100644
index 0000000000000000000000000000000000000000..ea1005d3def6baeec8456de12c4bb9547a421d37
--- /dev/null
+++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/http/playbook/BackgroundNoise.kt
@@ -0,0 +1,38 @@
+package de.rki.coronawarnapp.http.playbook
+
+import de.rki.coronawarnapp.http.WebRequestBuilder
+import de.rki.coronawarnapp.service.submission.SubmissionConstants
+import de.rki.coronawarnapp.storage.LocalData
+import de.rki.coronawarnapp.worker.BackgroundConstants
+import de.rki.coronawarnapp.worker.BackgroundWorkScheduler
+import kotlin.random.Random
+
+class BackgroundNoise {
+    companion object {
+        @Volatile
+        private var instance: BackgroundNoise? = null
+
+        fun getInstance(): BackgroundNoise {
+            return instance ?: synchronized(this) {
+                instance ?: BackgroundNoise().also {
+                    instance = it
+                }
+            }
+        }
+    }
+
+    fun scheduleDummyPattern() {
+        if (BackgroundConstants.NUMBER_OF_DAYS_TO_RUN_PLAYBOOK > 0)
+            BackgroundWorkScheduler.scheduleBackgroundNoisePeriodicWork()
+    }
+
+    suspend fun foregroundScheduleCheck() {
+        if (LocalData.isAllowedToSubmitDiagnosisKeys() == true) {
+            val chance = Random.nextFloat() * 100
+            if (chance < SubmissionConstants.probabilityToExecutePlaybookWhenOpenApp) {
+                PlaybookImpl(WebRequestBuilder.getInstance())
+                    .dummy()
+            }
+        }
+    }
+}
diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/http/playbook/Playbook.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/http/playbook/Playbook.kt
new file mode 100644
index 0000000000000000000000000000000000000000..66ab1f957b9edcb3af994ca120a3aba2276ecc19
--- /dev/null
+++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/http/playbook/Playbook.kt
@@ -0,0 +1,29 @@
+package de.rki.coronawarnapp.http.playbook
+
+import KeyExportFormat
+import de.rki.coronawarnapp.service.submission.KeyType
+import de.rki.coronawarnapp.util.formatter.TestResult
+
+/**
+ * The concept of Plausible Deniability aims to hide the existence of a positive test result by always using a defined “playbook pattern” of requests to the Verification Server and CWA Backend so it is impossible for an attacker to identify which communication was done.
+ * The “playbook pattern” represents a well-defined communication pattern consisting of dummy requests and real requests.
+ * To hide that a real request was done, the device does multiple of these requests over a longer period of time according to the previously defined communication pattern statistically similar to all apps so it is not possible to infer by observing the traffic if the requests under concern are real or the fake ones.
+ */
+interface Playbook {
+
+    suspend fun initialRegistration(
+        key: String,
+        keyType: KeyType
+    ): String /* registration token */
+
+    suspend fun testResult(
+        registrationToken: String
+    ): TestResult
+
+    suspend fun submission(
+        registrationToken: String,
+        keys: List<KeyExportFormat.TemporaryExposureKey>
+    )
+
+    suspend fun dummy()
+}
diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/http/playbook/PlaybookImpl.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/http/playbook/PlaybookImpl.kt
new file mode 100644
index 0000000000000000000000000000000000000000..3012a11394711c4d974fc4613431790e217c13de
--- /dev/null
+++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/http/playbook/PlaybookImpl.kt
@@ -0,0 +1,143 @@
+package de.rki.coronawarnapp.http.playbook
+
+import KeyExportFormat
+import de.rki.coronawarnapp.http.WebRequestBuilder
+import de.rki.coronawarnapp.service.submission.KeyType
+import de.rki.coronawarnapp.service.submission.SubmissionConstants
+import de.rki.coronawarnapp.util.formatter.TestResult
+import kotlinx.coroutines.CoroutineScope
+import kotlinx.coroutines.Dispatchers
+import kotlinx.coroutines.delay
+import kotlinx.coroutines.launch
+import timber.log.Timber
+import java.util.UUID
+import java.util.concurrent.TimeUnit
+
+class PlaybookImpl(
+    private val webRequestBuilder: WebRequestBuilder
+) : Playbook {
+
+    private val uid = UUID.randomUUID().toString()
+    private val coroutineScope: CoroutineScope = CoroutineScope(Dispatchers.IO)
+
+    override suspend fun initialRegistration(key: String, keyType: KeyType): String {
+        Timber.i("[$uid] New Initial Registration Playbook")
+
+        // real registration
+        val (registrationToken, exception) =
+            executeCapturingExceptions { webRequestBuilder.asyncGetRegistrationToken(key, keyType) }
+
+        // fake verification
+        ignoreExceptions { webRequestBuilder.asyncFakeVerification() }
+
+        // fake submission
+        ignoreExceptions { webRequestBuilder.asyncFakeSubmission() }
+
+        coroutineScope.launch { followUpPlaybooks() }
+
+        return registrationToken ?: propagateException(exception)
+    }
+
+    override suspend fun testResult(registrationToken: String): TestResult {
+        Timber.i("[$uid] New Test Result Playbook")
+
+        // real test result
+        val (testResult, exception) =
+            executeCapturingExceptions { webRequestBuilder.asyncGetTestResult(registrationToken) }
+
+        // fake verification
+        ignoreExceptions { webRequestBuilder.asyncFakeVerification() }
+
+        // fake submission
+        ignoreExceptions { webRequestBuilder.asyncFakeSubmission() }
+
+        coroutineScope.launch { followUpPlaybooks() }
+
+        return testResult?.let { TestResult.fromInt(it) }
+            ?: propagateException(exception)
+    }
+
+    override suspend fun submission(
+        registrationToken: String,
+        keys: List<KeyExportFormat.TemporaryExposureKey>
+    ) {
+        Timber.i("[$uid] New Submission Playbook")
+
+        // real auth code
+        val (authCode, exception) = executeCapturingExceptions {
+            webRequestBuilder.asyncGetTan(
+                registrationToken
+            )
+        }
+
+        // fake verification
+        ignoreExceptions { webRequestBuilder.asyncFakeVerification() }
+
+        // real submission
+        if (authCode != null) {
+            webRequestBuilder.asyncSubmitKeysToServer(authCode, keys)
+            coroutineScope.launch { followUpPlaybooks() }
+        } else {
+            webRequestBuilder.asyncFakeSubmission()
+            coroutineScope.launch { followUpPlaybooks() }
+            propagateException(exception)
+        }
+    }
+
+    private suspend fun dummy(launchFollowUp: Boolean) {
+        // fake verification
+        ignoreExceptions { webRequestBuilder.asyncFakeVerification() }
+
+        // fake verification
+        ignoreExceptions { webRequestBuilder.asyncFakeVerification() }
+
+        // fake submission
+        ignoreExceptions { webRequestBuilder.asyncFakeSubmission() }
+
+        if (launchFollowUp)
+            coroutineScope.launch { followUpPlaybooks() }
+    }
+
+    override suspend fun dummy() = dummy(true)
+
+    private suspend fun followUpPlaybooks() {
+        val runsToExecute = IntRange(
+            SubmissionConstants.minNumberOfSequentialPlaybooks - 1 /* one was already executed */,
+            SubmissionConstants.maxNumberOfSequentialPlaybooks - 1 /* one was already executed */
+        ).random()
+        Timber.i("[$uid] Follow Up: launching $runsToExecute follow up playbooks")
+
+        repeat(runsToExecute) {
+            val executionDelay = IntRange(
+                SubmissionConstants.minDelayBetweenSequentialPlaybooks,
+                SubmissionConstants.maxDelayBetweenSequentialPlaybooks
+            ).random()
+            Timber.i("[$uid] Follow Up: (${it + 1}/$runsToExecute) waiting $executionDelay[s]...")
+            delay(TimeUnit.SECONDS.toMillis(executionDelay.toLong()))
+
+            dummy(false)
+        }
+        Timber.i("[$uid] Follow Up: finished")
+    }
+
+    private suspend fun ignoreExceptions(body: suspend () -> Unit) {
+        try {
+            body.invoke()
+        } catch (e: Exception) {
+            Timber.d(e, "Ignoring dummy request exception")
+        }
+    }
+
+    private suspend fun <T> executeCapturingExceptions(body: suspend () -> T): Pair<T?, Exception?> {
+        return try {
+            val result = body.invoke()
+            result to null
+        } catch (e: Exception) {
+            null to e
+        }
+    }
+
+    private fun propagateException(exception: Exception?): Nothing {
+        throw exception ?: IllegalStateException()
+    }
+}
diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/http/requests/RegistrationRequest.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/http/requests/RegistrationRequest.kt
index 78d7d1d62cf05c141ebf62daa3f3d22e5541ec41..6a20e507c21ae3e0dc1c0358dc78e781af9620d2 100644
--- a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/http/requests/RegistrationRequest.kt
+++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/http/requests/RegistrationRequest.kt
@@ -4,5 +4,7 @@ import com.google.gson.annotations.SerializedName
 
 data class RegistrationRequest(
     @SerializedName("registrationToken")
-    val registrationToken: String
+    val registrationToken: String? = null,
+    @SerializedName("requestPadding")
+    val requestPadding: String? = null
 )
diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/http/requests/RegistrationTokenRequest.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/http/requests/RegistrationTokenRequest.kt
index 64b51092bc8b965b0df997c83af5bff45bfd9786..9667101c70a328c36fe9d6edbca5e0737d4dc1d6 100644
--- a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/http/requests/RegistrationTokenRequest.kt
+++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/http/requests/RegistrationTokenRequest.kt
@@ -4,7 +4,9 @@ import com.google.gson.annotations.SerializedName
 
 data class RegistrationTokenRequest(
     @SerializedName("keyType")
-    val keyType: String,
+    val keyType: String? = null,
     @SerializedName("key")
-    val key: String
+    val key: String? = null,
+    @SerializedName("requestPadding")
+    val requestPadding: String? = null
 )
diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/http/requests/TanRequestBody.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/http/requests/TanRequestBody.kt
index a06f7aa9b56c5cac9f74bf0961b6a56eaecd597f..ce6c123551516d2c56975f877b451737e8aa2bea 100644
--- a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/http/requests/TanRequestBody.kt
+++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/http/requests/TanRequestBody.kt
@@ -4,5 +4,7 @@ import com.google.gson.annotations.SerializedName
 
 data class TanRequestBody(
     @SerializedName("registrationToken")
-    val registrationToken: String
+    val registrationToken: String? = null,
+    @SerializedName("requestPadding")
+    val requestPadding: String? = null
 )
diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/http/service/SubmissionService.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/http/service/SubmissionService.kt
index 13e8fca37c6e8e89860b220745ec658c0d6b15c8..a2092edea1a5456b5f8949d1ae7afdd8ad595eda 100644
--- a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/http/service/SubmissionService.kt
+++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/http/service/SubmissionService.kt
@@ -11,8 +11,9 @@ interface SubmissionService {
     @POST
     suspend fun submitKeys(
         @Url url: String,
-        @Header("cwa-authorization") authCode: String,
+        @Header("cwa-authorization") authCode: String?,
         @Header("cwa-fake") fake: String,
+        @Header("cwa-header-padding") headerPadding: String?,
         @Body requestBody: KeyExportFormat.SubmissionPayload
     ): ResponseBody
 }
diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/http/service/VerificationService.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/http/service/VerificationService.kt
index 4f47c3bedf084523905c8a3f43c4bf9ead73f66e..9974fe50fa5666111dace01e73ff0f98e14d5016 100644
--- a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/http/service/VerificationService.kt
+++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/http/service/VerificationService.kt
@@ -17,6 +17,7 @@ interface VerificationService {
     suspend fun getRegistrationToken(
         @Url url: String,
         @Header("cwa-fake") fake: String,
+        @Header("cwa-header-padding") headerPadding: String?,
         @Body requestBody: RegistrationTokenRequest
     ): RegistrationTokenResponse
 
@@ -24,6 +25,7 @@ interface VerificationService {
     suspend fun getTestResult(
         @Url url: String,
         @Header("cwa-fake") fake: String,
+        @Header("cwa-header-padding") headerPadding: String?,
         @Body request: RegistrationRequest
     ): TestResultResponse
 
@@ -31,6 +33,7 @@ interface VerificationService {
     suspend fun getTAN(
         @Url url: String,
         @Header("cwa-fake") fake: String,
+        @Header("cwa-header-padding") headerPadding: String?,
         @Body requestBody: TanRequestBody
     ): TanResponse
 }
diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/risk/TimeVariables.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/risk/TimeVariables.kt
index 55cc1860550a4039df220e6d3768d1e03155a172..c518230d7a1a0f59dab7b17da660454efd018fb2 100644
--- a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/risk/TimeVariables.kt
+++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/risk/TimeVariables.kt
@@ -188,22 +188,19 @@ object TimeVariables {
 
         // by default the tracing is assumed to be activated
         // if the API is reachable we set the value accordingly 
-        var enIsDisabled = false
-
-        try {
-            enIsDisabled = !InternalExposureNotificationClient.asyncIsEnabled()
+        val enIsDisabled = try {
+            !InternalExposureNotificationClient.asyncIsEnabled()
         } catch (e: ApiException) {
             e.report(ExceptionCategory.EXPOSURENOTIFICATION)
+            false
         }
 
         if (enIsDisabled) {
             val current = System.currentTimeMillis()
-            var lastTimeTracingWasNotActivated =
-                LocalData.lastNonActiveTracingTimestamp() ?: current
-
-            if (lastTimeTracingWasNotActivated < (current - getTimeRangeFromRetentionPeriod())) {
-                lastTimeTracingWasNotActivated = current - getTimeRangeFromRetentionPeriod()
-            }
+            val lastTimeTracingWasNotActivated = minOf(
+                LocalData.lastNonActiveTracingTimestamp() ?: current,
+                current - tracingActiveMS
+            )
 
             inactiveTracingIntervals.add(Pair(lastTimeTracingWasNotActivated, current))
         }
diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/service/diagnosiskey/DiagnosisKeyConstants.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/service/diagnosiskey/DiagnosisKeyConstants.kt
index 2121c1679602cd89469759d9a8e8df688056a294..c9010f1086dd00ee23a1f129b09ec083e5d242fa 100644
--- a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/service/diagnosiskey/DiagnosisKeyConstants.kt
+++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/service/diagnosiskey/DiagnosisKeyConstants.kt
@@ -20,9 +20,7 @@
 package de.rki.coronawarnapp.service.diagnosiskey
 
 /**
- * The Diagnosis Key constants are used inside the DiagnosisKeyService
- *
- * @see DiagnosisKeyService
+ * The Diagnosis Key constants
  */
 object DiagnosisKeyConstants {
     /** version resource variable for REST-like Service Calls */
@@ -51,10 +49,10 @@ object DiagnosisKeyConstants {
     private var CURRENT_COUNTRY = "DE"
 
     /** Distribution URL built from CDN URL's and REST resources */
-    private var VERSIONED_DISTRIBUTION_CDN_URL = "/$VERSION/$CURRENT_VERSION"
+    private var VERSIONED_DISTRIBUTION_CDN_URL = "$VERSION/$CURRENT_VERSION"
 
     /** Submission URL built from CDN URL's and REST resources */
-    private var VERSIONED_SUBMISSION_CDN_URL = "/$VERSION/$CURRENT_VERSION"
+    private var VERSIONED_SUBMISSION_CDN_URL = "$VERSION/$CURRENT_VERSION"
 
     /** Parameter Download URL built from CDN URL's and REST resources */
     private val PARAMETERS_DOWNLOAD_URL = "$VERSIONED_DISTRIBUTION_CDN_URL/$PARAMETERS"
diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/service/diagnosiskey/DiagnosisKeyService.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/service/diagnosiskey/DiagnosisKeyService.kt
deleted file mode 100644
index c2dc27c88dc426b918ed61e18d0f322572fe5503..0000000000000000000000000000000000000000
--- a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/service/diagnosiskey/DiagnosisKeyService.kt
+++ /dev/null
@@ -1,60 +0,0 @@
-/******************************************************************************
- * Corona-Warn-App                                                            *
- *                                                                            *
- * SAP SE and all other contributors /                                        *
- * copyright owners license this file to you under the Apache                 *
- * License, Version 2.0 (the "License"); you may not use this                 *
- * file except in compliance with the License.                                *
- * You may obtain a copy of the License at                                    *
- *                                                                            *
- * http://www.apache.org/licenses/LICENSE-2.0                                 *
- *                                                                            *
- * Unless required by applicable law or agreed to in writing,                 *
- * software distributed under the License is distributed on an                *
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY                     *
- * KIND, either express or implied.  See the License for the                  *
- * specific language governing permissions and limitations                    *
- * under the License.                                                         *
- ******************************************************************************/
-
-package de.rki.coronawarnapp.service.diagnosiskey
-
-import KeyExportFormat
-import de.rki.coronawarnapp.exception.DiagnosisKeyRetrievalException
-import de.rki.coronawarnapp.exception.DiagnosisKeySubmissionException
-import de.rki.coronawarnapp.http.WebRequestBuilder
-import timber.log.Timber
-
-/**
- * The Diagnosis Key Service is used to interact with the Server to submit and retrieve keys through
- * predefined structures.
- *
- * @throws DiagnosisKeyRetrievalException An Exception thrown when an error occurs during Key Retrieval from the Server
- * @throws DiagnosisKeySubmissionException An Exception thrown when an error occurs during Key Reporting to the Server
- */
-object DiagnosisKeyService {
-
-    private val TAG: String? = DiagnosisKeyService::class.simpleName
-
-    /**
-     * Asynchronously submits keys to the Server with the WebRequestBuilder by retrieving
-     * keys out of the Google API.
-     *
-     *
-     * @throws de.rki.coronawarnapp.exception.DiagnosisKeySubmissionException An Exception thrown when an error occurs during Key Reporting to the Server
-     *
-     * @param authCode - TAN Authorization Code used to validate the request
-     * @param keysToReport - KeyList in the Server Format to submit to the Server
-     */
-    suspend fun asyncSubmitKeys(
-        authCode: String,
-        keysToReport: List<KeyExportFormat.TemporaryExposureKey>
-    ) {
-        Timber.d("Diagnosis Keys will be submitted.")
-        WebRequestBuilder.getInstance().asyncSubmitKeysToServer(
-            authCode,
-            false,
-            keysToReport
-        )
-    }
-}
diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/service/submission/SubmissionConstants.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/service/submission/SubmissionConstants.kt
index 4150a275b99715addd407de02bd75a9ce8801416..4ab4045084e1622f85f212ac4909f25a604ae984 100644
--- a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/service/submission/SubmissionConstants.kt
+++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/service/submission/SubmissionConstants.kt
@@ -10,9 +10,6 @@ object SubmissionConstants {
 
     private val VERSIONED_VERIFICATION_CDN_URL = "$VERSION/$CURRENT_VERSION"
 
-    const val QR_CODE_KEY_TYPE = "GUID"
-    const val TELE_TAN_KEY_TYPE = "TELETAN"
-
     val REGISTRATION_TOKEN_URL = "$VERSIONED_VERIFICATION_CDN_URL/$REGISTRATION_TOKEN"
     val TEST_RESULT_URL = "$VERSIONED_VERIFICATION_CDN_URL/$TEST_RESULT"
     val TAN_REQUEST_URL = "$VERSIONED_VERIFICATION_CDN_URL/$TAN"
@@ -22,4 +19,38 @@ object SubmissionConstants {
     const val GUID_SEPARATOR = '?'
 
     const val SERVER_ERROR_CODE_400 = 400
+
+    const val EMPTY_HEADER = ""
+
+    // padding registration token
+    private const val VERIFICATION_BODY_FILL = 139
+
+    const val PADDING_LENGTH_HEADER_REGISTRATION_TOKEN = 0
+    const val PADDING_LENGTH_BODY_REGISTRATION_TOKEN_TELETAN = 51 + VERIFICATION_BODY_FILL
+    const val PADDING_LENGTH_BODY_REGISTRATION_TOKEN_GUID = 0 + VERIFICATION_BODY_FILL
+
+    // padding test result
+    const val PADDING_LENGTH_HEADER_TEST_RESULT = 7
+    const val PADDING_LENGTH_BODY_TEST_RESULT = 31 + VERIFICATION_BODY_FILL
+
+    // padding tan
+    const val PADDING_LENGTH_HEADER_TAN = 14
+    const val PADDING_LENGTH_BODY_TAN = 31 + VERIFICATION_BODY_FILL
+    const val PADDING_LENGTH_BODY_TAN_FAKE = 31 + VERIFICATION_BODY_FILL
+    const val DUMMY_REGISTRATION_TOKEN = "11111111-2222-4444-8888-161616161616"
+
+    const val PADDING_LENGTH_HEADER_SUBMISSION_FAKE = 36
+
+    const val probabilityToExecutePlaybookWhenOpenApp = 0f
+    const val minNumberOfSequentialPlaybooks = 1
+    const val maxNumberOfSequentialPlaybooks = 1
+    const val minDelayBetweenSequentialPlaybooks = 0
+    const val maxDelayBetweenSequentialPlaybooks = 0
+
+    const val minKeyCountForSubmission = 14
+    const val fakeKeySize = (1 * 16 /* key data*/) + (3 * 4 /* 3x int32*/)
+}
+
+enum class KeyType {
+    GUID, TELETAN;
 }
diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/service/submission/SubmissionService.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/service/submission/SubmissionService.kt
index a5026b3fe8f82b844fcf79ab4f301d046a5ae08d..10dc0ec346f03304eb595d526ccbc11c328d0402 100644
--- a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/service/submission/SubmissionService.kt
+++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/service/submission/SubmissionService.kt
@@ -4,14 +4,15 @@ import com.google.android.gms.nearby.exposurenotification.TemporaryExposureKey
 import de.rki.coronawarnapp.exception.NoGUIDOrTANSetException
 import de.rki.coronawarnapp.exception.NoRegistrationTokenSetException
 import de.rki.coronawarnapp.http.WebRequestBuilder
-import de.rki.coronawarnapp.service.submission.SubmissionConstants.QR_CODE_KEY_TYPE
-import de.rki.coronawarnapp.service.submission.SubmissionConstants.TELE_TAN_KEY_TYPE
+import de.rki.coronawarnapp.http.playbook.BackgroundNoise
+import de.rki.coronawarnapp.http.playbook.PlaybookImpl
 import de.rki.coronawarnapp.storage.LocalData
 import de.rki.coronawarnapp.transaction.SubmitDiagnosisKeysTransaction
 import de.rki.coronawarnapp.util.formatter.TestResult
 import de.rki.coronawarnapp.worker.BackgroundWorkScheduler
 
 object SubmissionService {
+
     suspend fun asyncRegisterDevice() {
         val testGUID = LocalData.testGUID()
         val testTAN = LocalData.teletan()
@@ -22,13 +23,14 @@ object SubmissionService {
             else -> throw NoGUIDOrTANSetException()
         }
         LocalData.devicePairingSuccessfulTimestamp(System.currentTimeMillis())
+        BackgroundNoise.getInstance().scheduleDummyPattern()
     }
 
     private suspend fun asyncRegisterDeviceViaGUID(guid: String) {
         val registrationToken =
-            WebRequestBuilder.getInstance().asyncGetRegistrationToken(
+            PlaybookImpl(WebRequestBuilder.getInstance()).initialRegistration(
                 guid,
-                QR_CODE_KEY_TYPE
+                KeyType.GUID
             )
 
         LocalData.registrationToken(registrationToken)
@@ -37,19 +39,15 @@ object SubmissionService {
 
     private suspend fun asyncRegisterDeviceViaTAN(tan: String) {
         val registrationToken =
-            WebRequestBuilder.getInstance().asyncGetRegistrationToken(
+            PlaybookImpl(WebRequestBuilder.getInstance()).initialRegistration(
                 tan,
-                TELE_TAN_KEY_TYPE
+                KeyType.TELETAN
             )
 
         LocalData.registrationToken(registrationToken)
         deleteTeleTAN()
     }
 
-    suspend fun asyncRequestAuthCode(registrationToken: String): String {
-        return WebRequestBuilder.getInstance().asyncGetTan(registrationToken)
-    }
-
     suspend fun asyncSubmitExposureKeys(keys: List<TemporaryExposureKey>) {
         val registrationToken =
             LocalData.registrationToken() ?: throw NoRegistrationTokenSetException()
@@ -59,9 +57,8 @@ object SubmissionService {
     suspend fun asyncRequestTestResult(): TestResult {
         val registrationToken =
             LocalData.registrationToken() ?: throw NoRegistrationTokenSetException()
-        return TestResult.fromInt(
-            WebRequestBuilder.getInstance().asyncGetTestResult(registrationToken)
-        )
+
+        return PlaybookImpl(WebRequestBuilder.getInstance()).testResult(registrationToken)
     }
 
     fun containsValidGUID(scanResult: String): Boolean {
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 df9ff72967b703742197b3d639ccbfcc6e303648..ce4640c15db065cd1bde1485ebaf723f3c43ab3d 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
@@ -2,6 +2,7 @@ package de.rki.coronawarnapp.storage
 
 import android.content.Context
 import android.database.sqlite.SQLiteDatabase
+import androidx.annotation.VisibleForTesting
 import androidx.room.Database
 import androidx.room.Room
 import androidx.room.RoomDatabase
@@ -39,6 +40,7 @@ abstract class AppDatabase : RoomDatabase() {
             }
         }
 
+        @VisibleForTesting(otherwise = VisibleForTesting.PRIVATE)
         fun resetInstance() = synchronized(this) {
             instance = null
         }
diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/storage/ExposureSummaryRepository.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/storage/ExposureSummaryRepository.kt
index 60eb7bae15005e4f8d9e26013966e856729ba541..f1836e794d8d0ae2c30ba13152fcee466c4b0942 100644
--- a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/storage/ExposureSummaryRepository.kt
+++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/storage/ExposureSummaryRepository.kt
@@ -3,6 +3,7 @@ package de.rki.coronawarnapp.storage
 import androidx.lifecycle.MutableLiveData
 import com.google.android.gms.nearby.exposurenotification.ExposureSummary
 import de.rki.coronawarnapp.CoronaWarnApplication
+import de.rki.coronawarnapp.nearby.InternalExposureNotificationClient
 
 class ExposureSummaryRepository(private val exposureSummaryDao: ExposureSummaryDao) {
     companion object {
@@ -46,13 +47,14 @@ class ExposureSummaryRepository(private val exposureSummaryDao: ExposureSummaryD
             ExposureSummaryRepository.daysSinceLastExposure.postValue(daysSinceLastExposure)
         }
 
-    suspend fun getLatestExposureSummary() = exposureSummaryDao
-        .getLatestExposureSummary()
-        ?.convertToExposureSummary()
-        .also {
-            matchedKeyCount.postValue(it?.matchedKeyCount)
-            daysSinceLastExposure.postValue(it?.daysSinceLastExposure)
-        }
+    suspend fun getLatestExposureSummary(token: String) {
+        if (InternalExposureNotificationClient.asyncIsEnabled())
+            InternalExposureNotificationClient.asyncGetExposureSummary(token)
+                .also {
+                    matchedKeyCount.postValue(it.matchedKeyCount)
+                    daysSinceLastExposure.postValue(it.daysSinceLastExposure)
+                }
+    }
 
     private fun ExposureSummaryEntity.convertToExposureSummary() =
         ExposureSummary.ExposureSummaryBuilder()
diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/storage/SubmissionRepository.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/storage/SubmissionRepository.kt
index a81018bd088121ed7bc25eca0b133c732ef5e7c7..eb969441593d73076b13fb71e42a27490959829e 100644
--- a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/storage/SubmissionRepository.kt
+++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/storage/SubmissionRepository.kt
@@ -35,7 +35,6 @@ object SubmissionRepository {
     private suspend fun fetchTestResult(): DeviceUIState {
         try {
             val testResult = SubmissionService.asyncRequestTestResult()
-
             if (testResult == TestResult.POSITIVE) {
                 LocalData.isAllowedToSubmitDiagnosisKeys(true)
             }
@@ -58,6 +57,7 @@ object SubmissionRepository {
                 TestResult.POSITIVE -> DeviceUIState.PAIRED_POSITIVE
                 TestResult.PENDING -> DeviceUIState.PAIRED_NO_RESULT
                 TestResult.INVALID -> DeviceUIState.PAIRED_ERROR
+                TestResult.REDEEMED -> DeviceUIState.PAIRED_REDEEMED
             }
         } catch (err: NoRegistrationTokenSetException) {
             return DeviceUIState.UNPAIRED
diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/storage/tracing/TracingIntervalRepository.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/storage/tracing/TracingIntervalRepository.kt
index 478e580bfec8ee9ffcc61d27896a23bb06d1c46a..0f34787c36abdac94c4c5dccce2270b19895c83a 100644
--- a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/storage/tracing/TracingIntervalRepository.kt
+++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/storage/tracing/TracingIntervalRepository.kt
@@ -61,14 +61,12 @@ class TracingIntervalRepository(private val tracingIntervalDao: TracingIntervalD
     }
 
     suspend fun getIntervals(): List<Pair<Long, Long>> {
-        deleteOutdatedInterval()
-        return tracingIntervalDao.getAllIntervals().map {
-            Pair(it.from, it.to)
-        }.also {
-            Timber.d("Intervals: $it")
-        }
-    }
+        val retentionTimestamp = System.currentTimeMillis() - TimeVariables.getDefaultRetentionPeriodInMS()
+        tracingIntervalDao.deleteOutdatedIntervals(retentionTimestamp)
 
-    private suspend fun deleteOutdatedInterval() = tracingIntervalDao
-        .deleteOutdatedIntervals(System.currentTimeMillis() - TimeVariables.getDefaultRetentionPeriodInMS())
+        return tracingIntervalDao
+            .getAllIntervals()
+            .map { Pair(maxOf(it.from, retentionTimestamp), it.to) }
+            .also { Timber.d("Intervals: $it") }
+    }
 }
diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/transaction/RiskLevelTransaction.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/transaction/RiskLevelTransaction.kt
index bb272906f58f2fc04084263debdfa92c49563c60..fd019cbe9215bfd06b6a859e29fc3626c4674f07 100644
--- a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/transaction/RiskLevelTransaction.kt
+++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/transaction/RiskLevelTransaction.kt
@@ -19,7 +19,6 @@ import de.rki.coronawarnapp.risk.RiskLevelCalculation
 import de.rki.coronawarnapp.risk.TimeVariables
 import de.rki.coronawarnapp.server.protocols.ApplicationConfigurationOuterClass
 import de.rki.coronawarnapp.service.applicationconfiguration.ApplicationConfigurationService
-import de.rki.coronawarnapp.storage.ExposureSummaryRepository
 import de.rki.coronawarnapp.storage.LocalData
 import de.rki.coronawarnapp.storage.RiskLevelRepository
 import de.rki.coronawarnapp.transaction.RiskLevelTransaction.RiskLevelTransactionState.CHECK_APP_CONNECTIVITY
@@ -355,9 +354,9 @@ object RiskLevelTransaction : Transaction() {
      */
     private suspend fun executeRetrieveExposureSummary(): ExposureSummary =
         executeState(RETRIEVE_EXPOSURE_SUMMARY) {
-            val lastExposureSummary = getLastExposureSummary() ?: getNewExposureSummary()
+            val exposureSummary = getNewExposureSummary()
 
-            return@executeState lastExposureSummary.also {
+            return@executeState exposureSummary.also {
                 Timber.v(TAG, "$transactionId - get the exposure summary for further calculation")
             }
         }
@@ -466,20 +465,6 @@ object RiskLevelTransaction : Transaction() {
         return false
     }
 
-    /**
-     * Returns the last stored ExposureSummary from the storage.
-     * The ExposureSummary will be updated in the [de.rki.coronawarnapp.receiver.ExposureStateUpdateReceiver]
-     * once the BroadcastReceiver is triggered from the Google Exposure Notification API
-     *
-     * @return exposure summary from Google Exposure Notification API
-     */
-    private suspend fun getLastExposureSummary(): ExposureSummary? {
-        return ExposureSummaryRepository.getExposureSummaryRepository()
-            .getLatestExposureSummary().also {
-                Timber.v("used exposure summary for the risk level calculation: $it")
-            }
-    }
-
     /**
      * Make a call to the backend to retrieve the current application configuration values
      *
@@ -540,9 +525,6 @@ object RiskLevelTransaction : Transaction() {
         val exposureSummary =
             InternalExposureNotificationClient.asyncGetExposureSummary(googleToken)
 
-        ExposureSummaryRepository.getExposureSummaryRepository()
-            .insertExposureSummaryEntity(exposureSummary)
-
         return exposureSummary.also {
             Timber.v("$transactionId - generated new exposure summary with $googleToken")
         }
diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/transaction/SubmitDiagnosisKeysTransaction.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/transaction/SubmitDiagnosisKeysTransaction.kt
index b9a5d52c8dcbed6e41a8764b59fa74e309ebe415..326cffe113fbaf6494681cca328f29885de533d7 100644
--- a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/transaction/SubmitDiagnosisKeysTransaction.kt
+++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/transaction/SubmitDiagnosisKeysTransaction.kt
@@ -1,13 +1,13 @@
 package de.rki.coronawarnapp.transaction
 
 import com.google.android.gms.nearby.exposurenotification.TemporaryExposureKey
-import de.rki.coronawarnapp.service.diagnosiskey.DiagnosisKeyService
+import de.rki.coronawarnapp.http.WebRequestBuilder
+import de.rki.coronawarnapp.http.playbook.PlaybookImpl
 import de.rki.coronawarnapp.service.submission.SubmissionService
 import de.rki.coronawarnapp.transaction.SubmitDiagnosisKeysTransaction.SubmitDiagnosisKeysTransactionState.CLOSE
-import de.rki.coronawarnapp.transaction.SubmitDiagnosisKeysTransaction.SubmitDiagnosisKeysTransactionState.RETRIEVE_TAN
+import de.rki.coronawarnapp.transaction.SubmitDiagnosisKeysTransaction.SubmitDiagnosisKeysTransactionState.RETRIEVE_TAN_AND_SUBMIT_KEYS
 import de.rki.coronawarnapp.transaction.SubmitDiagnosisKeysTransaction.SubmitDiagnosisKeysTransactionState.RETRIEVE_TEMPORARY_EXPOSURE_KEY_HISTORY
 import de.rki.coronawarnapp.transaction.SubmitDiagnosisKeysTransaction.SubmitDiagnosisKeysTransactionState.STORE_SUCCESS
-import de.rki.coronawarnapp.transaction.SubmitDiagnosisKeysTransaction.SubmitDiagnosisKeysTransactionState.SUBMIT_KEYS
 import de.rki.coronawarnapp.util.ProtoFormatConverterExtensions.limitKeyCount
 import de.rki.coronawarnapp.util.ProtoFormatConverterExtensions.transformKeyHistoryToExternalFormat
 
@@ -41,22 +41,17 @@ object SubmitDiagnosisKeysTransaction : Transaction() {
     /** possible transaction states */
     private enum class SubmitDiagnosisKeysTransactionState :
         TransactionState {
-        RETRIEVE_TAN,
         RETRIEVE_TEMPORARY_EXPOSURE_KEY_HISTORY,
-        SUBMIT_KEYS,
+        RETRIEVE_TAN_AND_SUBMIT_KEYS,
         STORE_SUCCESS,
         CLOSE
     }
 
     /** initiates the transaction. This suspend function guarantees a successful transaction once completed. */
-    suspend fun start(registrationToken: String, keys: List<TemporaryExposureKey>) = lockAndExecuteUnique {
-        /****************************************************
-         * RETRIEVE TAN
-         ****************************************************/
-        val authCode = executeState(RETRIEVE_TAN) {
-            SubmissionService.asyncRequestAuthCode(registrationToken)
-        }
-
+    suspend fun start(
+        registrationToken: String,
+        keys: List<TemporaryExposureKey>
+    ) = lockAndExecuteUnique {
         /****************************************************
          * RETRIEVE TEMPORARY EXPOSURE KEY HISTORY
          ****************************************************/
@@ -65,10 +60,13 @@ object SubmitDiagnosisKeysTransaction : Transaction() {
                 .transformKeyHistoryToExternalFormat()
         }
         /****************************************************
-         * SUBMIT KEYS
+         * RETRIEVE TAN & SUBMIT KEYS
          ****************************************************/
-        executeState(SUBMIT_KEYS) {
-            DiagnosisKeyService.asyncSubmitKeys(authCode, temporaryExposureKeyList)
+        executeState(RETRIEVE_TAN_AND_SUBMIT_KEYS) {
+            PlaybookImpl(WebRequestBuilder.getInstance()).submission(
+                registrationToken,
+                temporaryExposureKeyList
+            )
         }
         /****************************************************
          * STORE SUCCESS
diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/information/InformationAboutFragment.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/information/InformationAboutFragment.kt
index 7f0860263e9f8bb9794edb408748f84bb23a8fd8..52153ca9f15cdb0e8590aa7fe3aa58cec6abe6b9 100644
--- a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/information/InformationAboutFragment.kt
+++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/information/InformationAboutFragment.kt
@@ -1,6 +1,7 @@
 package de.rki.coronawarnapp.ui.information
 
 import android.os.Bundle
+import android.text.method.LinkMovementMethod
 import android.view.LayoutInflater
 import android.view.View
 import android.view.ViewGroup
@@ -37,6 +38,12 @@ class InformationAboutFragment : Fragment() {
     override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
         super.onViewCreated(view, savedInstanceState)
         setButtonOnClickListener()
+        setLinks()
+    }
+
+    private fun setLinks() {
+        binding.informationAboutEasyLanguage
+            .movementMethod = LinkMovementMethod.getInstance()
     }
 
     override fun onResume() {
diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/information/InformationLegalFragment.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/information/InformationLegalFragment.kt
index 053d1bb2fa06b08794858cab2cb2393b616cc23c..4d5b127d03617c4bdde3b3a61994e9cf11464d4f 100644
--- a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/information/InformationLegalFragment.kt
+++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/information/InformationLegalFragment.kt
@@ -1,6 +1,7 @@
 package de.rki.coronawarnapp.ui.information
 
 import android.os.Bundle
+import android.text.method.LinkMovementMethod
 import android.view.LayoutInflater
 import android.view.View
 import android.view.ViewGroup
@@ -37,6 +38,17 @@ class InformationLegalFragment : Fragment() {
     override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
         super.onViewCreated(view, savedInstanceState)
         setButtonOnClickListener()
+        setUpContactFormLinks()
+    }
+
+    /**
+     * Make the links clickable
+     */
+    private fun setUpContactFormLinks() {
+        binding.informationLegalContactForm.informationLegalContactForm
+            .movementMethod = LinkMovementMethod.getInstance()
+        binding.informationLegalContactForm.informationLegalContactFormNonEnDe
+            .movementMethod = LinkMovementMethod.getInstance()
     }
 
     override fun onResume() {
diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/main/MainActivity.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/main/MainActivity.kt
index 2302135b6258005f0c59d13d33e1d4d0bcd147b4..fd3d3941807a6a45dd8caf5fcac14a110ffcc052 100644
--- a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/main/MainActivity.kt
+++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/main/MainActivity.kt
@@ -9,14 +9,17 @@ import androidx.appcompat.app.AppCompatActivity
 import androidx.fragment.app.Fragment
 import androidx.fragment.app.FragmentManager
 import androidx.lifecycle.ViewModelProviders
+import androidx.lifecycle.lifecycleScope
 import de.rki.coronawarnapp.R
 import de.rki.coronawarnapp.storage.LocalData
+import de.rki.coronawarnapp.http.playbook.BackgroundNoise
 import de.rki.coronawarnapp.ui.viewmodel.SettingsViewModel
 import de.rki.coronawarnapp.util.ConnectivityHelper
 import de.rki.coronawarnapp.util.DialogHelper
 import de.rki.coronawarnapp.util.ExternalActionHelper
 import de.rki.coronawarnapp.util.PowerManagementHelper
 import de.rki.coronawarnapp.worker.BackgroundWorkScheduler
+import kotlinx.coroutines.launch
 
 /**
  * This activity holds all the fragments (except onboarding) and also registers a listener for
@@ -96,6 +99,13 @@ class MainActivity : AppCompatActivity() {
         settingsViewModel.updateBackgroundJobEnabled(ConnectivityHelper.autoModeEnabled(this))
         scheduleWork()
         checkShouldDisplayBackgroundWarning()
+        doBackgroundNoiseCheck()
+    }
+
+    private fun doBackgroundNoiseCheck() {
+        lifecycleScope.launch {
+            BackgroundNoise.getInstance().foregroundScheduleCheck()
+        }
     }
 
     private fun showEnergyOptimizedEnabledForBackground() {
diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/onboarding/OnboardingFragment.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/onboarding/OnboardingFragment.kt
index ace481434d72a43119d9f3f4328f95c3a362d513..e01dac101a8a7ac0070713df131b8f141a3bacf3 100644
--- a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/onboarding/OnboardingFragment.kt
+++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/onboarding/OnboardingFragment.kt
@@ -1,6 +1,7 @@
 package de.rki.coronawarnapp.ui.onboarding
 
 import android.os.Bundle
+import android.text.method.LinkMovementMethod
 import android.view.LayoutInflater
 import android.view.View
 import android.view.ViewGroup
@@ -42,6 +43,12 @@ class OnboardingFragment : Fragment() {
                 OnboardingFragmentDirections.actionOnboardingFragmentToOnboardingPrivacyFragment()
             )
         }
+        setLinks()
+    }
+
+    private fun setLinks() {
+        binding.onboardingInclude.onboardingEasyLanguage
+            .movementMethod = LinkMovementMethod.getInstance()
     }
 
     override fun onResume() {
diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/submission/SubmissionResultPositiveOtherWarningFragment.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/submission/SubmissionResultPositiveOtherWarningFragment.kt
index 901a01df567b0a6c716d99f9de78cb985f491862..471d9f48c22b05b97bd0e5b4c81f7b58dfc437c2 100644
--- a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/submission/SubmissionResultPositiveOtherWarningFragment.kt
+++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/submission/SubmissionResultPositiveOtherWarningFragment.kt
@@ -170,7 +170,6 @@ class SubmissionResultPositiveOtherWarningFragment : Fragment(),
             DialogHelper.showDialog(tracingRequiredDialog)
             return
         }
-
         internalExposureNotificationPermissionHelper.requestPermissionToShareKeys()
     }
 
@@ -187,6 +186,7 @@ class SubmissionResultPositiveOtherWarningFragment : Fragment(),
         if (keys.isNotEmpty()) {
             submissionViewModel.submitDiagnosisKeys(keys)
         } else {
+            submissionViewModel.submitWithNoDiagnosisKeys()
             navigateToSubmissionDoneFragment()
         }
     }
diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/submission/SubmissionTestResultFragment.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/submission/SubmissionTestResultFragment.kt
index 41c8ace277433609dc6740c2fa531be9a8ca0273..03aecc8b20e2803224d0dcdb03772e76f2a3c42d 100644
--- a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/submission/SubmissionTestResultFragment.kt
+++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/submission/SubmissionTestResultFragment.kt
@@ -9,6 +9,7 @@ import android.view.accessibility.AccessibilityEvent
 import androidx.activity.OnBackPressedCallback
 import androidx.fragment.app.Fragment
 import androidx.fragment.app.activityViewModels
+import androidx.lifecycle.Observer
 import androidx.navigation.fragment.findNavController
 import de.rki.coronawarnapp.R
 import de.rki.coronawarnapp.databinding.FragmentSubmissionTestResultBinding
@@ -18,6 +19,7 @@ import de.rki.coronawarnapp.exception.http.CwaWebException
 import de.rki.coronawarnapp.ui.doNavigate
 import de.rki.coronawarnapp.ui.viewmodel.SubmissionViewModel
 import de.rki.coronawarnapp.ui.viewmodel.TracingViewModel
+import de.rki.coronawarnapp.util.DeviceUIState
 import de.rki.coronawarnapp.util.DialogHelper
 import de.rki.coronawarnapp.util.observeEvent
 
@@ -115,6 +117,23 @@ class SubmissionTestResultFragment : Fragment() {
         submissionViewModel.uiStateError.observeEvent(viewLifecycleOwner) {
             DialogHelper.showDialog(buildErrorDialog(it))
         }
+
+        submissionViewModel.deviceUiState.observe(viewLifecycleOwner, Observer { uiState ->
+            if (uiState == DeviceUIState.PAIRED_REDEEMED) {
+                showRedeemedTokenWarningDialog()
+            }
+        })
+    }
+
+    private fun showRedeemedTokenWarningDialog() {
+        val dialog = DialogHelper.DialogInstance(
+            requireActivity(),
+            R.string.submission_error_dialog_web_tan_redeemed_title,
+            R.string.submission_error_dialog_web_tan_redeemed_body,
+            R.string.submission_error_dialog_web_tan_redeemed_button_positive
+        )
+
+        DialogHelper.showDialog(dialog)
     }
 
     override fun onResume() {
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 bbcba1dfe57db90ea267ba15d41d3d82461d9409..1964d9169bbf3fd3f9448ce09bd2992c5972155a 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
@@ -112,6 +112,10 @@ class SubmissionViewModel : ViewModel() {
         SubmissionService.deleteTestGUID()
     }
 
+    fun submitWithNoDiagnosisKeys() {
+        SubmissionService.submissionSuccessful()
+    }
+
     fun deregisterTestFromDevice() {
         deleteTestGUID()
         SubmissionService.deleteRegistrationToken()
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 145486acde528c4c803341a6ff1b591d794b697b..8d3b8e0c5e1dcff34f1b7553c6ea07e94be3fe11 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
@@ -158,8 +158,11 @@ class TracingViewModel : ViewModel() {
     fun refreshExposureSummary() {
         viewModelScope.launch {
             try {
-                ExposureSummaryRepository.getExposureSummaryRepository()
-                    .getLatestExposureSummary()
+                val token = LocalData.googleApiToken()
+                if (token != null) {
+                    ExposureSummaryRepository.getExposureSummaryRepository()
+                        .getLatestExposureSummary(token)
+                }
                 Timber.v("retrieved latest exposure summary from db")
             } catch (e: Exception) {
                 e.report(
diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/util/DeviceUIState.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/util/DeviceUIState.kt
index 6049195d48cd55a2a46cdba6440d145f6c6f8e2c..bc304ab27c4a7eadac06adb6decadd14c4c97fac 100644
--- a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/util/DeviceUIState.kt
+++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/util/DeviceUIState.kt
@@ -7,6 +7,7 @@ enum class DeviceUIState {
     PAIRED_POSITIVE_TELETAN,
     PAIRED_NEGATIVE,
     PAIRED_ERROR,
+    PAIRED_REDEEMED,
     SUBMITTED_INITIAL,
     SUBMITTED_FINAL
 }
diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/util/formatter/FormatterInformationLegalHelper.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/util/formatter/FormatterInformationLegalHelper.kt
new file mode 100644
index 0000000000000000000000000000000000000000..37d044477804d4b497eb449f1c12a9659aae53e2
--- /dev/null
+++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/util/formatter/FormatterInformationLegalHelper.kt
@@ -0,0 +1,34 @@
+@file:JvmName("FormatterInformationLegalHelper")
+
+package de.rki.coronawarnapp.util.formatter
+import android.view.View
+import java.util.Locale
+
+/**
+ * Language based format visibility
+ *
+ * @param defaultLanguageEnglishOrGerman
+ * @param isContactFormView
+ * @return
+ */
+fun formatVisibilityLanguageBased(defaultLanguageEnglishOrGerman: Boolean, isContactFormView: Boolean?): Int {
+    if (defaultLanguageEnglishOrGerman) {
+        return if (isContactFormView == true) {
+            View.VISIBLE
+        } else View.GONE
+    }
+    return if (isContactFormView == false) {
+        View.VISIBLE
+    } else View.GONE
+}
+
+/**
+ * checks the default language of the device and formats the visibility
+ * Returns visibility value
+ *
+ * @param isContactFormView
+ * @return
+ */
+fun formatContactForm(isContactFormView: Boolean?): Int =
+    formatVisibilityLanguageBased(Locale.getDefault().language == Locale.ENGLISH.language ||
+        Locale.getDefault().language == Locale.GERMAN.language, isContactFormView)
diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/util/formatter/FormatterSubmissionHelper.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/util/formatter/FormatterSubmissionHelper.kt
index 5d93578b11d500499650e901cb517d0b087e4cb7..fb6de1ec97bf660e2481d4512f269fd44966a962 100644
--- a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/util/formatter/FormatterSubmissionHelper.kt
+++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/util/formatter/FormatterSubmissionHelper.kt
@@ -64,7 +64,8 @@ fun formatTestResultCardContent(uiState: DeviceUIState?): Spannable {
     return when (uiState) {
         DeviceUIState.PAIRED_NO_RESULT ->
             SpannableString(appContext.getString(R.string.test_result_card_status_pending))
-        DeviceUIState.PAIRED_ERROR ->
+        DeviceUIState.PAIRED_ERROR,
+        DeviceUIState.PAIRED_REDEEMED ->
             SpannableString(appContext.getString(R.string.test_result_card_status_invalid))
 
         DeviceUIState.PAIRED_POSITIVE,
@@ -81,7 +82,8 @@ fun formatTestStatusIcon(uiState: DeviceUIState?): Drawable? {
         DeviceUIState.PAIRED_POSITIVE_TELETAN,
         DeviceUIState.PAIRED_POSITIVE -> appContext.getDrawable(R.drawable.ic_test_result_illustration_positive)
         DeviceUIState.PAIRED_NEGATIVE -> appContext.getDrawable(R.drawable.ic_test_result_illustration_negative)
-        DeviceUIState.PAIRED_ERROR -> appContext.getDrawable(R.drawable.ic_test_result_illustration_invalid)
+        DeviceUIState.PAIRED_ERROR,
+        DeviceUIState.PAIRED_REDEEMED -> appContext.getDrawable(R.drawable.ic_test_result_illustration_invalid)
         else -> appContext.getDrawable(R.drawable.ic_test_result_illustration_invalid)
     }
 }
@@ -102,13 +104,14 @@ fun formatTestResultPositiveStepsVisible(uiState: DeviceUIState?): Int =
     formatVisibility(uiState == DeviceUIState.PAIRED_POSITIVE || uiState == DeviceUIState.PAIRED_POSITIVE_TELETAN)
 
 fun formatTestResultInvalidStepsVisible(uiState: DeviceUIState?): Int =
-    formatVisibility(uiState == DeviceUIState.PAIRED_ERROR)
+    formatVisibility(uiState == DeviceUIState.PAIRED_ERROR || uiState == DeviceUIState.PAIRED_REDEEMED)
 
 fun formatSubmissionStatusCardSubtitleColor(uiState: DeviceUIState?): Int {
     val appContext = CoronaWarnApplication.getAppContext()
     return when (uiState) {
         DeviceUIState.PAIRED_NEGATIVE -> appContext.getColor(R.color.colorTextSemanticGreen)
-        DeviceUIState.PAIRED_ERROR -> appContext.getColor(R.color.colorTextSemanticNeutral)
+        DeviceUIState.PAIRED_ERROR,
+        DeviceUIState.PAIRED_REDEEMED -> appContext.getColor(R.color.colorTextSemanticNeutral)
         else -> appContext.getColor(R.color.colorTextPrimary1)
     }
 }
@@ -117,7 +120,8 @@ fun formatSubmissionStatusCardSubtitleText(uiState: DeviceUIState?): String {
     val appContext = CoronaWarnApplication.getAppContext()
     return when (uiState) {
         DeviceUIState.PAIRED_NEGATIVE -> appContext.getString(R.string.submission_status_card_subtitle_negative)
-        DeviceUIState.PAIRED_ERROR -> appContext.getString(R.string.submission_status_card_subtitle_invalid)
+        DeviceUIState.PAIRED_ERROR,
+        DeviceUIState.PAIRED_REDEEMED -> appContext.getString(R.string.submission_status_card_subtitle_invalid)
         else -> ""
     }
 }
@@ -126,6 +130,7 @@ fun formatSubmissionStatusCardContentTitleText(uiState: DeviceUIState?): String
     val appContext = CoronaWarnApplication.getAppContext()
     return when (uiState) {
         DeviceUIState.PAIRED_ERROR,
+        DeviceUIState.PAIRED_REDEEMED,
         DeviceUIState.PAIRED_NEGATIVE -> appContext.getString(R.string.submission_status_card_title_available)
         DeviceUIState.PAIRED_NO_RESULT -> appContext.getString(R.string.submission_status_card_title_pending)
         else -> appContext.getString(R.string.submission_status_card_title_pending)
@@ -135,7 +140,8 @@ fun formatSubmissionStatusCardContentTitleText(uiState: DeviceUIState?): String
 fun formatSubmissionStatusCardContentBodyText(uiState: DeviceUIState?): String {
     val appContext = CoronaWarnApplication.getAppContext()
     return when (uiState) {
-        DeviceUIState.PAIRED_ERROR -> appContext.getString(R.string.submission_status_card_body_invalid)
+        DeviceUIState.PAIRED_ERROR,
+        DeviceUIState.PAIRED_REDEEMED -> appContext.getString(R.string.submission_status_card_body_invalid)
         DeviceUIState.PAIRED_NEGATIVE -> appContext.getString(R.string.submission_status_card_body_negative)
         DeviceUIState.PAIRED_NO_RESULT -> appContext.getString(R.string.submission_status_card_body_pending)
         else -> appContext.getString(R.string.submission_status_card_body_pending)
@@ -145,6 +151,7 @@ fun formatSubmissionStatusCardContentBodyText(uiState: DeviceUIState?): String {
 fun formatSubmissionStatusCardContentStatusTextVisible(uiState: DeviceUIState?): Int {
     return when (uiState) {
         DeviceUIState.PAIRED_NEGATIVE,
+        DeviceUIState.PAIRED_REDEEMED,
         DeviceUIState.PAIRED_ERROR -> View.VISIBLE
         else -> View.GONE
     }
@@ -157,7 +164,8 @@ fun formatSubmissionStatusCardContentIcon(uiState: DeviceUIState?): Drawable? {
         DeviceUIState.PAIRED_POSITIVE,
         DeviceUIState.PAIRED_POSITIVE_TELETAN -> appContext.getDrawable(R.drawable.ic_main_illustration_pending)
         DeviceUIState.PAIRED_NEGATIVE -> appContext.getDrawable(R.drawable.ic_main_illustration_negative)
-        DeviceUIState.PAIRED_ERROR -> appContext.getDrawable(R.drawable.ic_main_illustration_invalid)
+        DeviceUIState.PAIRED_ERROR,
+        DeviceUIState.PAIRED_REDEEMED -> appContext.getDrawable(R.drawable.ic_main_illustration_invalid)
         else -> appContext.getDrawable(R.drawable.ic_main_illustration_invalid)
     }
 }
@@ -180,7 +188,8 @@ fun formatSubmissionStatusCardContentVisible(
 ): Int = formatVisibility(
     deviceUiState == DeviceUIState.PAIRED_ERROR ||
             deviceUiState == DeviceUIState.PAIRED_NEGATIVE ||
-            deviceUiState == DeviceUIState.PAIRED_NO_RESULT
+            deviceUiState == DeviceUIState.PAIRED_NO_RESULT ||
+            deviceUiState == DeviceUIState.PAIRED_REDEEMED
 )
 
 fun formatShowSubmissionStatusPositiveCard(deviceUiState: DeviceUIState?): Int =
diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/util/formatter/TestResult.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/util/formatter/TestResult.kt
index 31ec1a64d5ebf138836d478eff3a642000ee6ced..c0cacc40a79d73c32ce47d9f4863df2c6f8bc1e9 100644
--- a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/util/formatter/TestResult.kt
+++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/util/formatter/TestResult.kt
@@ -5,7 +5,8 @@ enum class TestResult(val value: Int) {
     PENDING(0),
     NEGATIVE(1),
     POSITIVE(2),
-    INVALID(3);
+    INVALID(3),
+    REDEEMED(4);
 
     companion object {
         fun fromInt(value: Int) = values().first { it.value == value }
diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/util/security/HashHelper.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/util/security/HashHelper.kt
new file mode 100644
index 0000000000000000000000000000000000000000..b0726ae7c3da2fa95e8265aecb96aa721c863d4c
--- /dev/null
+++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/util/security/HashHelper.kt
@@ -0,0 +1,10 @@
+package de.rki.coronawarnapp.util.security
+
+import java.security.MessageDigest
+
+object HashHelper {
+    fun hash256(input: String): String = MessageDigest
+        .getInstance(SecurityConstants.DIGEST_ALGORITHM)
+        .digest(input.toByteArray())
+        .fold("", { str, it -> str + "%02x".format(it) })
+}
diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/util/security/SecurityHelper.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/util/security/SecurityHelper.kt
index 3b77bc8a155e143224f993f053b3902308b91b52..57617a039fa614edb8e55de95dc972fbd5e085de 100644
--- a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/util/security/SecurityHelper.kt
+++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/util/security/SecurityHelper.kt
@@ -31,9 +31,7 @@ import de.rki.coronawarnapp.exception.CwaSecurityException
 import de.rki.coronawarnapp.util.security.SecurityConstants.CWA_APP_SQLITE_DB_PW
 import de.rki.coronawarnapp.util.security.SecurityConstants.DB_PASSWORD_MAX_LENGTH
 import de.rki.coronawarnapp.util.security.SecurityConstants.DB_PASSWORD_MIN_LENGTH
-import de.rki.coronawarnapp.util.security.SecurityConstants.DIGEST_ALGORITHM
 import de.rki.coronawarnapp.util.security.SecurityConstants.ENCRYPTED_SHARED_PREFERENCES_FILE
-import java.security.MessageDigest
 import java.security.SecureRandom
 
 /**
@@ -110,11 +108,6 @@ object SecurityHelper {
         return password
     }
 
-    fun hash256(input: String): String = MessageDigest
-        .getInstance(DIGEST_ALGORITHM)
-        .digest(input.toByteArray())
-        .fold("", { str, it -> str + "%02x".format(it) })
-
     fun <T> withSecurityCatch(doInCatch: () -> T) = try {
         doInCatch.invoke()
     } catch (e: Exception) {
diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/worker/BackgroundConstants.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/worker/BackgroundConstants.kt
index df62ad1ccc6a2565db759f2fd22daffad489a267..f15edf5567a084410d3accf8e9cd529b4f1a6d0a 100644
--- a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/worker/BackgroundConstants.kt
+++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/worker/BackgroundConstants.kt
@@ -24,6 +24,16 @@ object BackgroundConstants {
      */
     const val DIAGNOSIS_TEST_RESULT_PERIODIC_WORKER_TAG = "DIAGNOSIS_TEST_RESULT_PERIODIC_WORKER"
 
+    /**
+     * Tag for background noise playbook periodic work
+     */
+    const val BACKGROUND_NOISE_PERIODIC_WORKER_TAG = "BACKGROUND_NOISE_PERIODIC_WORKER"
+
+    /**
+     * Tag for background noise playbook one time work
+     */
+    const val BACKGROUND_NOISE_ONE_TIME_WORKER_TAG = "BACKGROUND_NOISE_PERIODIC_WORKER"
+
     /**
      * Unique name for diagnosis key retrieval one time work
      */
@@ -39,6 +49,16 @@ object BackgroundConstants {
      */
     const val DIAGNOSIS_TEST_RESULT_PERIODIC_WORK_NAME = "DiagnosisTestResultBackgroundPeriodicWork"
 
+    /**
+     * Unique name for background noise playbook periodic work
+     */
+    const val BACKGROUND_NOISE_PERIODIC_WORK_NAME = "BackgroundNoisePeriodicWork"
+
+    /**
+     * Unique name for background noise playbook one time work
+     */
+    const val BACKGROUND_NOISE_ONE_TIME_WORK_NAME = "BackgroundNoiseOneTimeWork"
+
     /**
      * Total minutes in one day
      */
@@ -94,4 +114,25 @@ object BackgroundConstants {
      * @see TimeUnit.MINUTES
      */
     const val BACKOFF_INITIAL_DELAY = 8L
+
+    /**
+     * The minimum time in hours to wait between playbook executions
+     *
+     * @see TimeUnit.HOURS
+     */
+    const val MIN_HOURS_TO_NEXT_BACKGROUND_NOISE_EXECUTION = 0L
+
+    /**
+     * The maximum time in hours to wait between playbook executions
+     *
+     * @see TimeUnit.HOURS
+     */
+    const val MAX_HOURS_TO_NEXT_BACKGROUND_NOISE_EXECUTION = 0L
+
+    /**
+     * The total time in days to run the playbook
+     *
+     * @see TimeUnit.DAYS
+     */
+    const val NUMBER_OF_DAYS_TO_RUN_PLAYBOOK = 0
 }
diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/worker/BackgroundNoiseOneTimeWorker.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/worker/BackgroundNoiseOneTimeWorker.kt
new file mode 100644
index 0000000000000000000000000000000000000000..87e9a8c551721e4ac8c1dec420ed2803dd313744
--- /dev/null
+++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/worker/BackgroundNoiseOneTimeWorker.kt
@@ -0,0 +1,46 @@
+package de.rki.coronawarnapp.worker
+
+import android.content.Context
+import androidx.work.CoroutineWorker
+import androidx.work.WorkerParameters
+import de.rki.coronawarnapp.http.WebRequestBuilder
+import de.rki.coronawarnapp.http.playbook.PlaybookImpl
+
+/**
+ * One time background noise worker
+ *
+ * @see BackgroundWorkScheduler
+ */
+class BackgroundNoiseOneTimeWorker(
+    val context: Context,
+    workerParams: WorkerParameters
+) :
+    CoroutineWorker(context, workerParams) {
+
+    companion object {
+        private val TAG: String? = BackgroundNoiseOneTimeWorker::class.simpleName
+    }
+
+    /**
+     * Work execution
+     *
+     * @return Result
+     */
+    override suspend fun doWork(): Result {
+        var result = Result.success()
+
+        try {
+            PlaybookImpl(WebRequestBuilder.getInstance())
+                .dummy()
+        } catch (e: Exception) {
+            // TODO: Should we even retry here?
+            result = if (runAttemptCount > BackgroundConstants.WORKER_RETRY_COUNT_THRESHOLD) {
+                Result.failure()
+            } else {
+                Result.retry()
+            }
+        }
+
+        return result
+    }
+}
diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/worker/BackgroundNoisePeriodicWorker.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/worker/BackgroundNoisePeriodicWorker.kt
new file mode 100644
index 0000000000000000000000000000000000000000..3b9a93eb9fd246d0fa4734e4100ac78fa9140a37
--- /dev/null
+++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/worker/BackgroundNoisePeriodicWorker.kt
@@ -0,0 +1,64 @@
+package de.rki.coronawarnapp.worker
+
+import android.content.Context
+import androidx.work.CoroutineWorker
+import androidx.work.WorkerParameters
+import de.rki.coronawarnapp.storage.LocalData
+import de.rki.coronawarnapp.worker.BackgroundWorkScheduler.stop
+import org.joda.time.DateTime
+import org.joda.time.DateTimeZone
+import timber.log.Timber
+
+/**
+ * Periodic background noise worker
+ *
+ * @see BackgroundWorkScheduler
+ */
+class BackgroundNoisePeriodicWorker(
+    val context: Context,
+    workerParams: WorkerParameters
+) :
+    CoroutineWorker(context, workerParams) {
+
+    companion object {
+        private val TAG: String? = BackgroundNoisePeriodicWorker::class.simpleName
+    }
+
+    /**
+     * Work execution
+     *
+     * @return Result
+     *
+     * @see BackgroundConstants.NUMBER_OF_DAYS_TO_RUN_PLAYBOOK
+     */
+    override suspend fun doWork(): Result {
+        Timber.d("Background job started. Run attempt: $runAttemptCount")
+
+        var result = Result.success()
+        try {
+            val initialPairingDate = DateTime(
+                LocalData.devicePairingSuccessfulTimestamp(),
+                DateTimeZone.UTC
+            )
+
+            // Check if the numberOfDaysToRunPlaybook are over
+            if (initialPairingDate.plusDays(BackgroundConstants.NUMBER_OF_DAYS_TO_RUN_PLAYBOOK).isBeforeNow) {
+                stopWorker()
+                return result
+            }
+
+            BackgroundWorkScheduler.scheduleBackgroundNoiseOneTimeWork()
+        } catch (e: Exception) {
+            result = if (runAttemptCount > BackgroundConstants.WORKER_RETRY_COUNT_THRESHOLD) {
+                Result.failure()
+            } else {
+                Result.retry()
+            }
+        }
+        return result
+    }
+
+    private fun stopWorker() {
+        BackgroundWorkScheduler.WorkType.BACKGROUND_NOISE_PERIODIC_WORK.stop()
+    }
+}
diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/worker/BackgroundWorkBuilder.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/worker/BackgroundWorkBuilder.kt
new file mode 100644
index 0000000000000000000000000000000000000000..4578ebaac7e5e5a775478b737e6d785c48113b03
--- /dev/null
+++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/worker/BackgroundWorkBuilder.kt
@@ -0,0 +1,137 @@
+package de.rki.coronawarnapp.worker
+
+import androidx.work.BackoffPolicy
+import androidx.work.OneTimeWorkRequestBuilder
+import androidx.work.PeriodicWorkRequestBuilder
+import de.rki.coronawarnapp.worker.BackgroundWorkScheduler.WorkTag
+import java.util.concurrent.TimeUnit
+
+/**
+ * Build diagnosis key periodic work request
+ * Set "kind delay" for accessibility reason.
+ * Backoff criteria set to Linear type.
+ *
+ * @return PeriodicWorkRequest
+ *
+ * @see WorkTag.DIAGNOSIS_KEY_RETRIEVAL_PERIODIC_WORKER
+ * @see BackgroundConstants.KIND_DELAY
+ * @see BackgroundConstants.BACKOFF_INITIAL_DELAY
+ * @see BackoffPolicy.LINEAR
+ */
+fun buildDiagnosisKeyRetrievalPeriodicWork() =
+    PeriodicWorkRequestBuilder<DiagnosisKeyRetrievalPeriodicWorker>(
+        BackgroundWorkHelper.getDiagnosisKeyRetrievalPeriodicWorkTimeInterval(), TimeUnit.MINUTES
+    )
+        .addTag(WorkTag.DIAGNOSIS_KEY_RETRIEVAL_PERIODIC_WORKER.tag)
+        .setInitialDelay(
+            BackgroundConstants.KIND_DELAY,
+            TimeUnit.MINUTES
+        )
+        .setBackoffCriteria(
+            BackoffPolicy.EXPONENTIAL,
+            BackgroundConstants.BACKOFF_INITIAL_DELAY,
+            TimeUnit.MINUTES
+        )
+        .build()
+
+/**
+ * Build diagnosis key one time work request
+ * Set random initial delay for security reason.
+ * Backoff criteria set to Linear type.
+ *
+ * @return OneTimeWorkRequest
+ *
+ * @see WorkTag.DIAGNOSIS_KEY_RETRIEVAL_ONE_TIME_WORKER
+ * @see buildDiagnosisKeyRetrievalOneTimeWork
+ * @see BackgroundConstants.BACKOFF_INITIAL_DELAY
+ * @see BackoffPolicy.LINEAR
+ */
+fun buildDiagnosisKeyRetrievalOneTimeWork() =
+    OneTimeWorkRequestBuilder<DiagnosisKeyRetrievalOneTimeWorker>()
+        .addTag(WorkTag.DIAGNOSIS_KEY_RETRIEVAL_ONE_TIME_WORKER.tag)
+        .setConstraints(BackgroundWorkHelper.getConstraintsForDiagnosisKeyOneTimeBackgroundWork())
+        .setInitialDelay(
+            BackgroundConstants.KIND_DELAY,
+            TimeUnit.MINUTES
+        )
+        .setBackoffCriteria(
+            BackoffPolicy.EXPONENTIAL,
+            BackgroundConstants.BACKOFF_INITIAL_DELAY,
+            TimeUnit.MINUTES
+        )
+        .build()
+
+/**
+ * Build diagnosis Test Result periodic work request
+ * Set "kind delay" for accessibility reason.
+ *
+ * @return PeriodicWorkRequest
+ *
+ * @see WorkTag.DIAGNOSIS_TEST_RESULT_RETRIEVAL_PERIODIC_WORKER
+ * @see BackgroundConstants.KIND_DELAY
+ */
+fun buildDiagnosisTestResultRetrievalPeriodicWork() =
+    PeriodicWorkRequestBuilder<DiagnosisTestResultRetrievalPeriodicWorker>(
+        BackgroundWorkHelper.getDiagnosisTestResultRetrievalPeriodicWorkTimeInterval(),
+        TimeUnit.MINUTES
+    )
+        .addTag(WorkTag.DIAGNOSIS_TEST_RESULT_RETRIEVAL_PERIODIC_WORKER.tag)
+        .setConstraints(BackgroundWorkHelper.getConstraintsForDiagnosisKeyOneTimeBackgroundWork())
+        .setInitialDelay(
+            BackgroundConstants.DIAGNOSIS_TEST_RESULT_PERIODIC_INITIAL_DELAY,
+            TimeUnit.SECONDS
+        ).setBackoffCriteria(
+            BackoffPolicy.LINEAR,
+            BackgroundConstants.KIND_DELAY,
+            TimeUnit.MINUTES
+        )
+        .build()
+
+/**
+ * Build background noise one time work request
+ * Set BackgroundNoiseOneTimeWorkDelay for timing randomness.
+ *
+ * @return PeriodicWorkRequest
+ *
+ * @see WorkTag.BACKGROUND_NOISE_ONE_TIME_WORKER
+ * @see BackgroundWorkHelper.getBackgroundNoiseOneTimeWorkDelay
+ */
+fun buildBackgroundNoiseOneTimeWork() =
+    OneTimeWorkRequestBuilder<BackgroundNoiseOneTimeWorker>()
+        .addTag(WorkTag.BACKGROUND_NOISE_ONE_TIME_WORKER.tag)
+        .setConstraints(BackgroundWorkHelper.getConstraintsForDiagnosisKeyOneTimeBackgroundWork())
+        .setInitialDelay(
+            BackgroundWorkHelper.getBackgroundNoiseOneTimeWorkDelay(),
+            TimeUnit.HOURS
+        ).setBackoffCriteria(
+            BackoffPolicy.LINEAR,
+            BackgroundConstants.KIND_DELAY,
+            TimeUnit.MINUTES
+        )
+        .build()
+
+/**
+ * Build background noise periodic work request
+ * Set "kind delay" for accessibility reason.
+ *
+ * @return PeriodicWorkRequest
+ *
+ * @see BackgroundConstants.MIN_HOURS_TO_NEXT_BACKGROUND_NOISE_EXECUTION
+ * @see WorkTag.BACKGROUND_NOISE_PERIODIC_WORKER
+ * @see BackgroundConstants.KIND_DELAY
+ */
+fun buildBackgroundNoisePeriodicWork() =
+    PeriodicWorkRequestBuilder<BackgroundNoisePeriodicWorker>(
+        BackgroundConstants.MIN_HOURS_TO_NEXT_BACKGROUND_NOISE_EXECUTION,
+        TimeUnit.HOURS
+    )
+        .addTag(WorkTag.BACKGROUND_NOISE_PERIODIC_WORKER.tag)
+        .setInitialDelay(
+            BackgroundConstants.KIND_DELAY,
+            TimeUnit.SECONDS
+        ).setBackoffCriteria(
+            BackoffPolicy.LINEAR,
+            BackgroundConstants.KIND_DELAY,
+            TimeUnit.MINUTES
+        )
+        .build()
diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/worker/BackgroundWorkHelper.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/worker/BackgroundWorkHelper.kt
index ddaac2c8a35b93de0f6230c5bab730219c152dde..c7e797fa3a075a6cfb7cded9f63f8058533aa00c 100644
--- a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/worker/BackgroundWorkHelper.kt
+++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/worker/BackgroundWorkHelper.kt
@@ -5,6 +5,7 @@ import androidx.work.Constraints
 import androidx.work.NetworkType
 import de.rki.coronawarnapp.notification.NotificationHelper
 import de.rki.coronawarnapp.storage.LocalData
+import kotlin.random.Random
 
 /**
  * Singleton class for background work helper functions
@@ -49,6 +50,22 @@ object BackgroundWorkHelper {
         BackgroundConstants.DIAGNOSIS_KEY_RETRIEVAL_TRIES_PER_DAY
             .coerceAtMost(BackgroundConstants.GOOGLE_API_MAX_CALLS_PER_DAY)
 
+    /**
+     * Get background noise one time work delay
+     * The periodic job is already delayed by MIN_HOURS_TO_NEXT_BACKGROUND_NOISE_EXECUTION
+     * so we only need to delay further by the difference between min and max.
+     *
+     * @return Long
+     *
+     * @see BackgroundConstants.MAX_HOURS_TO_NEXT_BACKGROUND_NOISE_EXECUTION
+     * @see BackgroundConstants.MIN_HOURS_TO_NEXT_BACKGROUND_NOISE_EXECUTION
+     */
+    fun getBackgroundNoiseOneTimeWorkDelay() = Random.nextLong(
+        0,
+        BackgroundConstants.MAX_HOURS_TO_NEXT_BACKGROUND_NOISE_EXECUTION -
+                BackgroundConstants.MIN_HOURS_TO_NEXT_BACKGROUND_NOISE_EXECUTION
+    )
+
     /**
      * Constraints for diagnosis key one time work
      * Requires battery not low and any network connection
diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/worker/BackgroundWorkScheduler.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/worker/BackgroundWorkScheduler.kt
index 02a7c2e7c53ae2bbab0dbdc1c7638fcf55e59a4c..51ca8ea55de10fe99bcc1a1abe0ba87a9932df66 100644
--- a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/worker/BackgroundWorkScheduler.kt
+++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/worker/BackgroundWorkScheduler.kt
@@ -1,19 +1,15 @@
 package de.rki.coronawarnapp.worker
 
-import androidx.work.BackoffPolicy
 import androidx.work.ExistingPeriodicWorkPolicy
 import androidx.work.ExistingWorkPolicy
-import androidx.work.OneTimeWorkRequestBuilder
 import androidx.work.Operation
-import androidx.work.PeriodicWorkRequestBuilder
-import androidx.work.WorkInfo
 import androidx.work.WorkManager
+import androidx.work.WorkInfo
 import de.rki.coronawarnapp.BuildConfig
 import de.rki.coronawarnapp.CoronaWarnApplication
 import de.rki.coronawarnapp.storage.LocalData
 import timber.log.Timber
 import java.util.concurrent.ExecutionException
-import java.util.concurrent.TimeUnit
 
 /**
  * Singleton class for background work handling
@@ -32,11 +28,15 @@ object BackgroundWorkScheduler {
      * @see BackgroundConstants.DIAGNOSIS_KEY_ONE_TIME_WORKER_TAG
      * @see BackgroundConstants.DIAGNOSIS_KEY_PERIODIC_WORKER_TAG
      * @see BackgroundConstants.DIAGNOSIS_TEST_RESULT_PERIODIC_WORKER_TAG
+     * @see BackgroundConstants.BACKGROUND_NOISE_ONE_TIME_WORKER_TAG
+     * @see BackgroundConstants.BACKGROUND_NOISE_PERIODIC_WORKER_TAG
      */
     enum class WorkTag(val tag: String) {
         DIAGNOSIS_KEY_RETRIEVAL_ONE_TIME_WORKER(BackgroundConstants.DIAGNOSIS_KEY_ONE_TIME_WORKER_TAG),
         DIAGNOSIS_KEY_RETRIEVAL_PERIODIC_WORKER(BackgroundConstants.DIAGNOSIS_KEY_PERIODIC_WORKER_TAG),
-        DIAGNOSIS_TEST_RESULT_RETRIEVAL_PERIODIC_WORKER(BackgroundConstants.DIAGNOSIS_TEST_RESULT_PERIODIC_WORKER_TAG)
+        DIAGNOSIS_TEST_RESULT_RETRIEVAL_PERIODIC_WORKER(BackgroundConstants.DIAGNOSIS_TEST_RESULT_PERIODIC_WORKER_TAG),
+        BACKGROUND_NOISE_ONE_TIME_WORKER(BackgroundConstants.BACKGROUND_NOISE_ONE_TIME_WORKER_TAG),
+        BACKGROUND_NOISE_PERIODIC_WORKER(BackgroundConstants.BACKGROUND_NOISE_PERIODIC_WORKER_TAG)
     }
 
     /**
@@ -47,11 +47,15 @@ object BackgroundWorkScheduler {
      * @see BackgroundConstants.DIAGNOSIS_KEY_ONE_TIME_WORK_NAME
      * @see BackgroundConstants.DIAGNOSIS_KEY_PERIODIC_WORK_NAME
      * @see BackgroundConstants.DIAGNOSIS_TEST_RESULT_PERIODIC_WORK_NAME
+     * @see BackgroundConstants.BACKGROUND_NOISE_PERIODIC_WORK_NAME
+     * @see BackgroundConstants.BACKGROUND_NOISE_ONE_TIME_WORK_NAME
      */
     enum class WorkType(val uniqueName: String) {
         DIAGNOSIS_KEY_BACKGROUND_ONE_TIME_WORK(BackgroundConstants.DIAGNOSIS_KEY_ONE_TIME_WORK_NAME),
         DIAGNOSIS_KEY_BACKGROUND_PERIODIC_WORK(BackgroundConstants.DIAGNOSIS_KEY_PERIODIC_WORK_NAME),
-        DIAGNOSIS_TEST_RESULT_PERIODIC_WORKER(BackgroundConstants.DIAGNOSIS_TEST_RESULT_PERIODIC_WORK_NAME)
+        DIAGNOSIS_TEST_RESULT_PERIODIC_WORKER(BackgroundConstants.DIAGNOSIS_TEST_RESULT_PERIODIC_WORK_NAME),
+        BACKGROUND_NOISE_PERIODIC_WORK(BackgroundConstants.BACKGROUND_NOISE_PERIODIC_WORK_NAME),
+        BACKGROUND_NOISE_ONE_TIME_WORK(BackgroundConstants.BACKGROUND_NOISE_ONE_TIME_WORK_NAME)
     }
 
     /**
@@ -162,6 +166,24 @@ object BackgroundWorkScheduler {
         WorkType.DIAGNOSIS_KEY_BACKGROUND_ONE_TIME_WORK.start()
     }
 
+    /**
+     * Schedule background noise periodic work
+     *
+     * @see WorkType.BACKGROUND_NOISE_PERIODIC_WORK
+     */
+    fun scheduleBackgroundNoisePeriodicWork() {
+        WorkType.BACKGROUND_NOISE_PERIODIC_WORK.start()
+    }
+
+    /**
+     * Schedule background noise one time work
+     *
+     * @see WorkType.DIAGNOSIS_KEY_BACKGROUND_ONE_TIME_WORK
+     */
+    fun scheduleBackgroundNoiseOneTimeWork() {
+        WorkType.DIAGNOSIS_KEY_BACKGROUND_ONE_TIME_WORK.start()
+    }
+
     /**
      * Enqueue operation for work type defined in WorkType enum class
      *
@@ -173,6 +195,8 @@ object BackgroundWorkScheduler {
         WorkType.DIAGNOSIS_KEY_BACKGROUND_PERIODIC_WORK -> enqueueDiagnosisKeyBackgroundPeriodicWork()
         WorkType.DIAGNOSIS_KEY_BACKGROUND_ONE_TIME_WORK -> enqueueDiagnosisKeyBackgroundOneTimeWork()
         WorkType.DIAGNOSIS_TEST_RESULT_PERIODIC_WORKER -> enqueueDiagnosisTestResultBackgroundPeriodicWork()
+        WorkType.BACKGROUND_NOISE_PERIODIC_WORK -> enqueueBackgroundNoisePeriodicWork()
+        WorkType.BACKGROUND_NOISE_ONE_TIME_WORK -> enqueueBackgroundNoiseOneTimeWork()
     }
 
     /**
@@ -220,84 +244,34 @@ object BackgroundWorkScheduler {
         ).also { it.logOperationSchedule(WorkType.DIAGNOSIS_TEST_RESULT_PERIODIC_WORKER) }
 
     /**
-     * Build diagnosis key periodic work request
-     * Set "kind delay" for accessibility reason.
-     * Backoff criteria set to Linear type.
-     *
-     * @return PeriodicWorkRequest
-     *
-     * @see WorkTag.DIAGNOSIS_KEY_RETRIEVAL_PERIODIC_WORKER
-     * @see BackgroundConstants.KIND_DELAY
-     * @see BackgroundConstants.BACKOFF_INITIAL_DELAY
-     * @see BackoffPolicy.LINEAR
-     */
-    private fun buildDiagnosisKeyRetrievalPeriodicWork() =
-        PeriodicWorkRequestBuilder<DiagnosisKeyRetrievalPeriodicWorker>(
-            BackgroundWorkHelper.getDiagnosisKeyRetrievalPeriodicWorkTimeInterval(), TimeUnit.MINUTES
-        )
-            .addTag(WorkTag.DIAGNOSIS_KEY_RETRIEVAL_PERIODIC_WORKER.tag)
-            .setInitialDelay(
-                BackgroundConstants.KIND_DELAY,
-                TimeUnit.MINUTES
-            )
-            .setBackoffCriteria(
-                BackoffPolicy.EXPONENTIAL,
-                BackgroundConstants.BACKOFF_INITIAL_DELAY,
-                TimeUnit.MINUTES
-            )
-            .build()
-
-    /**
-     * Build diagnosis key one time work request
-     * Set random initial delay for security reason.
-     * Backoff criteria set to Linear type.
+     * Enqueue background noise periodic
+     * Replace with new if older work exists.
      *
-     * @return OneTimeWorkRequest
+     * @return Operation
      *
-     * @see WorkTag.DIAGNOSIS_KEY_RETRIEVAL_ONE_TIME_WORKER
-     * @see buildDiagnosisKeyRetrievalOneTimeWork
-     * @see BackgroundConstants.BACKOFF_INITIAL_DELAY
-     * @see BackoffPolicy.LINEAR
+     * @see WorkType.BACKGROUND_NOISE_PERIODIC_WORK
      */
-    private fun buildDiagnosisKeyRetrievalOneTimeWork() =
-        OneTimeWorkRequestBuilder<DiagnosisKeyRetrievalOneTimeWorker>()
-            .addTag(WorkTag.DIAGNOSIS_KEY_RETRIEVAL_ONE_TIME_WORKER.tag)
-            .setConstraints(BackgroundWorkHelper.getConstraintsForDiagnosisKeyOneTimeBackgroundWork())
-            .setInitialDelay(
-                BackgroundConstants.KIND_DELAY,
-                TimeUnit.MINUTES
-            )
-            .setBackoffCriteria(
-                BackoffPolicy.EXPONENTIAL,
-                BackgroundConstants.BACKOFF_INITIAL_DELAY,
-                TimeUnit.MINUTES
-            )
-            .build()
+    private fun enqueueBackgroundNoisePeriodicWork() =
+        workManager.enqueueUniquePeriodicWork(
+            WorkType.BACKGROUND_NOISE_PERIODIC_WORK.uniqueName,
+            ExistingPeriodicWorkPolicy.REPLACE,
+            buildBackgroundNoisePeriodicWork()
+        ).also { it.logOperationSchedule(WorkType.BACKGROUND_NOISE_PERIODIC_WORK) }
 
     /**
-     * Build diagnosis Test Result periodic work request
-     * Set "kind delay" for accessibility reason.
+     * Enqueue background noise one time
+     * Replace with new if older work exists.
      *
-     * @return PeriodicWorkRequest
+     * @return Operation
      *
-     * @see WorkTag.DIAGNOSIS_TEST_RESULT_RETRIEVAL_PERIODIC_WORKER
-     * @see BackgroundConstants.KIND_DELAY
+     * @see WorkType.BACKGROUND_NOISE_ONE_TIME_WORK
      */
-    private fun buildDiagnosisTestResultRetrievalPeriodicWork() =
-        PeriodicWorkRequestBuilder<DiagnosisTestResultRetrievalPeriodicWorker>(
-            BackgroundWorkHelper.getDiagnosisTestResultRetrievalPeriodicWorkTimeInterval(), TimeUnit.MINUTES
-        )
-            .addTag(WorkTag.DIAGNOSIS_TEST_RESULT_RETRIEVAL_PERIODIC_WORKER.tag)
-            .setConstraints(BackgroundWorkHelper.getConstraintsForDiagnosisKeyOneTimeBackgroundWork())
-            .setInitialDelay(
-                BackgroundConstants.DIAGNOSIS_TEST_RESULT_PERIODIC_INITIAL_DELAY,
-                TimeUnit.SECONDS
-            ).setBackoffCriteria(
-                BackoffPolicy.LINEAR,
-                BackgroundConstants.KIND_DELAY,
-                TimeUnit.MINUTES
-            )
-            .build()
+    private fun enqueueBackgroundNoiseOneTimeWork() =
+        workManager.enqueueUniqueWork(
+            WorkType.BACKGROUND_NOISE_ONE_TIME_WORK.uniqueName,
+            ExistingWorkPolicy.REPLACE,
+            buildBackgroundNoiseOneTimeWork()
+        ).also { it.logOperationSchedule(WorkType.BACKGROUND_NOISE_ONE_TIME_WORK) }
 
     /**
      * Log operation schedule
diff --git a/Corona-Warn-App/src/main/res/layout/fragment_information_about.xml b/Corona-Warn-App/src/main/res/layout/fragment_information_about.xml
index b2f48c1a246f3d223aa4061ab8c3670edd9a12c5..5d5c89cfd12d23814ea839799d974a5d7c4c860d 100644
--- a/Corona-Warn-App/src/main/res/layout/fragment_information_about.xml
+++ b/Corona-Warn-App/src/main/res/layout/fragment_information_about.xml
@@ -69,6 +69,22 @@
                     app:layout_constraintStart_toEndOf="@+id/guideline_start"
                     app:layout_constraintTop_toBottomOf="@+id/information_about_body_emphasized" />
 
+                <TextView
+                    android:id="@+id/information_about_easy_language"
+                    style="@style/subtitle"
+                    android:layout_width="0dp"
+                    android:layout_height="wrap_content"
+                    android:layout_marginTop="@dimen/spacing_normal"
+                    android:clickable="true"
+                    android:focusable="true"
+                    android:linksClickable="true"
+                    android:textColorLink="@color/colorTextTint"
+                    android:text="@string/onboarding_tracing_easy_language_explanation"
+                    app:layout_constraintEnd_toEndOf="@id/guideline_end"
+                    app:layout_constraintHorizontal_bias="1.0"
+                    app:layout_constraintStart_toStartOf="@id/guideline_start"
+                    app:layout_constraintTop_toBottomOf="@id/information_about_body" />
+
                 <androidx.constraintlayout.widget.Guideline
                     android:id="@+id/guideline_start"
                     android:layout_width="wrap_content"
diff --git a/Corona-Warn-App/src/main/res/layout/fragment_information_legal.xml b/Corona-Warn-App/src/main/res/layout/fragment_information_legal.xml
index ceace17bfb5a0c8e8abbd04da7f585a591fe0860..0cbf75aee7fb813758e3e63bd205846e35624a36 100644
--- a/Corona-Warn-App/src/main/res/layout/fragment_information_legal.xml
+++ b/Corona-Warn-App/src/main/res/layout/fragment_information_legal.xml
@@ -105,6 +105,15 @@
                     app:layout_constraintStart_toEndOf="@+id/guideline_start"
                     app:layout_constraintTop_toBottomOf="@+id/information_legal_headline_contact" />
 
+                <include
+                    android:id="@+id/information_legal_contact_form"
+                    layout="@layout/include_contact_form"
+                    android:layout_width="@dimen/match_constraint"
+                    android:layout_height="wrap_content"
+                    app:layout_constraintEnd_toStartOf="@+id/guideline_end"
+                    app:layout_constraintStart_toEndOf="@+id/guideline_start"
+                    app:layout_constraintTop_toBottomOf="@+id/information_legal_subtitle_contact" />
+
                 <include
                     android:id="@+id/information_legal_divider_taxid"
                     layout="@layout/include_divider"
@@ -113,7 +122,7 @@
                     android:layout_marginTop="@dimen/spacing_medium"
                     app:layout_constraintEnd_toEndOf="@+id/guideline_end"
                     app:layout_constraintStart_toStartOf="@+id/guideline_start"
-                    app:layout_constraintTop_toBottomOf="@+id/information_legal_subtitle_contact" />
+                    app:layout_constraintTop_toBottomOf="@+id/information_legal_contact_form" />
 
                 <TextView
                     android:id="@+id/information_legal_headline_taxid"
diff --git a/Corona-Warn-App/src/main/res/layout/fragment_onboarding.xml b/Corona-Warn-App/src/main/res/layout/fragment_onboarding.xml
index 1f778ffbca13adb3eaa0da6e5be82818f5626a07..e3a0f118607410b3ee6faf962bfde0b53bd4e77e 100644
--- a/Corona-Warn-App/src/main/res/layout/fragment_onboarding.xml
+++ b/Corona-Warn-App/src/main/res/layout/fragment_onboarding.xml
@@ -12,6 +12,7 @@
         tools:context="de.rki.coronawarnapp.ui.onboarding.OnboardingFragment">
 
         <include
+            android:id="@+id/onboarding_include"
             layout="@layout/include_onboarding"
             android:layout_width="0dp"
             android:layout_height="0dp"
@@ -20,6 +21,7 @@
             app:body="@{@string/onboarding_body}"
             app:bodyEmphasized="@{@string/onboarding_body_emphasized}"
             app:headline="@{@string/onboarding_headline}"
+            app:easyLanguageText="@{@string/onboarding_tracing_easy_language_explanation}"
             app:illustration="@{@drawable/ic_illustration_together}"
             app:illustrationDescription="@{@string/onboarding_illustration_description}"
             app:layout_constraintBottom_toTopOf="@+id/onboarding_button_next"
diff --git a/Corona-Warn-App/src/main/res/layout/include_contact_form.xml b/Corona-Warn-App/src/main/res/layout/include_contact_form.xml
new file mode 100644
index 0000000000000000000000000000000000000000..3369e7d09b226bca0af4011564fac16a261fdb63
--- /dev/null
+++ b/Corona-Warn-App/src/main/res/layout/include_contact_form.xml
@@ -0,0 +1,53 @@
+<?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>
+
+        <import type="de.rki.coronawarnapp.util.formatter.FormatterInformationLegalHelper" />
+
+        <import type="de.rki.coronawarnapp.util.formatter.FormatterHelper" />
+    </data>
+
+    <androidx.constraintlayout.widget.ConstraintLayout
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content">
+
+        <androidx.constraintlayout.widget.ConstraintLayout
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            app:layout_constraintTop_toTopOf="parent">
+
+            <TextView
+                android:id="@+id/information_legal_contact_form"
+                style="@style/subtitle"
+                android:layout_width="0dp"
+                android:layout_height="wrap_content"
+                android:clickable="true"
+                android:focusable="true"
+                android:linksClickable="true"
+                android:text="@string/information_legal_subtitle_contact_form"
+                android:textColorLink="@color/colorTextTint"
+                android:visibility="@{FormatterInformationLegalHelper.formatContactForm(true)}"
+                app:layout_constraintStart_toStartOf="parent"
+                app:layout_constraintTop_toTopOf="parent" />
+
+            <TextView
+                android:id="@+id/information_legal_contact_form_non_en_de"
+                style="@style/subtitle"
+                android:layout_width="0dp"
+                android:layout_height="wrap_content"
+                android:clickable="true"
+                android:focusable="true"
+                android:linksClickable="true"
+                android:text="@string/information_legal_subtitle_contact_form_non_en_de"
+                android:textColorLink="@color/colorTextTint"
+                android:visibility="@{FormatterInformationLegalHelper.formatContactForm(false)}"
+                app:layout_constraintBottom_toBottomOf="parent"
+                app:layout_constraintStart_toStartOf="parent"
+                app:layout_constraintTop_toBottomOf="@+id/information_legal_contact_form" />
+
+        </androidx.constraintlayout.widget.ConstraintLayout>
+    </androidx.constraintlayout.widget.ConstraintLayout>
+
+</layout>
\ No newline at end of file
diff --git a/Corona-Warn-App/src/main/res/layout/include_onboarding.xml b/Corona-Warn-App/src/main/res/layout/include_onboarding.xml
index 9a3fe133c68c1a6d16034e7254d091e091404eb5..2998539b56c537297ca6177c1514f32c5ec81d71 100644
--- a/Corona-Warn-App/src/main/res/layout/include_onboarding.xml
+++ b/Corona-Warn-App/src/main/res/layout/include_onboarding.xml
@@ -53,6 +53,10 @@
             name="locationBodyCard"
             type="String" />
 
+        <variable
+            name="easyLanguageText"
+            type="String" />
+
     </data>
 
     <ScrollView
@@ -130,6 +134,23 @@
                 app:layout_constraintTop_toBottomOf="@id/onboarding_body"
                 tools:text="@string/onboarding_body_emphasized" />
 
+            <TextView
+                android:id="@+id/onboarding_easy_language"
+                style="@style/subtitle"
+                android:layout_width="0dp"
+                android:layout_height="wrap_content"
+                android:layout_marginTop="@dimen/spacing_normal"
+                android:clickable="true"
+                android:focusable="true"
+                android:linksClickable="true"
+                android:textColorLink="@color/colorTextTint"
+                android:text="@string/onboarding_tracing_easy_language_explanation"
+                android:visibility="@{FormatterHelper.formatVisibilityText(easyLanguageText)}"
+                app:layout_constraintEnd_toEndOf="@id/guideline_end"
+                app:layout_constraintStart_toStartOf="@id/guideline_start"
+                app:layout_constraintTop_toBottomOf="@id/onboarding_body_emphasized"
+                tools:text="@string/onboarding_tracing_easy_language_explanation" />
+
             <include
                 android:id="@+id/onboarding_location_card"
                 layout="@layout/include_tracing_status_card"
@@ -143,7 +164,7 @@
                 app:icon="@{locationIconCard}"
                 app:layout_constraintEnd_toStartOf="@+id/guideline_card_end"
                 app:layout_constraintStart_toStartOf="@+id/guideline_card_start"
-                app:layout_constraintTop_toBottomOf="@+id/onboarding_body_emphasized" />
+                app:layout_constraintTop_toBottomOf="@+id/onboarding_easy_language" />
 
             <include
                 android:id="@+id/onboarding_card"
diff --git a/Corona-Warn-App/src/main/res/values-bg/strings.xml b/Corona-Warn-App/src/main/res/values-bg/strings.xml
index f631780c7148dfd5f1c12d8c58f89fff014429e9..eb6b2895c4725b010be116a9a6023df5422f564f 100644
--- a/Corona-Warn-App/src/main/res/values-bg/strings.xml
+++ b/Corona-Warn-App/src/main/res/values-bg/strings.xml
@@ -163,6 +163,8 @@
     <string name="risk_card_body_time_fetched">"Актуализирано: %1$s"</string>
     <!-- XTXT: risk card - next update -->
     <string name="risk_card_body_next_update">"Ежедневно актуализиране"</string>
+    <!-- XTXT: risk card - hint to open the app daily -->
+    <string name="risk_card_body_open_daily">"Бележка: Моля, отваряйте приложението всеки ден, за да актуализирате своя статус на риск."</string>
     <!-- XBUT: risk card - update risk -->
     <string name="risk_card_button_update">"Актуализиране"</string>
     <!-- XBUT: risk card - update risk with time display -->
@@ -274,7 +276,7 @@
     <!-- XHED: App overview subtitle for glossary contact  -->
     <string name="main_overview_subtitle_glossary_contact">"Излагания на риск"</string>
     <!-- YTXT: App overview body for glossary contact -->
-    <string name="main_overview_body_glossary_contact">"Контакти с по-голяма продължителност и близост до лица, диагностицирани с COVID-19."</string>
+    <string name="main_overview_body_glossary_contact">"Продължителни и близки контакти с лица, диагностицирани с COVID-19."</string>
     <!-- XHED: App overview subtitle for glossary notifications -->
     <string name="main_overview_subtitle_glossary_notification">"Известия за излагане на риск"</string>
     <!-- YTXT: App overview body for glossary notifications -->
@@ -303,7 +305,7 @@
     <!-- XMSG: risk details - get in touch with the corresponding people, something like a bullet point -->
     <string name="risk_details_behavior_body_contact_doctor">"Ако имате въпроси относно симптомите, възможностите за тестване или самоизолацията, се обърнете към:"</string>
     <!-- XMSG: risk details - wash your hands, something like a bullet point -->
-    <string name="risk_details_behavior_body_wash_hands">"Мийте ръцете си редовно."</string>
+    <string name="risk_details_behavior_body_wash_hands">"Мийте редовно ръцете си със сапун в продължение на 20 сек."</string>
     <!-- XMSG: risk details - wear a face mask, something like a bullet point -->
     <string name="risk_details_behavior_body_wear_mask">"Носете маска при контакт с други хора."</string>
     <!-- XMSG: risk details - stay 1,5 away, something like a bullet point -->
@@ -403,11 +405,13 @@
     <!-- XHED: onboarding(tracing) - how to enable tracing -->
     <string name="onboarding_tracing_headline">"Как да активирате регистрирането на излагания на риск"</string>
     <!-- XHED: onboarding(tracing) - two/three line headline under an illustration -->
-    <string name="onboarding_tracing_subtitle">"За да установите дали за Вас съществува риск от заразяване, трябва да активирате функцията за регистриране на излагания на риск."</string>
+    <string name="onboarding_tracing_subtitle">"За да установите дали сте застрашени от заразяване, трябва да активирате функцията за регистриране на излагания на риск."</string>
     <!-- YTXT: onboarding(tracing) - explain tracing -->
     <string name="onboarding_tracing_body">"Регистрирането на излагания на риск се извършва с помощта на Bluetooth връзка, при която Вашето устройство получава криптираните случайни ИД кодове на други потребители и изпраща до техните устройства Вашите случайни ИД кодове. Функцията може да бъде дезактивирана по всяко време."</string>
     <!-- YTXT: onboarding(tracing) - explain tracing -->
     <string name="onboarding_tracing_body_emphasized">"Криптираните случайни ИД кодове предават само информация за дата, продължителност и близост на контакта с други лица (посредством силата на сигнала). Лични данни от типа на име, адрес и местоположение не се записват и идентифицирането на лицата е невъзможно."</string>
+    <!-- YTXT: onboarding(tracing) - easy language explain tracing link-->
+    <string name="onboarding_tracing_easy_language_explanation"><a href="https://www.bundesregierung.de/breg-de/themen/corona-warn-app/corona-warn-app-leichte-sprache-gebaerdensprache">"Информация за приложението на опростен и жестомимичен език."</a></string>
     <!-- XHED: onboarding(tracing) - headline for consent information -->
     <string name="onboarding_tracing_headline_consent">"Поверителност"</string>
     <!-- YTXT: onboarding(tracing) - body for consent information -->
@@ -564,7 +568,7 @@
     <!-- XTXT: settings(notification) - next to a switch -->
     <string name="settings_notifications_subtitle_update_risk">"Промяна на Вашия риск от заразяване"</string>
     <!-- XTXT: settings(notification) - next to a switch -->
-    <string name="settings_notifications_subtitle_update_test">"Статус на Вашия тест за COVID-19"</string>
+    <string name="settings_notifications_subtitle_update_test">"Наличие на резултат от Ваш тест за COVID-19"</string>
     <!-- XBUT: settings(notification) - go to operating settings -->
     <string name="settings_notifications_button_open_settings">"Към настройките за устройството"</string>
     <!-- XACT: main (overview) - illustraction description, explanation image, displays notificatin status, active -->
@@ -687,7 +691,11 @@
     <!-- XHED: Headline for legal information page, contact section -->
     <string name="information_legal_headline_contact">"Контакт"</string>
     <!-- YTXT: subtitle for legal information page, contact section -->
-    <string name="information_legal_subtitle_contact">"Имейл: CoronaWarnApp@rki.de"<xliff:g id="line_break">"\n"</xliff:g>"Телефон: +49 30 18754 5100"</string>
+    <string name="information_legal_subtitle_contact">"Имейл: CoronaWarnApp@rki.de"</string>
+    <!-- YTXT: subtitle for legal information page, open contact form -->
+    <string name="information_legal_subtitle_contact_form"><a href="https://www.rki.de/SharedDocs/Kontaktformulare/weitere/Corona-Warn-App/Corona-Warn-App_Integrator.html">"Формуляр за контакт"</a></string>
+    <!-- NOTR: subtitle for legal information page, open contact form for languages other than English and German -->
+    <string name="information_legal_subtitle_contact_form_non_en_de">"Contact Form in "<a href="https://www.rki.de/SharedDocs/Kontaktformulare/en/Kontaktformulare/weitere/Corona-Warn-App/Corona-Warn-App_Integrator.html">"English"</a>" or "<a href="https://www.rki.de/SharedDocs/Kontaktformulare/weitere/Corona-Warn-App/Corona-Warn-App_Integrator.html">"German"</a></string>
     <!-- XHED: Headline for legal information page, tax section -->
     <string name="information_legal_headline_taxid">"Идентификационен номер за ДДС"</string>
     <!-- YTXT: subtitle for legal information page, tax section -->
@@ -730,6 +738,13 @@
     <!-- XBUT: Positive button for submission tan invalid -->
     <string name="submission_error_dialog_web_tan_invalid_button_positive">"Назад"</string>
 
+    <!-- XHED: Dialog title for submission tan redeemed -->
+    <string name="submission_error_dialog_web_tan_redeemed_title">"Грешки в теста"</string>
+    <!-- XMSG: Dialog body for submission tan redeemed -->
+    <string name="submission_error_dialog_web_tan_redeemed_body">"Възникнаха грешки при проверката на Вашия тест. Този QR код вече е изтекъл."</string>
+    <!-- XBUT: Positive button for submission tan redeemed -->
+    <string name="submission_error_dialog_web_tan_redeemed_button_positive">"OK"</string>
+
     <!-- Permission Rationale Dialog -->
     <!-- XHED: Dialog headline QR Scan permission rationale  -->
     <string name="submission_qr_code_scan_permission_rationale_dialog_headline">"Изисква се разрешение за използване на камерата"</string>
@@ -750,9 +765,9 @@
 
     <!-- QR Code Scan Invalid Dialog -->
     <!-- XHED: Dialog headline for invalid QR code  -->
-    <string name="submission_qr_code_scan_invalid_dialog_headline">"Неправилен QR код"</string>
+    <string name="submission_qr_code_scan_invalid_dialog_headline">"Невалиден QR код"</string>
     <!-- YTXT: Dialog Body text for invalid QR code -->
-    <string name="submission_qr_code_scan_invalid_dialog_body">"QR кодът е неправилен. Моля, опитайте отново по-късно."</string>
+    <string name="submission_qr_code_scan_invalid_dialog_body">"QR кодът е невалиден или вече е регистриран на друг смартфон. Ще получите резултата си от център за тестване или лаборатория, независимо от валидността на QR кода. Ако Ви бъде поставена диагноза COVID-19, службата за обществено осигуряване ще Ви уведоми за това."</string>
     <!-- XBUT: Dialog(Invalid QR code) - positive button (right) -->
     <string name="submission_qr_code_scan_invalid_dialog_button_positive">"Моля, опитайте отново."</string>
     <!-- XBUT: Dialog(Invalid QR code) - negative button (left) -->
@@ -765,7 +780,7 @@
 
     <!-- Submission Test Result -->
     <!-- XHED: Page headline for test result  -->
-    <string name="submission_test_result_headline">"Резултат от теста"</string>
+    <string name="submission_test_result_headline">"Резултат от тест"</string>
     <!-- XHED: Page subheadline for test result  -->
     <string name="submission_test_result_subtitle">"Как работи:"</string>
     <!-- XHED: Page headline for results next steps  -->
@@ -799,7 +814,7 @@
     <!-- XHED: Page headline for invalid test result screen  -->
     <string name="submission_test_result_invalid_steps_invalid_heading">"Резултатът от Вашия тест"</string>
     <!-- YTXT: Body text for next steps section of invalid test result-->
-    <string name="submission_test_result_invalid_steps_invalid_body">"Възникна проблем при определянето на резултата от Вашия тест. Моля, свържете се с местната служба за обществено здравеопазване (Gesundheitsamt), за да получите информация какво трябва да направите.\n\nМоля, изтрийте теста от Вашето Corona-Warn-App приложение, за да можете да запазите нов код на тест, ако е необходимо."</string>
+    <string name="submission_test_result_invalid_steps_invalid_body">"Възникна проблем при определянето на резултата от Вашия тест. Моля, свържете се със съответния център за тестване или лаборатория, за да получите информация какво трябва да направите.\n\nМоля, изтрийте теста от Вашето Corona-Warn-App приложение, за да можете да запазите нов код на тест, ако е необходимо."</string>
     <!-- XBUT: invalid test result : remove the test button -->
     <string name="submission_test_result_invalid_remove_test_button">"Изтриване на тест"</string>
     <!-- XHED: Dialog title for tracing required dailog  -->
@@ -809,9 +824,9 @@
     <!-- XBUT: tracing required : OK button -->
     <string name="submission_test_result_dialog_tracing_required_button">"OK"</string>
     <!-- XHED: Dialog title for test removal  -->
-    <string name="submission_test_result_dialog_remove_test_title">"Да се изтрие ли тестът?"</string>
+    <string name="submission_test_result_dialog_remove_test_title">"Тестът може да се сканира само веднъж."</string>
     <!-- YTXT: Dialog text for test removal -->
-    <string name="submission_test_result_dialog_remove_test_message">"Тестът ще бъде изтрит безвъзвратно от приложението Corona-Warn-App и няма да може да бъде добавен отново. Действието не може да бъде отменено."</string>
+    <string name="submission_test_result_dialog_remove_test_message">"Ако изтриете теста, повече няма да можете да извлечете данните за резултата си. Ще получите резултата си от център за тестване или лаборатория, независимо от приложението. Ако Ви бъде поставена диагноза COVID-19, службата за обществено осигуряване ще Ви уведоми за това."</string>
     <!-- XBUT: Positive button for test removal -->
     <string name="submission_test_result_dialog_remove_test_button_positive">"Изтриване"</string>
     <!-- XBUT: Negative button for test removal -->
@@ -931,11 +946,11 @@
     <!-- XHED: Page headline for contact page in submission flow -->
     <string name="submission_contact_headline">"Как работи:"</string>
     <!-- YTXT: Body text for contact page in submission flow-->
-    <string name="submission_contact_body">"За да заявите ТАН код, подгответе резултата от своя тест (ако е наличен) и телефонния си номер."</string>
+    <string name="submission_contact_body">"За да заявите ТАН код, подгответе резултата от своя тест (ако е наличен) и телефонния си номер.\n\nЛицата със слухови нарушения могат да използват релейните услуги Tess (за превод между писмен немски и жестомимичен език), за да се обаждат на горещата телефонна линия. Може да изтеглите приложението от Google Play."</string>
     <!-- XBUT: submission contact call button -->
     <string name="submission_contact_button_call">"Обаждане"</string>
     <!-- XBUT: submission contact enter tan button -->
-    <string name="submission_contact_button_enter">"Въведете ТАН код"</string>
+    <string name="submission_contact_button_enter">"Въвеждане на ТАН"</string>
     <!-- YTXT: Body text for step 1 of contact page -->
     <string name="submission_contact_step_1_body">"Обадете се на горещата линия и поискайте ТАН код:"</string>
     <!-- XLNK: Button / hyperlink to phone call for TAN contact page -->
diff --git a/Corona-Warn-App/src/main/res/values-de/strings.xml b/Corona-Warn-App/src/main/res/values-de/strings.xml
index 7d4892497051821a476176eb32f0eac788a7e3f8..1029935d40350a3f87fe7978c56788c97a039d33 100644
--- a/Corona-Warn-App/src/main/res/values-de/strings.xml
+++ b/Corona-Warn-App/src/main/res/values-de/strings.xml
@@ -163,6 +163,8 @@
     <string name="risk_card_body_time_fetched">"Aktualisiert: %1$s"</string>
     <!-- XTXT: risk card - next update -->
     <string name="risk_card_body_next_update">"Tägliche Aktualisierung"</string>
+    <!-- XTXT: risk card - hint to open the app daily -->
+    <string name="risk_card_body_open_daily">"Hinweis: Bitte öffnen Sie die App täglich, um den Risikostatus zu aktualisieren."</string>
     <!-- XBUT: risk card - update risk -->
     <string name="risk_card_button_update">"Aktualisieren"</string>
     <!-- XBUT: risk card - update risk with time display -->
@@ -303,7 +305,7 @@
     <!-- XMSG: risk details - get in touch with the corresponding people, something like a bullet point -->
     <string name="risk_details_behavior_body_contact_doctor">"Für Fragen zu auftretenden Symptomen, Testmöglichkeiten und weiteren Isolationsmaßnahmen, wenden Sie sich bitte an eine der folgenden Stellen:"</string>
     <!-- XMSG: risk details - wash your hands, something like a bullet point -->
-    <string name="risk_details_behavior_body_wash_hands">"Waschen Sie Ihre Hände regelmäßig."</string>
+    <string name="risk_details_behavior_body_wash_hands">"Waschen Sie Ihre Hände regelmäßig mit Seife für 20 Sekunden."</string>
     <!-- XMSG: risk details - wear a face mask, something like a bullet point -->
     <string name="risk_details_behavior_body_wear_mask">"Tragen Sie einen Mund-Nasen-Schutz bei Begegnungen mit anderen Personen."</string>
     <!-- XMSG: risk details - stay 1,5 away, something like a bullet point -->
@@ -338,12 +340,12 @@
     <string name="risk_details_information_body_low_risk">"Sie haben ein niedriges Infektionsrisiko, da keine Begegnung mit nachweislich Corona-positiv getesteten Personen aufgezeichnet wurde oder sich Ihre Begegnung auf kurze Zeit und einen größeren Abstand beschränkt hat."</string>
     <!-- YTXT: risk details - increased risk explanation text with variable for day(s) since last contact -->
     <plurals name="risk_details_information_body_increased_risk">
-        <item quantity="one">"Sie haben ein erhöhtes Infektionsrisiko, da Sie zuletzt vor %1$s Tag mindestens einer nachweislich Corona-positiv getesteten Person über einen längeren Zeitpunkt und mit einem geringen Abstand begegnet sind."</item>
-        <item quantity="other">"Sie haben ein erhöhtes Infektionsrisiko, da Sie zuletzt vor %1$s Tagen mindestens einer nachweislich Corona-positiv getesteten Person über einen längeren Zeitpunkt und mit einem geringen Abstand begegnet sind."</item>
-        <item quantity="zero">"Sie haben ein erhöhtes Infektionsrisiko, da Sie zuletzt vor %1$s Tagen mindestens einer nachweislich Corona-positiv getesteten Person über einen längeren Zeitpunkt und mit einem geringen Abstand begegnet sind."</item>
-        <item quantity="two">"Sie haben ein erhöhtes Infektionsrisiko, da Sie zuletzt vor %1$s Tagen mindestens einer nachweislich Corona-positiv getesteten Person über einen längeren Zeitpunkt und mit einem geringen Abstand begegnet sind."</item>
-        <item quantity="few">"Sie haben ein erhöhtes Infektionsrisiko, da Sie zuletzt vor %1$s Tagen mindestens einer nachweislich Corona-positiv getesteten Person über einen längeren Zeitpunkt und mit einem geringen Abstand begegnet sind."</item>
-        <item quantity="many">"Sie haben ein erhöhtes Infektionsrisiko, da Sie zuletzt vor %1$s Tagen mindestens einer nachweislich Corona-positiv getesteten Person über einen längeren Zeitpunkt und mit einem geringen Abstand begegnet sind."</item>
+        <item quantity="one">"Sie haben ein erhöhtes Infektionsrisiko, da Sie zuletzt vor %1$s Tag mindestens einer nachweislich Corona-positiv getesteten Person über einen längeren Zeitraum und mit einem geringen Abstand begegnet sind."</item>
+        <item quantity="other">"Sie haben ein erhöhtes Infektionsrisiko, da Sie zuletzt vor %1$s Tagen mindestens einer nachweislich Corona-positiv getesteten Person über einen längeren Zeitraum und mit einem geringen Abstand begegnet sind."</item>
+        <item quantity="zero">"Sie haben ein erhöhtes Infektionsrisiko, da Sie zuletzt vor %1$s Tagen mindestens einer nachweislich Corona-positiv getesteten Person über einen längeren Zeitraum und mit einem geringen Abstand begegnet sind."</item>
+        <item quantity="two">"Sie haben ein erhöhtes Infektionsrisiko, da Sie zuletzt vor %1$s Tagen mindestens einer nachweislich Corona-positiv getesteten Person über einen längeren Zeitraum und mit einem geringen Abstand begegnet sind."</item>
+        <item quantity="few">"Sie haben ein erhöhtes Infektionsrisiko, da Sie zuletzt vor %1$s Tagen mindestens einer nachweislich Corona-positiv getesteten Person über einen längeren Zeitraum und mit einem geringen Abstand begegnet sind."</item>
+        <item quantity="many">"Sie haben ein erhöhtes Infektionsrisiko, da Sie zuletzt vor %1$s Tagen mindestens einer nachweislich Corona-positiv getesteten Person über einen längeren Zeitraum und mit einem geringen Abstand begegnet sind."</item>
     </plurals>
     <!-- YTXT: risk details - risk calculation explanation -->
     <string name="risk_details_information_body_notice">"Das Infektionsrisiko wird anhand der Daten der Risiko-Ermittlung unter Berücksichtigung von Abstand und Dauer lokal auf Ihrem Smartphone berechnet. Ihr Infektionsrisiko ist für niemanden einsehbar und wird nicht weitergegeben."</string>
@@ -408,6 +410,8 @@
     <string name="onboarding_tracing_body">"Die Risiko-Ermittlung funktioniert, indem Ihr Handy per Bluetooth verschlüsselte Zufallscodes anderer Nutzerinnen und Nutzer empfängt und Ihren eigenen Zufallscode an deren Smartphones weitergibt. Die Funktion lässt sich jederzeit wieder deaktivieren."</string>
     <!-- YTXT: onboarding(tracing) - explain tracing -->
     <string name="onboarding_tracing_body_emphasized">"Die verschlüsselten Zufallscodes geben nur Auskunft über das Datum, die Dauer und die anhand der Signalstärke berechnete Entfernung zu Ihren Mitmenschen. Persönliche Daten wie Name, Adresse oder Aufenthaltsort werden zu keiner Zeit erfasst. Konkrete Rückschlüsse auf Personen sind nicht möglich."</string>
+    <!-- YTXT: onboarding(tracing) - easy language explain tracing link-->
+    <string name="onboarding_tracing_easy_language_explanation"><a href="https://www.bundesregierung.de/breg-de/themen/corona-warn-app/corona-warn-app-leichte-sprache-gebaerdensprache">Informationen zur App in leichter Sprache und Gebärdensprache</a></string>
     <!-- XHED: onboarding(tracing) - headline for consent information -->
     <string name="onboarding_tracing_headline_consent">"Einwilligungserklärung"</string>
     <!-- YTXT: onboarding(tracing) - body for consent information -->
@@ -687,7 +691,11 @@
     <!-- XHED: Headline for legal information page, contact section -->
     <string name="information_legal_headline_contact">"Kontakt"</string>
     <!-- YTXT: subtitle for legal information page, contact section -->
-    <string name="information_legal_subtitle_contact">"E-Mail: CoronaWarnApp@rki.de"<xliff:g id="line_break">"\n"</xliff:g>"Telefon: +49 30 18754 5100"</string>
+    <string name="information_legal_subtitle_contact">"E-Mail: CoronaWarnApp@rki.de"</string>
+    <!-- YTXT: subtitle for legal information page, open contact form -->
+    <string name="information_legal_subtitle_contact_form"><a href="https://www.rki.de/SharedDocs/Kontaktformulare/weitere/Corona-Warn-App/Corona-Warn-App_Integrator.html">Kontaktformular</a></string>
+    <!-- NOTR: subtitle for legal information page, open contact form for languages other than English and German -->
+    <string name="information_legal_subtitle_contact_form_non_en_de">Contact Form in <a href="https://www.rki.de/SharedDocs/Kontaktformulare/en/Kontaktformulare/weitere/Corona-Warn-App/Corona-Warn-App_Integrator.html">English</a> or <a href="https://www.rki.de/SharedDocs/Kontaktformulare/weitere/Corona-Warn-App/Corona-Warn-App_Integrator.html">German</a></string>
     <!-- XHED: Headline for legal information page, tax section -->
     <string name="information_legal_headline_taxid">"Umsatzsteueridentifikationsnummer"</string>
     <!-- YTXT: subtitle for legal information page, tax section -->
@@ -730,6 +738,13 @@
     <!-- XBUT: Positive button for submission tan invalid -->
     <string name="submission_error_dialog_web_tan_invalid_button_positive">"Zurück"</string>
 
+    <!-- XHED: Dialog title for submission tan redeemed -->
+    <string name="submission_error_dialog_web_tan_redeemed_title">"Test fehlerhaft"</string>
+    <!-- XMSG: Dialog body for submission tan redeemed -->
+    <string name="submission_error_dialog_web_tan_redeemed_body">"Es gab ein Problem bei der Auswertung Ihres Tests. Ihr QR Code ist bereits abgelaufen."</string>
+    <!-- XBUT: Positive button for submission tan redeemed -->
+    <string name="submission_error_dialog_web_tan_redeemed_button_positive">"OK"</string>
+
     <!-- Permission Rationale Dialog -->
     <!-- XHED: Dialog headline QR Scan permission rationale  -->
     <string name="submission_qr_code_scan_permission_rationale_dialog_headline">"Kamera-Zugriff benötigt"</string>
@@ -750,9 +765,9 @@
 
     <!-- QR Code Scan Invalid Dialog -->
     <!-- XHED: Dialog headline for invalid QR code  -->
-    <string name="submission_qr_code_scan_invalid_dialog_headline">"QR-Code nicht korrekt"</string>
+    <string name="submission_qr_code_scan_invalid_dialog_headline">"QR-Code ist ungültig"</string>
     <!-- YTXT: Dialog Body text for invalid QR code -->
-    <string name="submission_qr_code_scan_invalid_dialog_body">"Der QR-Code ist nicht korrekt. Bitte versuchen Sie es erneut."</string>
+    <string name="submission_qr_code_scan_invalid_dialog_body">"Der QR-Code ist ungültig oder wurde bereits auf einem Smartphone registriert. Ihr Testergebnis bekommen Sie vom Testcenter oder Labor, unabhängig von der Gültigkeit des QR-Codes. Wenn Ihr Test positiv ausfällt, bekommen Sie vom Gesundheitsamt eine Mitteilung."</string>
     <!-- XBUT: Dialog(Invalid QR code) - positive button (right) -->
     <string name="submission_qr_code_scan_invalid_dialog_button_positive">"Erneut versuchen"</string>
     <!-- XBUT: Dialog(Invalid QR code) - negative button (left) -->
@@ -799,7 +814,7 @@
     <!-- XHED: Page headline for invalid test result screen  -->
     <string name="submission_test_result_invalid_steps_invalid_heading">"Ihr Testergebnis"</string>
     <!-- YTXT: Body text for next steps section of invalid test result-->
-    <string name="submission_test_result_invalid_steps_invalid_body">"Es gab ein Problem bei der Auswertung Ihres Tests. Bitte kontaktieren Sie das Gesundheitsamt um Information zum weiteren Vorgehen zu erhalten.\n\nBitte entfernen Sie den Test wieder aus der Corona-Warn-App, damit Sie bei Bedarf einen neuen Test hinterlegen können."</string>
+    <string name="submission_test_result_invalid_steps_invalid_body">"Es gab ein Problem bei der Auswertung Ihres Tests. Bitte kontaktieren Sie das Testcenter oder das zuständige Labor, um Information zum weiteren Vorgehen zu erhalten.\n\nBitte entfernen Sie den Test wieder aus der Corona-Warn-App, damit Sie bei Bedarf einen neuen Test hinterlegen können."</string>
     <!-- XBUT: invalid test result : remove the test button -->
     <string name="submission_test_result_invalid_remove_test_button">"Test entfernen"</string>
     <!-- XHED: Dialog title for tracing required dailog  -->
@@ -809,9 +824,9 @@
     <!-- XBUT: tracing required : OK button -->
     <string name="submission_test_result_dialog_tracing_required_button">"OK"</string>
     <!-- XHED: Dialog title for test removal  -->
-    <string name="submission_test_result_dialog_remove_test_title">"Test entfernen?"</string>
+    <string name="submission_test_result_dialog_remove_test_title">"Test kann nur einmal gescannt werden"</string>
     <!-- YTXT: Dialog text for test removal -->
-    <string name="submission_test_result_dialog_remove_test_message">"Der Test wird endgültig aus der Corona-Warn-App entfernt und kann nicht wieder hinzugefügt werden. Dieser Vorgang kann nicht widerrufen werden."</string>
+    <string name="submission_test_result_dialog_remove_test_message">"Wenn Sie den Test entfernen, können Sie Ihr Testergebnis nicht mehr abrufen. Ihr Testergebnis bekommen Sie vom Testcenter oder Labor, unabhängig von der App. Wenn Ihr Test positiv ausfällt, bekommen Sie vom Gesundheitsamt eine Mitteilung."</string>
     <!-- XBUT: Positive button for test removal -->
     <string name="submission_test_result_dialog_remove_test_button_positive">"Entfernen"</string>
     <!-- XBUT: Negative button for test removal -->
@@ -931,7 +946,7 @@
     <!-- XHED: Page headline for contact page in submission flow -->
     <string name="submission_contact_headline">"Info zum Ablauf:"</string>
     <!-- YTXT: Body text for contact page in submission flow-->
-    <string name="submission_contact_body">"Bitte halten Sie zur TAN-Abfrage Ihren Befundbrief (sofern vorhanden) und Ihre Telefonnummer bereit."</string>
+    <string name="submission_contact_body">"Bitte halten Sie zur TAN-Abfrage Ihren Befundbrief (sofern vorhanden) und Ihre Telefonnummer bereit.\n\nGehörlose, schwerhörige und spätertaubte Menschen können zur telefonischen Kontaktaufnahme die Tess-Relay-Dienste (Dolmetschen in Gebärdensprache und deutscher Schriftsprache) nutzen. Die Software können Sie in Ihrem Play Store herunterladen."</string>
     <!-- XBUT: submission contact call button -->
     <string name="submission_contact_button_call">"Anrufen"</string>
     <!-- XBUT: submission contact enter tan button -->
diff --git a/Corona-Warn-App/src/main/res/values-en/strings.xml b/Corona-Warn-App/src/main/res/values-en/strings.xml
index f028e2864caae91bdfbe317c570414e379c1251e..0a8eca2492bd528f4b94a84cdbd0f3756ec724c9 100644
--- a/Corona-Warn-App/src/main/res/values-en/strings.xml
+++ b/Corona-Warn-App/src/main/res/values-en/strings.xml
@@ -163,6 +163,8 @@
     <string name="risk_card_body_time_fetched">"Updated: %1$s"</string>
     <!-- XTXT: risk card - next update -->
     <string name="risk_card_body_next_update">"Updated daily"</string>
+    <!-- XTXT: risk card - hint to open the app daily -->
+    <string name="risk_card_body_open_daily">"Note: Please open the app daily to update your risk status."</string>
     <!-- XBUT: risk card - update risk -->
     <string name="risk_card_button_update">"Update"</string>
     <!-- XBUT: risk card - update risk with time display -->
@@ -274,7 +276,7 @@
     <!-- XHED: App overview subtitle for glossary contact  -->
     <string name="main_overview_subtitle_glossary_contact">"Exposures"</string>
     <!-- YTXT: App overview body for glossary contact -->
-    <string name="main_overview_body_glossary_contact">"Encounters over a longer duration and close proximity to people diagnosed with COVID-19."</string>
+    <string name="main_overview_body_glossary_contact">"Encounters over an extended period and in close proximity to a person diagnosed with COVID-19."</string>
     <!-- XHED: App overview subtitle for glossary notifications -->
     <string name="main_overview_subtitle_glossary_notification">"Exposure Notification"</string>
     <!-- YTXT: App overview body for glossary notifications -->
@@ -303,7 +305,7 @@
     <!-- XMSG: risk details - get in touch with the corresponding people, something like a bullet point -->
     <string name="risk_details_behavior_body_contact_doctor">"If you have questions about symptoms, testing availability, or self-isolation, please contact one of the following:"</string>
     <!-- XMSG: risk details - wash your hands, something like a bullet point -->
-    <string name="risk_details_behavior_body_wash_hands">"Wash your hands regularly."</string>
+    <string name="risk_details_behavior_body_wash_hands">"Wash your hands regularly, with soap, for 20 seconds."</string>
     <!-- XMSG: risk details - wear a face mask, something like a bullet point -->
     <string name="risk_details_behavior_body_wear_mask">"Wear a face mask when you encounter other people."</string>
     <!-- XMSG: risk details - stay 1,5 away, something like a bullet point -->
@@ -408,6 +410,8 @@
     <string name="onboarding_tracing_body">"Exposure logging works by your device receiving, via Bluetooth, encrypted random IDs of other users and passing your own random ID to their devices. This feature can be deactivated at any time."</string>
     <!-- YTXT: onboarding(tracing) - explain tracing -->
     <string name="onboarding_tracing_body_emphasized">"The encrypted random IDs only pass information about date, duration and proximity (using signal strength) to other people. Personal data such as name, address, location is never recorded. Individuals cannot be identified."</string>
+    <!-- YTXT: onboarding(tracing) - easy language explain tracing link-->
+    <string name="onboarding_tracing_easy_language_explanation"><a href="https://www.bundesregierung.de/breg-de/themen/corona-warn-app/corona-warn-app-leichte-sprache-gebaerdensprache">"App Information in Simplified Language and Sign Language"</a></string>
     <!-- XHED: onboarding(tracing) - headline for consent information -->
     <string name="onboarding_tracing_headline_consent">"Declaration of Consent"</string>
     <!-- YTXT: onboarding(tracing) - body for consent information -->
@@ -687,7 +691,11 @@
     <!-- XHED: Headline for legal information page, contact section -->
     <string name="information_legal_headline_contact">"Contact"</string>
     <!-- YTXT: subtitle for legal information page, contact section -->
-    <string name="information_legal_subtitle_contact">"E-Mail: CoronaWarnApp@rki.de"<xliff:g id="line_break">"\n"</xliff:g>"Telephone: +49 30 18754 5100"</string>
+    <string name="information_legal_subtitle_contact">"E-mail: CoronaWarnApp@rki.de"</string>
+    <!-- YTXT: subtitle for legal information page, open contact form -->
+    <string name="information_legal_subtitle_contact_form"><a href="https://www.rki.de/SharedDocs/Kontaktformulare/weitere/Corona-Warn-App/Corona-Warn-App_Integrator.html">"Contact Form"</a></string>
+    <!-- NOTR: subtitle for legal information page, open contact form for languages other than English and German -->
+    <string name="information_legal_subtitle_contact_form_non_en_de">"Contact Form in "<a href="https://www.rki.de/SharedDocs/Kontaktformulare/en/Kontaktformulare/weitere/Corona-Warn-App/Corona-Warn-App_Integrator.html">"English"</a>" or "<a href="https://www.rki.de/SharedDocs/Kontaktformulare/weitere/Corona-Warn-App/Corona-Warn-App_Integrator.html">"German"</a></string>
     <!-- XHED: Headline for legal information page, tax section -->
     <string name="information_legal_headline_taxid">"VAT identification number"</string>
     <!-- YTXT: subtitle for legal information page, tax section -->
@@ -730,6 +738,13 @@
     <!-- XBUT: Positive button for submission tan invalid -->
     <string name="submission_error_dialog_web_tan_invalid_button_positive">"Back"</string>
 
+    <!-- XHED: Dialog title for submission tan redeemed -->
+    <string name="submission_error_dialog_web_tan_redeemed_title">"Test has errors"</string>
+    <!-- XMSG: Dialog body for submission tan redeemed -->
+    <string name="submission_error_dialog_web_tan_redeemed_body">"There was a problem evaluating your test. Your QR code has already expired."</string>
+    <!-- XBUT: Positive button for submission tan redeemed -->
+    <string name="submission_error_dialog_web_tan_redeemed_button_positive">"OK"</string>
+
     <!-- Permission Rationale Dialog -->
     <!-- XHED: Dialog headline QR Scan permission rationale  -->
     <string name="submission_qr_code_scan_permission_rationale_dialog_headline">"Camera authorization required"</string>
@@ -750,9 +765,9 @@
 
     <!-- QR Code Scan Invalid Dialog -->
     <!-- XHED: Dialog headline for invalid QR code  -->
-    <string name="submission_qr_code_scan_invalid_dialog_headline">"Incorrect QR code"</string>
+    <string name="submission_qr_code_scan_invalid_dialog_headline">"QR code is invalid"</string>
     <!-- YTXT: Dialog Body text for invalid QR code -->
-    <string name="submission_qr_code_scan_invalid_dialog_body">"The QR code is not correct. Please try again."</string>
+    <string name="submission_qr_code_scan_invalid_dialog_body">"The QR code is invalid or has been registered on another smartphone already. You will receive your test result from the test center or laboratory regardless of the validity of the QR code. If you are diagnosed with COVID-19, you will be notified by the public health authority."</string>
     <!-- XBUT: Dialog(Invalid QR code) - positive button (right) -->
     <string name="submission_qr_code_scan_invalid_dialog_button_positive">"Please try again."</string>
     <!-- XBUT: Dialog(Invalid QR code) - negative button (left) -->
@@ -799,7 +814,7 @@
     <!-- XHED: Page headline for invalid test result screen  -->
     <string name="submission_test_result_invalid_steps_invalid_heading">"Your Test Result"</string>
     <!-- YTXT: Body text for next steps section of invalid test result-->
-    <string name="submission_test_result_invalid_steps_invalid_body">"There was a problem evaluating your test. Please contact the public health authority to find out how to proceed.\n\nPlease delete the test from your Corona-Warn-App so that you will be able to save a new test code there, if necessary."</string>
+    <string name="submission_test_result_invalid_steps_invalid_body">"There was a problem evaluating your test. Please contact the test center or laboratory involved to find out how to proceed.\n\nPlease delete the test from your Corona-Warn-App so that you will be able to save a new test code there, if necessary."</string>
     <!-- XBUT: invalid test result : remove the test button -->
     <string name="submission_test_result_invalid_remove_test_button">"Delete Test"</string>
     <!-- XHED: Dialog title for tracing required dailog  -->
@@ -809,9 +824,9 @@
     <!-- XBUT: tracing required : OK button -->
     <string name="submission_test_result_dialog_tracing_required_button">"OK"</string>
     <!-- XHED: Dialog title for test removal  -->
-    <string name="submission_test_result_dialog_remove_test_title">"Delete the test?"</string>
+    <string name="submission_test_result_dialog_remove_test_title">"The test can only be scanned once."</string>
     <!-- YTXT: Dialog text for test removal -->
-    <string name="submission_test_result_dialog_remove_test_message">"The test will be permanently deleted from the Corona-Warn-App and cannot be added again. This procedure cannot be undone."</string>
+    <string name="submission_test_result_dialog_remove_test_message">"If you delete the test, you can no longer retrieve your test result. You receive your test result from the test center or laboratory, independently of the app. If you are diagnosed with COVID-19, you will be notified by the public health authority."</string>
     <!-- XBUT: Positive button for test removal -->
     <string name="submission_test_result_dialog_remove_test_button_positive">"Remove"</string>
     <!-- XBUT: Negative button for test removal -->
@@ -931,7 +946,7 @@
     <!-- XHED: Page headline for contact page in submission flow -->
     <string name="submission_contact_headline">"How this works:"</string>
     <!-- YTXT: Body text for contact page in submission flow-->
-    <string name="submission_contact_body">"Please keep your test result (if available) and your phone number ready to request a TAN."</string>
+    <string name="submission_contact_body">"Please keep your test result (if available) and your phone number ready to request a TAN.\n\nPeople with hearing impairments can use Tess Relay services (interpreting between German written language and sign language) to contact the phone hotline. You can download the software from Google Play."</string>
     <!-- XBUT: submission contact call button -->
     <string name="submission_contact_button_call">"Call"</string>
     <!-- XBUT: submission contact enter tan button -->
diff --git a/Corona-Warn-App/src/main/res/values-pl/strings.xml b/Corona-Warn-App/src/main/res/values-pl/strings.xml
index 5abb33a845a83efe2112e6d230206840d34b4c0a..98d60042f624170b22086c8162df4a738d067eb3 100644
--- a/Corona-Warn-App/src/main/res/values-pl/strings.xml
+++ b/Corona-Warn-App/src/main/res/values-pl/strings.xml
@@ -149,9 +149,9 @@
         <item quantity="one">"%1$s narażenie"</item>
         <item quantity="other">"%1$s narażenia"</item>
         <item quantity="zero">"Brak narażenia do tej pory"</item>
-        <item quantity="two">"%1$s narażenia/narażeń"</item>
-        <item quantity="few">"%1$s narażenia/narażeń"</item>
-        <item quantity="many">"%1$s narażenia/narażeń"</item>
+        <item quantity="two">"%1$s narażenia"</item>
+        <item quantity="few">"%1$s narażenia"</item>
+        <item quantity="many">"%1$s narażeń"</item>
     </plurals>
     <!-- XTXT: risk card - tracing active for x out of 14 days -->
     <string name="risk_card_body_saved_days">"Rejestrowanie narażenia było aktywne przez %1$s z ostatnich 14 dni."</string>
@@ -163,6 +163,8 @@
     <string name="risk_card_body_time_fetched">"Zaktualizowano: %1$s"</string>
     <!-- XTXT: risk card - next update -->
     <string name="risk_card_body_next_update">"Aktualizowane codziennie"</string>
+    <!-- XTXT: risk card - hint to open the app daily -->
+    <string name="risk_card_body_open_daily">"Uwaga: Proszę codziennie otwierać aplikację, aby zaktualizować swój status ryzyka."</string>
     <!-- XBUT: risk card - update risk -->
     <string name="risk_card_button_update">"Aktualizuj"</string>
     <!-- XBUT: risk card - update risk with time display -->
@@ -178,16 +180,16 @@
     <!-- XTXT: risk card - increased risk days since last contact -->
     <plurals name="risk_card_increased_risk_body_contact_last">
         <item quantity="one">"%1$s dzień od ostatniego kontaktu"</item>
-        <item quantity="other">"%1$s dni od ostatniego kontaktu"</item>
+        <item quantity="other">"%1$s dnia od ostatniego kontaktu"</item>
         <item quantity="zero">"%1$s dni od ostatniego kontaktu"</item>
         <item quantity="two">"%1$s dni od ostatniego kontaktu"</item>
         <item quantity="few">"%1$s dni od ostatniego kontaktu"</item>
         <item quantity="many">"%1$s dni od ostatniego kontaktu"</item>
     </plurals>
     <!-- XHED: risk card - unknown risk headline -->
-    <string name="risk_card_unknown_risk_headline">"Nieznane ryzyko"</string>
+    <string name="risk_card_unknown_risk_headline">"Ryzyko nieznane"</string>
     <!-- XTXT: risk card - tracing isn't active long enough, so a new risk level can't be calculated -->
-    <string name="risk_card_unknown_risk_body">"Ponieważ nie aktywowałeś(-aś) rejestrowania narażenia na wystarczająco długi czas, nie mogliśmy obliczyć Twojego ryzyka zakażenia."</string>
+    <string name="risk_card_unknown_risk_body">"Nie możemy jeszcze podać ryzyka zakażenia, ponieważ nie mamy jeszcze wystarczającej ilości danych."</string>
     <!-- XHED: risk card - tracing stopped headline, due to no possible calculation -->
     <string name="risk_card_no_calculation_possible_headline">"Rejestrowanie narażenia zatrzymane"</string>
     <!-- XTXT: risk card - last successfully calculated risk level -->
@@ -256,21 +258,21 @@
     <!-- XTXT: App overview low risk level -->
     <string name="main_overview_subtitle_low_risk">"Niskie ryzyko"</string>
     <!-- XTXT: App overview unknown risk level -->
-    <string name="main_overview_subtitle_unknown_risk">"Nieznane ryzyko"</string>
+    <string name="main_overview_subtitle_unknown_risk">"Ryzyko nieznane"</string>
     <!-- XHED: App overview subtitle for test procedure explanation -->
     <string name="main_overview_headline_test">"Powiadamianie innych użytkowników"</string>
     <!-- YTXT: App overview body text about rest procedure -->
-    <string name="main_overview_body_test">"Inną kluczową funkcją jest rejestracja testu i pobranie wyniku. W przypadku zdiagnozowania u Ciebie COVID-19 będziesz mieć możliwość powiadomienia innych i przerwania łańcucha zakażeń."</string>
+    <string name="main_overview_body_test">"Kolejną kluczową funkcją jest rejestracja testu i pobranie wyniku. W przypadku zdiagnozowania u Ciebie COVID-19 będziesz mieć możliwość powiadomienia innych i przerwania łańcucha zakażeń."</string>
     <!-- XHED: App overview headline for glossary -->
     <string name="main_overview_headline_glossary">"Definicja terminów:"</string>
     <!-- XHED: App overview subtitle for glossary key storage -->
     <string name="main_overview_subtitle_glossary_tracing">"Dziennik narażeń"</string>
     <!-- YTXT: App overview body for glossary key storage -->
-    <string name="main_overview_body_glossary_tracing">"Lista otrzymanych i tymczasowych losowych identyfikatorów zapisanych tymczasowo w pamięci masowej systemu operacyjnego. Lista ta jest odczytywana podczas sprawdzania narażeń. Wszystkie losowe identyfikatory są automatycznie usuwane po 14 dniach."</string>
+    <string name="main_overview_body_glossary_tracing">"Lista otrzymanych i tymczasowych losowych identyfikatorów zapisanych tymczasowo w pamięci masowej systemu operacyjnego. Aplikacja korzysta z listy podczas sprawdzania narażeń. Wszystkie losowe identyfikatory są automatycznie usuwane po 14 dniach."</string>
     <!-- XHED: App overview subtitle for glossary risk calculation  -->
     <string name="main_overview_subtitle_glossary_calculation">"Sprawdzanie narażenia"</string>
     <!-- YTXT: App overview body for glossary risk calculation -->
-    <string name="main_overview_body_glossary_calculation">"Dane dziennika narażeń są pobierane i synchronizowane ze zgłoszonymi zakażeniami innych użytkowników. Sprawdzanie narażeń jest wykonywane automatycznie mniej więcej co dwie godziny."</string>
+    <string name="main_overview_body_glossary_calculation">"Odczytanie danych dziennika narażeń i porównanie ze zgłoszonymi zakażeniami innych użytkowników. Sprawdzanie narażeń jest wykonywane automatycznie mniej więcej co dwie godziny."</string>
     <!-- XHED: App overview subtitle for glossary contact  -->
     <string name="main_overview_subtitle_glossary_contact">"Narażenia"</string>
     <!-- YTXT: App overview body for glossary contact -->
@@ -278,11 +280,11 @@
     <!-- XHED: App overview subtitle for glossary notifications -->
     <string name="main_overview_subtitle_glossary_notification">"Powiadomienie o narażeniu"</string>
     <!-- YTXT: App overview body for glossary notifications -->
-    <string name="main_overview_body_glossary_notification">"Wyświetlanie narażeń w Corona-Warn-App."</string>
+    <string name="main_overview_body_glossary_notification">"Wyświetlenie narażeń w Corona-Warn-App."</string>
     <!-- XHED: App overview subtitle for glossary keys -->
     <string name="main_overview_subtitle_glossary_keys">"Losowe identyfikatory"</string>
     <!-- YTXT: App overview body for glossary keys -->
-    <string name="main_overview_body_glossary_keys">"Identyfikatory losowe są kombinacją cyfr i liter generowanych losowo. Są one wymieniane pomiędzy urządzeniami znajdującymi się w bliskiej odległości od siebie. Identyfikatorów losowych nie można przypisać do konkretnej osoby. Są one automatycznie usuwane po 14 dniach. Osoby, u których zdiagnozowano COVID-19, mogą zdecydować się na udostępnienie swoich losowych identyfikatorów z ostatnich 14 dni innym użytkownikom aplikacji."</string>
+    <string name="main_overview_body_glossary_keys">"Losowe identyfikatory są kombinacją cyfr i liter generowanych losowo. Są one wymieniane pomiędzy urządzeniami znajdującymi się w bliskiej odległości od siebie. Losowych identyfikatorów nie można przypisać do konkretnej osoby. Są one automatycznie usuwane po 14 dniach. Osoby, u których zdiagnozowano COVID-19, mogą zdecydować się na udostępnienie swoich losowych identyfikatorów z ostatnich 14 dni innym użytkownikom aplikacji."</string>
     <!-- XACT: main (overview) - illustraction description, explanation image -->
     <string name="main_overview_illustration_description">"Smartfon wyświetla różne treści oznaczone numerami od 1 do 3."</string>
     <!-- XACT: App main page title -->
@@ -303,9 +305,9 @@
     <!-- XMSG: risk details - get in touch with the corresponding people, something like a bullet point -->
     <string name="risk_details_behavior_body_contact_doctor">"W przypadku pytań dotyczących objawów, możliwości wykonania testu lub samoizolacji skontaktuj się z jednym z poniższych miejsc:"</string>
     <!-- XMSG: risk details - wash your hands, something like a bullet point -->
-    <string name="risk_details_behavior_body_wash_hands">"Regularnie myj ręce."</string>
+    <string name="risk_details_behavior_body_wash_hands">"Regularnie myj ręce mydłem przez 20 sekund."</string>
     <!-- XMSG: risk details - wear a face mask, something like a bullet point -->
-    <string name="risk_details_behavior_body_wear_mask">"Załóż maseczkę na twarz, mając kontakt z innymi osobami."</string>
+    <string name="risk_details_behavior_body_wear_mask">"Załóż maseczkę, jeśli zamierzasz kontaktować się fizycznie z innymi osobami."</string>
     <!-- XMSG: risk details - stay 1,5 away, something like a bullet point -->
     <string name="risk_details_behavior_body_stay_away">"Zachowuj odległość co najmniej 1,5 metra od innych osób."</string>
     <!-- XMSG: risk details - cough/sneeze, something like a bullet point -->
@@ -313,7 +315,7 @@
     <!-- XMSG: risk details - contact your doctor, bullet point -->
     <string name="risk_details_behavior_increased_body_1">"Twój lekarz rodzinny"</string>
     <!-- XMSG: risk details - panel doctor on-call service, bullet point -->
-    <string name="risk_details_behavior_increased_body_2">"Pogotowie ratunkowe pod numerem telefonu 116117"</string>
+    <string name="risk_details_behavior_increased_body_2">"Lekarz dyżurny pod numerem telefonu 116117"</string>
     <!-- XMSG: risk details - public health department, bullet point -->
     <string name="risk_details_behavior_increased_body_3">"Organ ds. zdrowia publicznego"</string>
     <!-- XHED: risk details - infection risk headline, below behaviors -->
@@ -331,7 +333,7 @@
     <!-- XHED: risk details - how your risk level will be calculated, below behaviors -->
     <string name="risk_details_subtitle_infection_risk">"Sposób, w jaki obliczane jest Twoje ryzyko"</string>
     <!-- XMSG: risk details - risk couldn't be calculated tracing wasn't enabled long enough, below behaviors -->
-    <string name="risk_details_information_body_unknown_risk">"Ponieważ nie aktywowałeś(-aś) rejestrowania narażenia na wystarczająco długi czas, nie mogliśmy obliczyć Twojego ryzyka zakażenia."</string>
+    <string name="risk_details_information_body_unknown_risk">"Nie możemy jeszcze podać ryzyka zakażenia, ponieważ nie mamy jeszcze wystarczającej ilości danych."</string>
     <!-- XMSG: risk details - risk calculation wasn't possible for 24h, below behaviors -->
     <string name="risk_details_information_body_outdated_risk">"Rejestrowanie narażenia nie mogło zostać zaktualizowane przez okres dłuższy niż 24 godziny."</string>
     <!-- YTXT: risk details - low risk explanation text -->
@@ -361,7 +363,7 @@
     <!-- XHED: one time risk explanation dialog title  -->
     <string name="risk_details_explanation_dialog_title">"Informacje o funkcjonalności rejestrowania narażenia"</string>
     <!-- YTXT: one time risk explanation dialog - pointing to the faq page for more information-->
-    <string name="risk_details_explanation_dialog_faq_body">"Więcej informacji znajduje się na naszej stronie Często zadawane pytania."</string>
+    <string name="risk_details_explanation_dialog_faq_body">"Więcej informacji znajduje się na naszej stronie „Często zadawane pytania”."</string>
 
     <!-- ####################################
               Onboarding
@@ -407,9 +409,11 @@
     <!-- YTXT: onboarding(tracing) - explain tracing -->
     <string name="onboarding_tracing_body">"Działanie funkcji rejestrowania narażenia polega na odbieraniu przez Twoje urządzenie za pomocą Bluetooth zaszyfrowanych, losowych identyfikatorów innych użytkowników i przekazywaniu Twoich własnych, losowych identyfikatorów do ich urządzeń. Funkcję tę można wyłączyć w dowolnym momencie."</string>
     <!-- YTXT: onboarding(tracing) - explain tracing -->
-    <string name="onboarding_tracing_body_emphasized">"Zaszyfrowane losowe identyfikatory przekazują innym osobom jedynie informacje o dacie, czasie trwania i bliskości (przy wykorzystaniu mocy sygnału). Dane osobowe, takie jak nazwisko, adres, lokalizacja, nie są nigdy rejestrowane. Ustalenie tożsamości osób nie jest możliwe."</string>
+    <string name="onboarding_tracing_body_emphasized">"Identyfikatory przekazują w sposób zaszyfrowany wyłącznie informacje o dacie, czasie trwania i odległości (przy wykorzystaniu mocy sygnału) od innych użytkowników aplikacji. Dane osobowe, takie jak nazwisko, adres, lokalizacja, nie są nigdy rejestrowane. Ustalenie tożsamości osób nie jest możliwe."</string>
+    <!-- YTXT: onboarding(tracing) - easy language explain tracing link-->
+    <string name="onboarding_tracing_easy_language_explanation"><a href="https://www.bundesregierung.de/breg-de/themen/corona-warn-app/corona-warn-app-leichte-sprache-gebaerdensprache">"Informacja o aplikacji w języku uproszczonym i języku migowym"</a></string>
     <!-- XHED: onboarding(tracing) - headline for consent information -->
-    <string name="onboarding_tracing_headline_consent">"Oświadczenia o wyrażeniu zgody"</string>
+    <string name="onboarding_tracing_headline_consent">"Oświadczenie o wyrażeniu zgody"</string>
     <!-- YTXT: onboarding(tracing) - body for consent information -->
     <string name="onboarding_tracing_body_consent">"To find out whether you have been in contact with an infected person and whether there is a risk that you yourself have been infected, you need to enable the App’s exposure logging feature. By tapping on the “Enable” button, you agree to the enabling of the App’s exposure logging feature and the associated data processing."<xliff:g id="line_break">"\n"</xliff:g><xliff:g id="line_break">"\n"</xliff:g>"In order to use the App’s exposure logging feature, you will have to enable the COVID-19 Exposure Logging functionality provided by Google on your smartphone and grant the Corona-Warn-App permission to use this."<xliff:g id="line_break">"\n"</xliff:g><xliff:g id="line_break">"\n"</xliff:g>"When exposure logging is enabled, your smartphone continuously generates and transmits random IDs via Bluetooth, which other Android or Apple smartphones in your vicinity can receive if exposure logging is also enabled on them. Your smartphone, in turn, receives the random IDs of the other smartphones. Your own random IDs and those received from other smartphones are recorded in the exposure log and stored there for 14 days."<xliff:g id="line_break">"\n"</xliff:g><xliff:g id="line_break">"\n"</xliff:g>"To identify your risk of infection, the App loads a list – several times a day or on request – of the random IDs of all users who have told the App that they have been infected with the coronavirus. This list is then compared with the random IDs stored in the exposure log. If the App detects that you may have been in contact with an infected user, it will inform you of this and tell you that there is a risk that you are also infected. In this case, the App is also given access to other data stored in your smartphone’s exposure log (date, duration and Bluetooth signal strength of the contact)."<xliff:g id="line_break">"\n"</xliff:g><xliff:g id="line_break">"\n"</xliff:g>"The Bluetooth signal strength is used to derive the physical distance (the stronger the signal, the smaller the distance). The App then analyses this information in order to assess your likelihood of having been infected with the coronavirus and to give you recommendations for what to do next. This analysis is only performed locally on your smartphone. Apart from you, nobody (not even the RKI) will know whether you have been in contact with an infected person and what risk has been identified for you."<xliff:g id="line_break">"\n"</xliff:g><xliff:g id="line_break">"\n"</xliff:g>"To withdraw your consent to the exposure logging feature, you can disable the feature using the toggle switch in the App or delete the App. If you decide to use the exposure logging feature again, you can toggle the feature back on or reinstall the App. If you disable the exposure logging feature, the App will no longer check whether you have been in contact with an infected user. If you also wish to stop your device sending and receiving random IDs, you will need to disable COVID-19 Exposure Logging in your smartphone settings. Please note that your own random IDs and those received from other smartphones which are stored in the exposure log will not be deleted in the App. You can only permanently delete the data stored in the exposure log in your smartphone settings."<xliff:g id="line_break">"\n"</xliff:g><xliff:g id="line_break">"\n"</xliff:g>"The App’s privacy notice (including an explanation of the data processing carried out for the exposure logging feature) can be found in the menu under “Data Privacy Information”."</string>
     <!-- XBUT: onboarding(tracing) - button enable tracing -->
@@ -459,7 +463,7 @@
     <!-- XHED: onboarding(test) - two/three line headline under an illustration -->
     <string name="onboarding_test_subtitle">"… zgłoś ten fakt w Corona-Warn-App. Udostępnianie wyników testu jest dobrowolne i bezpieczne. Zrób to ze względu na zdrowie innych osób."</string>
     <!-- YTXT: onboarding(test) - explain test -->
-    <string name="onboarding_test_body">"Twoje powiadomienie jest szyfrowane w bezpieczny sposób i przetwarzane na bezpiecznym serwerze. Osoby, których zaszyfrowane losowe identyfikatory zostały zgromadzone przez Twoje urządzenie, otrzymają teraz ostrzeżenie wraz z informacją na temat dalszych kroków postępowania."</string>
+    <string name="onboarding_test_body">"Twoje powiadomienie jest szyfrowane w bezpieczny sposób i przetwarzane na bezpiecznym serwerze. Osoby, których zaszyfrowane losowe identyfikatory zostały zgromadzone przez Twoje urządzenie, otrzymają wtedy ostrzeżenie wraz z informacją na temat dalszych kroków postępowania."</string>
     <!-- XACT: onboarding(test) - illustraction description, header image -->
     <string name="onboarding_test_illustration_description">"Zaszyfrowana diagnoza zakażenia jest przesyłana do systemu, który będzie teraz ostrzegał innych użytkowników."</string>
     <!-- XACT: Onboarding (datashare) page title -->
@@ -520,7 +524,7 @@
     <!-- XBUT: settings(tracing) - go to operating system settings button on card - location -->
     <string name="settings_tracing_status_location_button">"Otwórz ustawienia urządzenia"</string>
     <!--XHED : settings(tracing) - headline on card about the current status and what to do -->
-    <string name="settings_tracing_status_connection_headline">"Otwórz połączenie z Internetem"</string>
+    <string name="settings_tracing_status_connection_headline">"Połącz z Internetem"</string>
     <!-- XTXT: settings(tracing) - explains user what to do on card if connection is disabled -->
     <string name="settings_tracing_status_connection_body">"Rejestrowanie narażenia wymaga połączenia z Internetem w celu obliczenia narażeń. Włącz WIFI lub dane mobilne w ustawieniach swojego urządzenia."</string>
     <!-- XBUT: settings(tracing) - go to operating system settings button on card -->
@@ -528,7 +532,7 @@
     <!-- XTXT: settings(tracing) - explains the circle progress indicator to the right with the current value -->
     <plurals name="settings_tracing_status_body_active">
         <item quantity="one">"Rejestrowanie narażenia jest aktywne od jednego dnia.\nSprawdzanie narażeń jest wiarygodne tylko wtedy, gdy rejestrowanie narażenia jest aktywowane na stałe."</item>
-        <item quantity="other">"Rejestrowanie narażenia jest aktywne od %1$s dni.\nSprawdzanie narażeń jest wiarygodne tylko wtedy, gdy rejestracja narażenia jest aktywowana na stałe."</item>
+        <item quantity="other">"Rejestrowanie narażenia jest aktywne od %1$s dnia.\nSprawdzanie narażeń jest wiarygodne tylko wtedy, gdy rejestracja narażenia jest aktywowana na stałe."</item>
         <item quantity="zero">"Rejestrowanie narażenia jest aktywne od %1$s dni.\nSprawdzanie narażeń jest wiarygodne tylko wtedy, gdy rejestrowanie narażenia jest aktywowane na stałe."</item>
         <item quantity="two">"Rejestrowanie narażenia jest aktywne od %1$s dni.\nSprawdzanie narażeń jest wiarygodne tylko wtedy, gdy rejestracja narażenia jest aktywowana na stałe."</item>
         <item quantity="few">"Rejestrowanie narażenia jest aktywne od %1$s dni.\nSprawdzanie narażeń jest wiarygodne tylko wtedy, gdy rejestracja narażenia jest aktywowana na stałe."</item>
@@ -663,7 +667,7 @@
     <!-- YTXT: Body text for technical contact and hotline information page -->
     <string name="information_contact_body_open">"Języki: niemiecki, angielski, turecki\nGodziny pracy:"<xliff:g id="line_break">"\n"</xliff:g>"od poniedziałku do soboty: 7:00 - 22:00"<xliff:g id="line_break">"\n(za wyjątkiem świąt państwowych)"</xliff:g><xliff:g id="line_break">"\nPołączenie jest bezpłatne."</xliff:g></string>
     <!-- YTXT: Body text for technical contact and hotline information page -->
-    <string name="information_contact_body_other">"W razie jakichkolwiek pytań związanych ze zdrowiem skontaktuj się z lekarzem rodzinnym lub pogotowiem ratunkowym pod numerem: 116 117."</string>
+    <string name="information_contact_body_other">"W razie jakichkolwiek pytań związanych ze zdrowiem skontaktuj się z lekarzem rodzinnym lub lekarzem dyżurnym pod numerem: 116 117."</string>
     <!-- XACT: describes illustration -->
     <string name="information_contact_illustration_description">"Mężczyzna korzystający z zestawu słuchawkowego prowadzi rozmowę telefoniczną."</string>
     <!-- XLNK: Menu item / hyper link / button text for navigation to FAQ website -->
@@ -687,7 +691,11 @@
     <!-- XHED: Headline for legal information page, contact section -->
     <string name="information_legal_headline_contact">"Kontakt"</string>
     <!-- YTXT: subtitle for legal information page, contact section -->
-    <string name="information_legal_subtitle_contact">"E-mail: CoronaWarnApp@rki.de"<xliff:g id="line_break">"\n"</xliff:g>"Telefon: +49 30 18754 5100"</string>
+    <string name="information_legal_subtitle_contact">"E-mail: CoronaWarnApp@rki.de"</string>
+    <!-- YTXT: subtitle for legal information page, open contact form -->
+    <string name="information_legal_subtitle_contact_form"><a href="https://www.rki.de/SharedDocs/Kontaktformulare/weitere/Corona-Warn-App/Corona-Warn-App_Integrator.html">"Formularz kontaktowy"</a></string>
+    <!-- NOTR: subtitle for legal information page, open contact form for languages other than English and German -->
+    <string name="information_legal_subtitle_contact_form_non_en_de">"Contact Form in "<a href="https://www.rki.de/SharedDocs/Kontaktformulare/en/Kontaktformulare/weitere/Corona-Warn-App/Corona-Warn-App_Integrator.html">"English"</a>" or "<a href="https://www.rki.de/SharedDocs/Kontaktformulare/weitere/Corona-Warn-App/Corona-Warn-App_Integrator.html">"German"</a></string>
     <!-- XHED: Headline for legal information page, tax section -->
     <string name="information_legal_headline_taxid">"Numer identyfikacyjny VAT"</string>
     <!-- YTXT: subtitle for legal information page, tax section -->
@@ -730,6 +738,13 @@
     <!-- XBUT: Positive button for submission tan invalid -->
     <string name="submission_error_dialog_web_tan_invalid_button_positive">"Wstecz"</string>
 
+    <!-- XHED: Dialog title for submission tan redeemed -->
+    <string name="submission_error_dialog_web_tan_redeemed_title">"Test zawiera błędy"</string>
+    <!-- XMSG: Dialog body for submission tan redeemed -->
+    <string name="submission_error_dialog_web_tan_redeemed_body">"Podczas ustalania wyniku testu pojawił się błąd. Twój kod QR wygasł."</string>
+    <!-- XBUT: Positive button for submission tan redeemed -->
+    <string name="submission_error_dialog_web_tan_redeemed_button_positive">"OK"</string>
+
     <!-- Permission Rationale Dialog -->
     <!-- XHED: Dialog headline QR Scan permission rationale  -->
     <string name="submission_qr_code_scan_permission_rationale_dialog_headline">"Wymagana autoryzacja aparatu"</string>
@@ -752,7 +767,7 @@
     <!-- XHED: Dialog headline for invalid QR code  -->
     <string name="submission_qr_code_scan_invalid_dialog_headline">"Niepoprawny kod QR"</string>
     <!-- YTXT: Dialog Body text for invalid QR code -->
-    <string name="submission_qr_code_scan_invalid_dialog_body">"Kod QR jest nie poprawny. Spróbuj ponownie."</string>
+    <string name="submission_qr_code_scan_invalid_dialog_body">"Kod QR jest niepoprawny lub został już zarejestrowany na innym smartfonie. Otrzymasz swój wynik testu z ośrodka wykonującego testy lub laboratorium niezależnie od ważności kodu QR. W przypadku zdiagnozowania u Ciebie COVID-19 otrzymasz powiadomienie z organu ds. zdrowia publicznego."</string>
     <!-- XBUT: Dialog(Invalid QR code) - positive button (right) -->
     <string name="submission_qr_code_scan_invalid_dialog_button_positive">"Spróbuj ponownie."</string>
     <!-- XBUT: Dialog(Invalid QR code) - negative button (left) -->
@@ -769,7 +784,7 @@
     <!-- XHED: Page subheadline for test result  -->
     <string name="submission_test_result_subtitle">"Jak to działa:"</string>
     <!-- XHED: Page headline for results next steps  -->
-    <string name="submission_test_result_steps_added_heading">"Test został dodany"</string>
+    <string name="submission_test_result_steps_added_heading">"Test został dodany."</string>
     <!-- YTXT: Body text for for results next steps  -->
     <string name="submission_test_result_steps_added_body">"Twój test został zapisany w Corona-Warn-App."</string>
     <!-- XHED: Page headline for pending test result next steps  -->
@@ -799,7 +814,7 @@
     <!-- XHED: Page headline for invalid test result screen  -->
     <string name="submission_test_result_invalid_steps_invalid_heading">"Twój wynik testu"</string>
     <!-- YTXT: Body text for next steps section of invalid test result-->
-    <string name="submission_test_result_invalid_steps_invalid_body">"Wystąpił problem z ustaleniem wyniku Twojego testu. Skontaktuj się z organem ds. zdrowia publicznego, aby dowiedzieć się, jak dalej postępować.\n\nUsuń test z aplikacji Corona-Warn-App, aby w razie potrzeby móc zapisać w niej kod nowego testu."</string>
+    <string name="submission_test_result_invalid_steps_invalid_body">"Wystąpił problem z ustaleniem wyniku Twojego testu. Skontaktuj się z ośrodkiem wykonującym testy lub odpowiednim laboratorium, aby dowiedzieć się, jak dalej postępować.\n\nUsuń test z aplikacji Corona-Warn-App, aby w razie potrzeby móc zapisać w niej kod nowego testu."</string>
     <!-- XBUT: invalid test result : remove the test button -->
     <string name="submission_test_result_invalid_remove_test_button">"Usuń test"</string>
     <!-- XHED: Dialog title for tracing required dailog  -->
@@ -809,9 +824,9 @@
     <!-- XBUT: tracing required : OK button -->
     <string name="submission_test_result_dialog_tracing_required_button">"OK"</string>
     <!-- XHED: Dialog title for test removal  -->
-    <string name="submission_test_result_dialog_remove_test_title">"Usunąć test?"</string>
+    <string name="submission_test_result_dialog_remove_test_title">"Test może być zeskanowany tylko raz."</string>
     <!-- YTXT: Dialog text for test removal -->
-    <string name="submission_test_result_dialog_remove_test_message">"Test zostanie trwale usunięty z Corona-Warn-App i jego ponownie dodanie nie będzie możliwe. Tej procedury nie można cofnąć."</string>
+    <string name="submission_test_result_dialog_remove_test_message">"Jeśli usuniesz test, nie będziesz mieć możliwości pobrania wyniku swojego testu. Otrzymasz wynik swojego testu z ośrodka wykonującego testy lub laboratorium, niezależnie od aplikacji. W przypadku zdiagnozowania u Ciebie COVID-19 otrzymasz powiadomienie z organu ds. zdrowia publicznego."</string>
     <!-- XBUT: Positive button for test removal -->
     <string name="submission_test_result_dialog_remove_test_button_positive">"Usuń"</string>
     <!-- XBUT: Negative button for test removal -->
@@ -865,7 +880,7 @@
     <!-- YTXT: Body text for QR code dispatcher option -->
     <string name="submission_dispatcher_qr_card_text">"Zarejestruj test poprzez zeskanowanie kodu QR dokumentu testu."</string>
     <!-- XHED: Dialog headline for dispatcher QR prviacy dialog  -->
-    <string name="submission_dispatcher_qr_privacy_dialog_headline">"Oświadczenia o wyrażeniu zgody"</string>
+    <string name="submission_dispatcher_qr_privacy_dialog_headline">"Oświadczenie o wyrażeniu zgody"</string>
     <!-- YTXT: Dialog Body text for dispatcher QR privacy dialog -->
     <string name="submission_dispatcher_qr_privacy_dialog_body">"By tapping on “Accept”, you consent to the App querying the status of your coronavirus test and displaying it in the App. This feature is available to you if you have received a QR code and have consented to your test result being transmitted to the App’s server system. As soon as the testing lab has stored your test result on the server, you will be able to see the result in the App. If you have enabled notifications, you will also receive a notification outside the App telling you that your test result has been received. However, for privacy reasons, the test result itself will only be displayed in the App. You can withdraw this consent at any time by deleting your test registration in the App. Withdrawing your consent will not affect the lawfulness of processing before its withdrawal. Further information can be found in the menu under “Data Privacy Information”."</string>
     <!-- XBUT: submission(dispatcher QR Dialog) - positive button (right) -->
@@ -910,13 +925,13 @@
     <!-- YTXT: text after submission: contagious -->
     <string name="submission_done_contagious">"Możesz zarażać."</string>
     <!-- YTXT: text after submission: isolate -->
-    <string name="submission_done_isolate">"Izoluj się od innych osób."</string>
+    <string name="submission_done_isolate">"Zastosuj izolacjÄ™ / unikaj kontaktu fizycznego z innymi osobami."</string>
     <!-- XHED: Title for further info -->
     <string name="submission_done_further_info_title">"Inne informacje:"</string>
     <!-- YTXT: submission done further info bullet points -->
     <string-array name="submission_done_further_info_bullet_points">
         <item>"Okres kwarantanny wynosi zazwyczaj 14 dni. Obserwuj swoje objawy i monitoruj ich rozwój."</item>
-        <item>"Zostaniesz poproszony(-a) przez organ ds. zdrowia publicznego o stworzenie listy osób, z którymi miałeś(-aś) kontakt. Powinna ona obejmować wszystkie osoby, z którymi miałeś(-aś) bliski kontakt (w odległości mniejszej niż 2 metry, rozmowa twarzą w twarz) przez ponad 15 minut w ciągu dwóch dni przed wystąpieniem objawów."</item>
+        <item>"Zostaniesz poproszony(-a) przez organ ds. zdrowia publicznego o stworzenie listy osób, z którymi miałeś(-aś) kontakt. Powinna ona obejmować wszystkie osoby, z którymi miałeś(-aś) bliski kontakt (rozmowa twarzą w twarz w odległości mniejszej niż 2 metry) przez ponad 15 minut w ciągu dwóch dni przed wystąpieniem objawów."</item>
         <item>"Zwróć szczególną uwagę na osoby, które nie zostaną powiadomione bezpośrednio przez aplikację, ponieważ nie posiadają smartfonów lub nie zainstalowały aplikacji."</item>
         <item>"Nawet jeśli nie masz już żadnych objawów i znów czujesz się dobrze, możesz nadal zarażać."</item>
     </string-array>
@@ -931,7 +946,7 @@
     <!-- XHED: Page headline for contact page in submission flow -->
     <string name="submission_contact_headline">"Jak to działa:"</string>
     <!-- YTXT: Body text for contact page in submission flow-->
-    <string name="submission_contact_body">"Przygotuj wynik testu (jeśli jest dostępny) oraz numer telefonu, pod którym można poprosić o numer TAN."</string>
+    <string name="submission_contact_body">"Przygotuj wynik testu (jeśli jest dostępny) oraz numer telefonu, aby poprosić o numer TAN.\n\nOsoby niedosłyszące mogą skorzystać z usług Tess Relay (tłumaczenie z pisanego języka niemieckiego na język migowy i odwrotnie) w celu skontaktowania się z infolinią. To oprogramowanie można pobrać z Google Play."</string>
     <!-- XBUT: submission contact call button -->
     <string name="submission_contact_button_call">"Zadzwoń"</string>
     <!-- XBUT: submission contact enter tan button -->
@@ -968,7 +983,7 @@
     <!-- XHED: Subtitle for the submission status card: invalid -->
     <string name="submission_status_card_subtitle_invalid">"Nieprawidłowy test"</string>
     <!-- XHED: Subtitle for the submission status card: negative -->
-    <string name="submission_status_card_subtitle_negative">"Diagnoza braku zakażenia"</string>
+    <string name="submission_status_card_subtitle_negative">"Diagnoza: brak zakażenia"</string>
     <!-- YTXT: Body text for submission status: fetching -->
     <string name="submission_status_card_body_fetching">"Twój wynik jest aktualizowany"</string>
     <!-- YTXT: Body text for submission status: unregistered -->
@@ -988,7 +1003,7 @@
     <!-- XHED: submission status card positive result subtitle -->
     <string name="submission_status_card_positive_result_subtitle">"Uwaga:"</string>
     <!-- YTXT: text for contagious card -->
-    <string name="submission_status_card_positive_result_contagious">"Możesz zarażać. Izoluj się od innych osób."</string>
+    <string name="submission_status_card_positive_result_contagious">"Możesz zarażać. Zastosuj izolację / unikaj kontaktu fizycznego z innymi osobami."</string>
     <!-- YTXT: text for contact card -->
     <string name="submission_status_card_positive_result_contact">"Organ ds. zdrowia publicznego skontaktuje się z Tobą w ciągu kilku najbliższych dni telefonicznie lub listownie."</string>
     <!-- YTXT: text for share result card-->
@@ -1045,9 +1060,9 @@
     <!-- XTXT: error dialog - detailed text if there is an error during external navigation / external action -->
     <string name="errors_external_action">"Nie możesz wykonać tej czynności. Skontaktuj się z infolinią."</string>
     <!-- XTXT: error dialog - phone still needs Google Play Services or Google Mobile Services update -->
-    <string name="errors_google_update_needed">"Twoja aplikacja Corona-Warn-App jest poprawnie zainstalowana, ale usługa „Powiadomienia o narażeniu na COVID-19” nie jest dostępna w systemie operacyjnym Twojego smartfona. Oznacza to, że nie możesz korzystać z aplikacji Corona-Warn-App. Więcej informacji znajduje się na naszej stronie Często zadawane pytania: https://www.coronawarn.app/en/faq/."</string>
+    <string name="errors_google_update_needed">"Twoja aplikacja Corona-Warn-App jest poprawnie zainstalowana, ale usługa „Powiadomienia o narażeniu na COVID-19” nie jest dostępna w systemie operacyjnym Twojego smartfona. Oznacza to, że nie możesz korzystać z aplikacji Corona-Warn-App. Więcej informacji znajduje się na naszej stronie „Często zadawane pytania”: https://www.coronawarn.app/en/faq/."</string>
     <!-- XTXT: error dialog - either Google API Error (10) or reached request limit per day -->
-    <string name="errors_google_api_error">"Aplikacja Corona-Warn-App działa prawidłowo, ale nie możemy zaaktualizować Twojego aktualnego statusu ryzyka. Rejestrowanie narażenia pozostaje aktywne i działa prawidłowo. Więcej informacji można znaleźć na naszej stronie Często zadawane pytania: https://www.coronawarn.app/en/faq/"</string>
+    <string name="errors_google_api_error">"Aplikacja Corona-Warn-App działa prawidłowo, ale nie możemy zaaktualizować Twojego aktualnego statusu ryzyka. Rejestrowanie narażenia pozostaje aktywne i działa prawidłowo. Więcej informacji można znaleźć na naszej stronie „Często zadawane pytania”: https://www.coronawarn.app/en/faq/"</string>
 
     <!-- ####################################
                Generic Error Messages
diff --git a/Corona-Warn-App/src/main/res/values-ro/strings.xml b/Corona-Warn-App/src/main/res/values-ro/strings.xml
index 75c8656bc2b966b28ff6fdfe5aebd448ea8bd314..9a4d0c6cca4653bc6671ba0c83172af6f3f644d3 100644
--- a/Corona-Warn-App/src/main/res/values-ro/strings.xml
+++ b/Corona-Warn-App/src/main/res/values-ro/strings.xml
@@ -163,6 +163,8 @@
     <string name="risk_card_body_time_fetched">"Actualizată: %1$s"</string>
     <!-- XTXT: risk card - next update -->
     <string name="risk_card_body_next_update">"Actualizată zilnic"</string>
+    <!-- XTXT: risk card - hint to open the app daily -->
+    <string name="risk_card_body_open_daily">"Rețineți: Deschideți aplicația zilnic pentru a actualiza starea riscului dvs."</string>
     <!-- XBUT: risk card - update risk -->
     <string name="risk_card_button_update">"Actualizare"</string>
     <!-- XBUT: risk card - update risk with time display -->
@@ -274,7 +276,7 @@
     <!-- XHED: App overview subtitle for glossary contact  -->
     <string name="main_overview_subtitle_glossary_contact">"Expuneri"</string>
     <!-- YTXT: App overview body for glossary contact -->
-    <string name="main_overview_body_glossary_contact">"Întâlniri de o durată mai lungă și în strânsă proximitate cu persoane diagnosticate cu COVID-19."</string>
+    <string name="main_overview_body_glossary_contact">"Întâlniri de o durată lungă și în strânsă proximitate cu o persoană diagnosticată cu COVID-19."</string>
     <!-- XHED: App overview subtitle for glossary notifications -->
     <string name="main_overview_subtitle_glossary_notification">"Notificarea de expunere"</string>
     <!-- YTXT: App overview body for glossary notifications -->
@@ -303,7 +305,7 @@
     <!-- XMSG: risk details - get in touch with the corresponding people, something like a bullet point -->
     <string name="risk_details_behavior_body_contact_doctor">"Dacă aveți întrebări despre simptome, disponibilitatea testării sau autoizolare, contactați:"</string>
     <!-- XMSG: risk details - wash your hands, something like a bullet point -->
-    <string name="risk_details_behavior_body_wash_hands">"Spălați-vă frecvent pe mâini."</string>
+    <string name="risk_details_behavior_body_wash_hands">"Spălați-vă frecvent pe mâini cu săpun timp de 20 de secunde."</string>
     <!-- XMSG: risk details - wear a face mask, something like a bullet point -->
     <string name="risk_details_behavior_body_wear_mask">"Purtați o mască facială când întâlniți alte persoane."</string>
     <!-- XMSG: risk details - stay 1,5 away, something like a bullet point -->
@@ -408,6 +410,8 @@
     <string name="onboarding_tracing_body">"Înregistrarea în jurnal a expunerilor funcționează astfel: dispozitivul dvs. primește prin Bluetooth ID-uri aleatorii criptate ale altor utilizatori și transmite propriul dvs. ID aleatoriu către dispozitivele acestora. Această caracteristică poate fi oricând dezactivată."</string>
     <!-- YTXT: onboarding(tracing) - explain tracing -->
     <string name="onboarding_tracing_body_emphasized">"ID-urile aleatorii criptate transmit informații doar despre dată, durată și proximitatea față de alte persoane (utilizând intensitatea semnalului). Datele personale, precum numele, adresa, locația nu sunt înregistrate niciodată. Nu se pot identifica persoanele individuale."</string>
+    <!-- YTXT: onboarding(tracing) - easy language explain tracing link-->
+    <string name="onboarding_tracing_easy_language_explanation"><a href="https://www.bundesregierung.de/breg-de/themen/corona-warn-app/corona-warn-app-leichte-sprache-gebaerdensprache">"Informații despre aplicație în limbaj simplificat și în limbajul semnelor"</a></string>
     <!-- XHED: onboarding(tracing) - headline for consent information -->
     <string name="onboarding_tracing_headline_consent">"Declarație de consimțământ"</string>
     <!-- YTXT: onboarding(tracing) - body for consent information -->
@@ -427,7 +431,7 @@
     <!-- YMSI: onboarding(tracing) - dialog about background jobs -->
     <string name="onboarding_background_fetch_dialog_body">"Ați dezactivat actualizările în fundal pentru aplicația Corona-Warn. Activați actualizările în fundal pentru a utiliza înregistrarea automată în jurnal a expunerilor. Dacă nu activați actualizările în fundal, puteți porni doar manual din aplicație înregistrarea în jurnal a expunerilor. Puteți activa actualizările în fundal pentru aplicație din setările dispozitivului dvs."</string>
     <!-- XBUT: onboarding(tracing) - dialog about background jobs, open device settings -->
-    <string name="onboarding_background_fetch_dialog_button_positive">"Deschideți Setările dispozitivului"</string>
+    <string name="onboarding_background_fetch_dialog_button_positive">"Deschideți setările dispozitivului"</string>
     <!-- XBUT: onboarding(tracing) - dialog about background jobs, continue in app -->
     <string name="onboarding_background_fetch_dialog_button_negative">"Porniți manual înregistrarea în jurnal a expunerilor"</string>
     <!-- XACT: onboarding(tracing) - dialog about energy optimized header text -->
@@ -451,7 +455,7 @@
     <!-- XTXT: onboarding(tracing) - location explanation for bluetooth body text -->
     <string name="onboarding_tracing_location_body">"Locația dvs. nu poate fi accesată. Google și/sau Android necesită acces la locația dispozitivului dvs. pentru a utiliza Bluetooth-ul."</string>
     <!-- XBUT: onboarding(tracing) - button enable tracing -->
-    <string name="onboarding_tracing_location_button">"Deschideți Setările dispozitivului"</string>
+    <string name="onboarding_tracing_location_button">"Deschideți setările dispozitivului"</string>
     <!-- XACT: Onboarding (test) page title -->
     <string name="onboarding_test_accessibility_title">"Pagina de înregistrare 4 din 5: Dacă sunteți diagnosticat cu COVID-19…"</string>
     <!-- XHED: onboarding(test) - about positive tests -->
@@ -510,21 +514,21 @@
     <!--XHED : settings(tracing) - headline on card about the current status and what to do -->
     <string name="settings_tracing_status_bluetooth_headline">"Activați Bluetooth-ul"</string>
     <!-- XTXT: settings(tracing) - explains user what to do on card if bluetooth is disabled -->
-    <string name="settings_tracing_status_bluetooth_body">"Bluetooth-ul trebuie să fie pornit pentru ca înregistrarea în jurnal a expunerilor să funcționeze. Porniți Bluetooth-ul în setările dispozitivului."</string>
+    <string name="settings_tracing_status_bluetooth_body">"Bluetooth-ul trebuie să fie activat pentru ca înregistrarea în jurnal a expunerilor să funcționeze. Activați Bluetooth-ul în setările dispozitivului."</string>
     <!-- XBUT: settings(tracing) - go to operating system settings button on card -->
-    <string name="settings_tracing_status_bluetooth_button">"Deschideți Setările dispozitivului"</string>
+    <string name="settings_tracing_status_bluetooth_button">"Deschideți setările dispozitivului"</string>
     <!--XHED : settings(tracing) - headline on card about the current status and what to do -->
     <string name="settings_tracing_status_location_headline">"Permiteți accesul la locație"</string>
     <!-- XTXT: settings(tracing) - explains user what to do on card if location is disabled -->
     <string name="settings_tracing_status_location_body">"Locația dvs. nu poate fi accesată. Google și/sau Android necesită acces la locația dispozitivului dvs. pentru a utiliza Bluetooth-ul."</string>
     <!-- XBUT: settings(tracing) - go to operating system settings button on card - location -->
-    <string name="settings_tracing_status_location_button">"Deschideți Setările dispozitivului"</string>
+    <string name="settings_tracing_status_location_button">"Deschideți setările dispozitivului"</string>
     <!--XHED : settings(tracing) - headline on card about the current status and what to do -->
     <string name="settings_tracing_status_connection_headline">"Deschideți conexiunea la internet"</string>
     <!-- XTXT: settings(tracing) - explains user what to do on card if connection is disabled -->
     <string name="settings_tracing_status_connection_body">"Înregistrarea în jurnal a expunerilor necesită conexiunea la internet pentru a calcula expunerile. Porniți rețeaua Wi-Fi sau datele mobile din setările dispozitivului dvs."</string>
     <!-- XBUT: settings(tracing) - go to operating system settings button on card -->
-    <string name="settings_tracing_status_connection_button">"Deschideți Setările dispozitivului"</string>
+    <string name="settings_tracing_status_connection_button">"Deschideți setările dispozitivului"</string>
     <!-- XTXT: settings(tracing) - explains the circle progress indicator to the right with the current value -->
     <plurals name="settings_tracing_status_body_active">
         <item quantity="one">"Înregistrarea în jurnal a expunerilor a fost activă o zi.\nO verificare a expunerii poate fi de încredere doar dacă înregistrarea în jurnal a expunerilor este activată permanent."</item>
@@ -566,7 +570,7 @@
     <!-- XTXT: settings(notification) - next to a switch -->
     <string name="settings_notifications_subtitle_update_test">"Starea testului COVID-19"</string>
     <!-- XBUT: settings(notification) - go to operating settings -->
-    <string name="settings_notifications_button_open_settings">"Deschideți Setările dispozitivului"</string>
+    <string name="settings_notifications_button_open_settings">"Deschideți setările dispozitivului"</string>
     <!-- XACT: main (overview) - illustraction description, explanation image, displays notificatin status, active -->
     <string name="settings_notifications_illustration_description_active">"O femeie primește o notificare de la Corona-Warn-App."</string>
     <!-- XACT: main (overview) - illustraction description, explanation image, displays notificatin status, inactive -->
@@ -610,7 +614,7 @@
     <!-- XTXT: settings(background priority) - explains user what to do on card if background priority is enabled -->
     <string name="settings_background_priority_card_body">"Dacă doriți să dezactivați activitatea în fundal cu prioritate, vă rugăm să faceți acest lucru din setările dispozitivului."</string>
     <!-- XBUT: settings(background priority) - go to operating system settings button on card -->
-    <string name="settings_background_priority_card_button">"Deschideți Setările dispozitivului"</string>
+    <string name="settings_background_priority_card_button">"Deschideți setările dispozitivului"</string>
     <!-- XHED : settings(background priority) - headline on card about the current status and what to do -->
     <string name="settings_background_priority_card_headline">"Dezactivați activitatea în fundal cu prioritate"</string>
 
@@ -687,7 +691,11 @@
     <!-- XHED: Headline for legal information page, contact section -->
     <string name="information_legal_headline_contact">"Contact"</string>
     <!-- YTXT: subtitle for legal information page, contact section -->
-    <string name="information_legal_subtitle_contact">"E-mail: CoronaWarnApp@rki.de"<xliff:g id="line_break">"\n"</xliff:g>"Telefon: +49 30 18754 5100"</string>
+    <string name="information_legal_subtitle_contact">"E-mail: CoronaWarnApp@rki.de"</string>
+    <!-- YTXT: subtitle for legal information page, open contact form -->
+    <string name="information_legal_subtitle_contact_form"><a href="https://www.rki.de/SharedDocs/Kontaktformulare/weitere/Corona-Warn-App/Corona-Warn-App_Integrator.html">"Formular de contact"</a></string>
+    <!-- NOTR: subtitle for legal information page, open contact form for languages other than English and German -->
+    <string name="information_legal_subtitle_contact_form_non_en_de">"Contact Form in "<a href="https://www.rki.de/SharedDocs/Kontaktformulare/en/Kontaktformulare/weitere/Corona-Warn-App/Corona-Warn-App_Integrator.html">"English"</a>" or "<a href="https://www.rki.de/SharedDocs/Kontaktformulare/weitere/Corona-Warn-App/Corona-Warn-App_Integrator.html">"German"</a></string>
     <!-- XHED: Headline for legal information page, tax section -->
     <string name="information_legal_headline_taxid">"Număr de înregistrare în scop de TVA"</string>
     <!-- YTXT: subtitle for legal information page, tax section -->
@@ -730,6 +738,13 @@
     <!-- XBUT: Positive button for submission tan invalid -->
     <string name="submission_error_dialog_web_tan_invalid_button_positive">"ÃŽnapoi"</string>
 
+    <!-- XHED: Dialog title for submission tan redeemed -->
+    <string name="submission_error_dialog_web_tan_redeemed_title">"Testul are erori"</string>
+    <!-- XMSG: Dialog body for submission tan redeemed -->
+    <string name="submission_error_dialog_web_tan_redeemed_body">"A apărut o problemă la evaluarea testului dvs. Codul dvs. QR a expirat deja."</string>
+    <!-- XBUT: Positive button for submission tan redeemed -->
+    <string name="submission_error_dialog_web_tan_redeemed_button_positive">"OK"</string>
+
     <!-- Permission Rationale Dialog -->
     <!-- XHED: Dialog headline QR Scan permission rationale  -->
     <string name="submission_qr_code_scan_permission_rationale_dialog_headline">"Este necesară autorizația pentru camera foto"</string>
@@ -750,9 +765,9 @@
 
     <!-- QR Code Scan Invalid Dialog -->
     <!-- XHED: Dialog headline for invalid QR code  -->
-    <string name="submission_qr_code_scan_invalid_dialog_headline">"Cod QR incorect"</string>
+    <string name="submission_qr_code_scan_invalid_dialog_headline">"Cod QR nevalabil"</string>
     <!-- YTXT: Dialog Body text for invalid QR code -->
-    <string name="submission_qr_code_scan_invalid_dialog_body">"Codul QR nu este corect. Reîncercați."</string>
+    <string name="submission_qr_code_scan_invalid_dialog_body">"Codul QR este nevalabil sau a fost deja înregistrat pe un alt smartphone. Veți primi rezultatul testului dvs. de la centrul sau laboratorul de testare, indiferent de valabilitatea codului QR. Dacă sunteți diagnosticat cu COVID-19, veți fi notificat de autoritatea de sănătate publică."</string>
     <!-- XBUT: Dialog(Invalid QR code) - positive button (right) -->
     <string name="submission_qr_code_scan_invalid_dialog_button_positive">"Reîncercați."</string>
     <!-- XBUT: Dialog(Invalid QR code) - negative button (left) -->
@@ -799,7 +814,7 @@
     <!-- XHED: Page headline for invalid test result screen  -->
     <string name="submission_test_result_invalid_steps_invalid_heading">"Rezultatul testului dvs."</string>
     <!-- YTXT: Body text for next steps section of invalid test result-->
-    <string name="submission_test_result_invalid_steps_invalid_body">"A apărut o problemă la evaluarea testului dvs. Contactați direcția de sănătate publică pentru a afla pașii următori.\n\nȘtergeți testul din Corona-Warn-App pentru a salva un nou cod de test aici dacă este necesar."</string>
+    <string name="submission_test_result_invalid_steps_invalid_body">"A apărut o problemă la evaluarea testului dvs. Contactați centrul sau laboratorul de testare implicat pentru a afla pașii următori.\n\nȘtergeți testul din Corona-Warn-App pentru a salva un nou cod de test aici, dacă este necesar."</string>
     <!-- XBUT: invalid test result : remove the test button -->
     <string name="submission_test_result_invalid_remove_test_button">"Ștergere test"</string>
     <!-- XHED: Dialog title for tracing required dailog  -->
@@ -809,9 +824,9 @@
     <!-- XBUT: tracing required : OK button -->
     <string name="submission_test_result_dialog_tracing_required_button">"OK"</string>
     <!-- XHED: Dialog title for test removal  -->
-    <string name="submission_test_result_dialog_remove_test_title">"Ștergeți testul?"</string>
+    <string name="submission_test_result_dialog_remove_test_title">"Testul poate fi scanat o singură dată."</string>
     <!-- YTXT: Dialog text for test removal -->
-    <string name="submission_test_result_dialog_remove_test_message">"Testul va fi șters definitiv din Corona-Warn-App și nu mai poate fi adăugat din nou. Această procedură nu poate fi anulată."</string>
+    <string name="submission_test_result_dialog_remove_test_message">"Dacă ștergeți testul, nu veți mai putea afla rezultatul testului dvs. Primiți rezultatul testului dvs. de la centrul sau laboratorul de testare, independent de aplicație. Dacă sunteți diagnosticat cu COVID-19, veți fi notificat de autoritatea de sănătate publică."</string>
     <!-- XBUT: Positive button for test removal -->
     <string name="submission_test_result_dialog_remove_test_button_positive">"Eliminare"</string>
     <!-- XBUT: Negative button for test removal -->
@@ -931,7 +946,7 @@
     <!-- XHED: Page headline for contact page in submission flow -->
     <string name="submission_contact_headline">"Cum funcționează:"</string>
     <!-- YTXT: Body text for contact page in submission flow-->
-    <string name="submission_contact_body">"Vă rugăm să aveți la îndemână rezultatul testului (dacă este disponibil) și numărul de telefon pentru a solicita un cod TAN."</string>
+    <string name="submission_contact_body">"Vă rugăm să aveți la îndemână rezultatul testului (dacă este disponibil) și numărul dvs. de telefon pentru a solicita un cod TAN.\n\nPersoanele cu deficiențe de auz pot utiliza serviciile Tess Relay (interpretare între limba germană scrisă și limbajul semnelor) pentru a contacta hotline-ul telefonic. Puteți descărca software-ul din Google Play."</string>
     <!-- XBUT: submission contact call button -->
     <string name="submission_contact_button_call">"Apelare"</string>
     <!-- XBUT: submission contact enter tan button -->
diff --git a/Corona-Warn-App/src/main/res/values-tr/strings.xml b/Corona-Warn-App/src/main/res/values-tr/strings.xml
index 7e94c26db8582506445954d077de269cd36ff629..4130ff1dd6aecfeaee60f4cf362dee9deec25210 100644
--- a/Corona-Warn-App/src/main/res/values-tr/strings.xml
+++ b/Corona-Warn-App/src/main/res/values-tr/strings.xml
@@ -163,6 +163,8 @@
     <string name="risk_card_body_time_fetched">"Güncelleme: %1$s"</string>
     <!-- XTXT: risk card - next update -->
     <string name="risk_card_body_next_update">"Günlük olarak güncellenir"</string>
+    <!-- XTXT: risk card - hint to open the app daily -->
+    <string name="risk_card_body_open_daily">"Not: Risk durumunuzu güncellemek için lütfen uygulamayı her gün açın."</string>
     <!-- XBUT: risk card - update risk -->
     <string name="risk_card_button_update">"Güncelle"</string>
     <!-- XBUT: risk card - update risk with time display -->
@@ -303,7 +305,7 @@
     <!-- XMSG: risk details - get in touch with the corresponding people, something like a bullet point -->
     <string name="risk_details_behavior_body_contact_doctor">"Belirtiler, test kullanılabilirliği veya bireysel izolasyon hakkında sorularınız varsa lütfen aşağıdakilerden biri ile iletişime geçin:"</string>
     <!-- XMSG: risk details - wash your hands, something like a bullet point -->
-    <string name="risk_details_behavior_body_wash_hands">"Ellerinizi düzenli olarak yıkayın."</string>
+    <string name="risk_details_behavior_body_wash_hands">"Ellerinizi düzenli olarak 20 saniye sabunla yıkayın."</string>
     <!-- XMSG: risk details - wear a face mask, something like a bullet point -->
     <string name="risk_details_behavior_body_wear_mask">"Diğer insanlarla karşılaştığınızda yüz maskesi takın."</string>
     <!-- XMSG: risk details - stay 1,5 away, something like a bullet point -->
@@ -408,6 +410,8 @@
     <string name="onboarding_tracing_body">"Maruz kalma günlüğü, cihazınızın Bluetooth üzerinden diğer kullanıcıların şifrelenmiş rastgele kimliklerini alması ve size ait rastgele kimliği diğer kullanıcıların cihazlarına aktarmasıyla çalışır. Bu özellik dilediğiniz zaman devre dışı bırakılabilir."</string>
     <!-- YTXT: onboarding(tracing) - explain tracing -->
     <string name="onboarding_tracing_body_emphasized">"Şifrelenmiş rastgele kimlikler yalnızca tarih, süre ve yakınlık (sinyal gücünü kullanarak) hakkındaki bilgileri aktarır. Ad, adres, konum gibi kişisel veriler asla kaydedilmez. Kişilerin kimliği belirlenemez."</string>
+    <!-- YTXT: onboarding(tracing) - easy language explain tracing link-->
+    <string name="onboarding_tracing_easy_language_explanation"><a href="https://www.bundesregierung.de/breg-de/themen/corona-warn-app/corona-warn-app-leichte-sprache-gebaerdensprache">"BasitleÅŸtirilmiÅŸ Dilde ve Ä°ÅŸaret Dilinde Uygulama Bilgileri"</a></string>
     <!-- XHED: onboarding(tracing) - headline for consent information -->
     <string name="onboarding_tracing_headline_consent">"Kabul Beyanı"</string>
     <!-- YTXT: onboarding(tracing) - body for consent information -->
@@ -687,7 +691,11 @@
     <!-- XHED: Headline for legal information page, contact section -->
     <string name="information_legal_headline_contact">"Ä°letiÅŸim"</string>
     <!-- YTXT: subtitle for legal information page, contact section -->
-    <string name="information_legal_subtitle_contact">"E-posta: CoronaWarnApp@rki.de"<xliff:g id="line_break">"\n"</xliff:g>"Telefon: +49 30 18754 5100"</string>
+    <string name="information_legal_subtitle_contact">"E-posta: CoronaWarnApp@rki.de"</string>
+    <!-- YTXT: subtitle for legal information page, open contact form -->
+    <string name="information_legal_subtitle_contact_form"><a href="https://www.rki.de/SharedDocs/Kontaktformulare/weitere/Corona-Warn-App/Corona-Warn-App_Integrator.html">"Ä°letiÅŸim Formu"</a></string>
+    <!-- NOTR: subtitle for legal information page, open contact form for languages other than English and German -->
+    <string name="information_legal_subtitle_contact_form_non_en_de">"Contact Form in "<a href="https://www.rki.de/SharedDocs/Kontaktformulare/en/Kontaktformulare/weitere/Corona-Warn-App/Corona-Warn-App_Integrator.html">"English"</a>" or "<a href="https://www.rki.de/SharedDocs/Kontaktformulare/weitere/Corona-Warn-App/Corona-Warn-App_Integrator.html">"German"</a></string>
     <!-- XHED: Headline for legal information page, tax section -->
     <string name="information_legal_headline_taxid">"KDV numarası"</string>
     <!-- YTXT: subtitle for legal information page, tax section -->
@@ -730,6 +738,13 @@
     <!-- XBUT: Positive button for submission tan invalid -->
     <string name="submission_error_dialog_web_tan_invalid_button_positive">"Geri"</string>
 
+    <!-- XHED: Dialog title for submission tan redeemed -->
+    <string name="submission_error_dialog_web_tan_redeemed_title">"Testte hata var"</string>
+    <!-- XMSG: Dialog body for submission tan redeemed -->
+    <string name="submission_error_dialog_web_tan_redeemed_body">"Testinizi değerlendirirken bir problem oluştu. QR kodunuzun süresi dolmuş."</string>
+    <!-- XBUT: Positive button for submission tan redeemed -->
+    <string name="submission_error_dialog_web_tan_redeemed_button_positive">"Tamam"</string>
+
     <!-- Permission Rationale Dialog -->
     <!-- XHED: Dialog headline QR Scan permission rationale  -->
     <string name="submission_qr_code_scan_permission_rationale_dialog_headline">"Kamera yetkisi gereklidir"</string>
@@ -752,7 +767,7 @@
     <!-- XHED: Dialog headline for invalid QR code  -->
     <string name="submission_qr_code_scan_invalid_dialog_headline">"QR kod yanlış"</string>
     <!-- YTXT: Dialog Body text for invalid QR code -->
-    <string name="submission_qr_code_scan_invalid_dialog_body">"QR kod yanlış. Lütfen tekrar deneyin."</string>
+    <string name="submission_qr_code_scan_invalid_dialog_body">"QR kod yanlış veya başka bir akıllı telefona zaten kaydedilmiş. QR kod geçerli olsun veya olmasın test sonucunuzu test merkezinden veya laboratuvardan alacaksınız. COVID-19 tanısı alırsanız kamu sağlığı yetkilisi tarafından bilgilendirileceksiniz."</string>
     <!-- XBUT: Dialog(Invalid QR code) - positive button (right) -->
     <string name="submission_qr_code_scan_invalid_dialog_button_positive">"Lütfen tekrar deneyin."</string>
     <!-- XBUT: Dialog(Invalid QR code) - negative button (left) -->
@@ -799,7 +814,7 @@
     <!-- XHED: Page headline for invalid test result screen  -->
     <string name="submission_test_result_invalid_steps_invalid_heading">"Test Sonucunuz"</string>
     <!-- YTXT: Body text for next steps section of invalid test result-->
-    <string name="submission_test_result_invalid_steps_invalid_body">"Testinizi değerlendirirken bir problem oluştu. Lütfen sonraki adımlarınız için kamu sağlığı yetkilisi ile görüşün.\n\nGerekirse yeni bir test kodu kaydedebilmeniz için lütfen testi Corona-Warn-App\'ten silin."</string>
+    <string name="submission_test_result_invalid_steps_invalid_body">"Testinizi değerlendirirken bir problem oluştu. Lütfen sonraki adımlarınız için test merkezi veya laboratuvar ile görüşün.\n\nGerekirse yeni bir test kodu kaydedebilmeniz için lütfen testi Corona-Warn-App\'ten silin."</string>
     <!-- XBUT: invalid test result : remove the test button -->
     <string name="submission_test_result_invalid_remove_test_button">"Testi Sil"</string>
     <!-- XHED: Dialog title for tracing required dailog  -->
@@ -809,9 +824,9 @@
     <!-- XBUT: tracing required : OK button -->
     <string name="submission_test_result_dialog_tracing_required_button">"Tamam"</string>
     <!-- XHED: Dialog title for test removal  -->
-    <string name="submission_test_result_dialog_remove_test_title">"Test silinsin mi?"</string>
+    <string name="submission_test_result_dialog_remove_test_title">"Test yalnızca bir kez taranabilir."</string>
     <!-- YTXT: Dialog text for test removal -->
-    <string name="submission_test_result_dialog_remove_test_message">"Test kalıcı olarak Corona-Warn-App\'ten silinir ve tekrar eklenemez. Bu işlem geri alınamaz."</string>
+    <string name="submission_test_result_dialog_remove_test_message">"Testi silerseniz test sonucunuzu alamazsınız. Test sonucunuzu uygulamadan bağımsız olarak test merkezinden veya laboratuvardan alırsınız. COVID-19 tanısı alırsanız kamu sağlığı yetkilisi tarafından bilgilendirileceksiniz."</string>
     <!-- XBUT: Positive button for test removal -->
     <string name="submission_test_result_dialog_remove_test_button_positive">"Kaldır"</string>
     <!-- XBUT: Negative button for test removal -->
@@ -931,7 +946,7 @@
     <!-- XHED: Page headline for contact page in submission flow -->
     <string name="submission_contact_headline">"Nasıl çalışır?"</string>
     <!-- YTXT: Body text for contact page in submission flow-->
-    <string name="submission_contact_body">"TAN talebinde bulunmak için lütfen test sonucunuzu (varsa) ve telefon numaranızı hazır tutun."</string>
+    <string name="submission_contact_body">"TAN talebinde bulunmak için lütfen test sonucunuzu (varsa) ve telefon numaranızı hazır tutun.\n\nİşitme engeli bulunan kişiler yardım hattı ile iletişime geçmek için Tess Relay hizmetlerini (Almanca yazı dili ile işaret dili arasında tercüme) kullanabilir. Yazılımı Google Play\'den indirebilirsiniz."</string>
     <!-- XBUT: submission contact call button -->
     <string name="submission_contact_button_call">"Ara"</string>
     <!-- XBUT: submission contact enter tan button -->
diff --git a/Corona-Warn-App/src/main/res/values/strings.xml b/Corona-Warn-App/src/main/res/values/strings.xml
index 7387ba9f1f328ce845b30a5b895de03ecaba8eac..167cf47779f83b73ef523a01b2962812be9adca9 100644
--- a/Corona-Warn-App/src/main/res/values/strings.xml
+++ b/Corona-Warn-App/src/main/res/values/strings.xml
@@ -165,6 +165,8 @@
     <string name="risk_card_body_time_fetched">"Updated: %1$s"</string>
     <!-- XTXT: risk card - next update -->
     <string name="risk_card_body_next_update">"Updated daily"</string>
+    <!-- XTXT: risk card - hint to open the app daily -->
+    <string name="risk_card_body_open_daily">"Note: Please open the app daily to update your risk status."</string>
     <!-- XBUT: risk card - update risk -->
     <string name="risk_card_button_update">"Update"</string>
     <!-- XBUT: risk card - update risk with time display -->
@@ -276,7 +278,7 @@
     <!-- XHED: App overview subtitle for glossary contact  -->
     <string name="main_overview_subtitle_glossary_contact">"Exposures"</string>
     <!-- YTXT: App overview body for glossary contact -->
-    <string name="main_overview_body_glossary_contact">"Encounters over a longer duration and close proximity to people diagnosed with COVID-19."</string>
+    <string name="main_overview_body_glossary_contact">"Encounters over an extended period and in close proximity to a person diagnosed with COVID-19."</string>
     <!-- XHED: App overview subtitle for glossary notifications -->
     <string name="main_overview_subtitle_glossary_notification">"Exposure Notification"</string>
     <!-- YTXT: App overview body for glossary notifications -->
@@ -305,7 +307,7 @@
     <!-- XMSG: risk details - get in touch with the corresponding people, something like a bullet point -->
     <string name="risk_details_behavior_body_contact_doctor">"If you have questions about symptoms, testing availability, or self-isolation, please contact one of the following:"</string>
     <!-- XMSG: risk details - wash your hands, something like a bullet point -->
-    <string name="risk_details_behavior_body_wash_hands">"Wash your hands regularly."</string>
+    <string name="risk_details_behavior_body_wash_hands">"Wash your hands regularly, with soap, for 20 seconds."</string>
     <!-- XMSG: risk details - wear a face mask, something like a bullet point -->
     <string name="risk_details_behavior_body_wear_mask">"Wear a face mask when you encounter other people."</string>
     <!-- XMSG: risk details - stay 1,5 away, something like a bullet point -->
@@ -410,6 +412,8 @@
     <string name="onboarding_tracing_body">"Exposure logging works by your device receiving, via Bluetooth, encrypted random IDs of other users and passing your own random ID to their devices. This feature can be deactivated at any time."</string>
     <!-- YTXT: onboarding(tracing) - explain tracing -->
     <string name="onboarding_tracing_body_emphasized">"The encrypted random IDs only pass information about date, duration and proximity (using signal strength) to other people. Personal data such as name, address, location is never recorded. Individuals cannot be identified."</string>
+    <!-- YTXT: onboarding(tracing) - easy language explain tracing link-->
+    <string name="onboarding_tracing_easy_language_explanation"><a href="https://www.bundesregierung.de/breg-de/themen/corona-warn-app/corona-warn-app-leichte-sprache-gebaerdensprache">"App Information in Simplified Language and Sign Language"</a></string>
     <!-- XHED: onboarding(tracing) - headline for consent information -->
     <string name="onboarding_tracing_headline_consent">"Declaration of Consent"</string>
     <!-- YTXT: onboarding(tracing) - body for consent information -->
@@ -689,7 +693,11 @@
     <!-- XHED: Headline for legal information page, contact section -->
     <string name="information_legal_headline_contact">"Contact"</string>
     <!-- YTXT: subtitle for legal information page, contact section -->
-    <string name="information_legal_subtitle_contact">"E-Mail: CoronaWarnApp@rki.de"<xliff:g id="line_break">"\n"</xliff:g>"Telephone: +49 30 18754 5100"</string>
+    <string name="information_legal_subtitle_contact">"E-mail: CoronaWarnApp@rki.de"</string>
+    <!-- YTXT: subtitle for legal information page, open contact form -->
+    <string name="information_legal_subtitle_contact_form"><a href="https://www.rki.de/SharedDocs/Kontaktformulare/weitere/Corona-Warn-App/Corona-Warn-App_Integrator.html">"Contact Form"</a></string>
+    <!-- NOTR: subtitle for legal information page, open contact form for languages other than English and German -->
+    <string name="information_legal_subtitle_contact_form_non_en_de">"Contact Form in "<a href="https://www.rki.de/SharedDocs/Kontaktformulare/en/Kontaktformulare/weitere/Corona-Warn-App/Corona-Warn-App_Integrator.html">"English"</a>" or "<a href="https://www.rki.de/SharedDocs/Kontaktformulare/weitere/Corona-Warn-App/Corona-Warn-App_Integrator.html">"German"</a></string>
     <!-- XHED: Headline for legal information page, tax section -->
     <string name="information_legal_headline_taxid">"VAT identification number"</string>
     <!-- YTXT: subtitle for legal information page, tax section -->
@@ -732,6 +740,13 @@
     <!-- XBUT: Positive button for submission tan invalid -->
     <string name="submission_error_dialog_web_tan_invalid_button_positive">"Back"</string>
 
+    <!-- XHED: Dialog title for submission tan redeemed -->
+    <string name="submission_error_dialog_web_tan_redeemed_title">"Test has errors"</string>
+    <!-- XMSG: Dialog body for submission tan redeemed -->
+    <string name="submission_error_dialog_web_tan_redeemed_body">"There was a problem evaluating your test. Your QR code has already expired."</string>
+    <!-- XBUT: Positive button for submission tan redeemed -->
+    <string name="submission_error_dialog_web_tan_redeemed_button_positive">"OK"</string>
+
     <!-- Permission Rationale Dialog -->
     <!-- XHED: Dialog headline QR Scan permission rationale  -->
     <string name="submission_qr_code_scan_permission_rationale_dialog_headline">"Camera authorization required"</string>
@@ -752,9 +767,9 @@
 
     <!-- QR Code Scan Invalid Dialog -->
     <!-- XHED: Dialog headline for invalid QR code  -->
-    <string name="submission_qr_code_scan_invalid_dialog_headline">"Incorrect QR code"</string>
+    <string name="submission_qr_code_scan_invalid_dialog_headline">"QR code is invalid"</string>
     <!-- YTXT: Dialog Body text for invalid QR code -->
-    <string name="submission_qr_code_scan_invalid_dialog_body">"The QR code is not correct. Please try again."</string>
+    <string name="submission_qr_code_scan_invalid_dialog_body">"The QR code is invalid or has been registered on another smartphone already. You will receive your test result from the test center or laboratory regardless of the validity of the QR code. If you are diagnosed with COVID-19, you will be notified by the public health authority."</string>
     <!-- XBUT: Dialog(Invalid QR code) - positive button (right) -->
     <string name="submission_qr_code_scan_invalid_dialog_button_positive">"Please try again."</string>
     <!-- XBUT: Dialog(Invalid QR code) - negative button (left) -->
@@ -801,7 +816,7 @@
     <!-- XHED: Page headline for invalid test result screen  -->
     <string name="submission_test_result_invalid_steps_invalid_heading">"Your Test Result"</string>
     <!-- YTXT: Body text for next steps section of invalid test result-->
-    <string name="submission_test_result_invalid_steps_invalid_body">"There was a problem evaluating your test. Please contact the public health authority to find out how to proceed.\n\nPlease delete the test from your Corona-Warn-App so that you will be able to save a new test code there, if necessary."</string>
+    <string name="submission_test_result_invalid_steps_invalid_body">"There was a problem evaluating your test. Please contact the test center or laboratory involved to find out how to proceed.\n\nPlease delete the test from your Corona-Warn-App so that you will be able to save a new test code there, if necessary."</string>
     <!-- XBUT: invalid test result : remove the test button -->
     <string name="submission_test_result_invalid_remove_test_button">"Delete Test"</string>
     <!-- XHED: Dialog title for tracing required dailog  -->
@@ -811,9 +826,9 @@
     <!-- XBUT: tracing required : OK button -->
     <string name="submission_test_result_dialog_tracing_required_button">"OK"</string>
     <!-- XHED: Dialog title for test removal  -->
-    <string name="submission_test_result_dialog_remove_test_title">"Delete the test?"</string>
+    <string name="submission_test_result_dialog_remove_test_title">"The test can only be scanned once."</string>
     <!-- YTXT: Dialog text for test removal -->
-    <string name="submission_test_result_dialog_remove_test_message">"The test will be permanently deleted from the Corona-Warn-App and cannot be added again. This procedure cannot be undone."</string>
+    <string name="submission_test_result_dialog_remove_test_message">"If you delete the test, you can no longer retrieve your test result. You receive your test result from the test center or laboratory, independently of the app. If you are diagnosed with COVID-19, you will be notified by the public health authority."</string>
     <!-- XBUT: Positive button for test removal -->
     <string name="submission_test_result_dialog_remove_test_button_positive">"Remove"</string>
     <!-- XBUT: Negative button for test removal -->
@@ -933,7 +948,7 @@
     <!-- XHED: Page headline for contact page in submission flow -->
     <string name="submission_contact_headline">"How this works:"</string>
     <!-- YTXT: Body text for contact page in submission flow-->
-    <string name="submission_contact_body">"Please keep your test result (if available) and your phone number ready to request a TAN."</string>
+    <string name="submission_contact_body">"Please keep your test result (if available) and your phone number ready to request a TAN.\n\nPeople with hearing impairments can use Tess Relay services (interpreting between German written language and sign language) to contact the phone hotline. You can download the software from Google Play."</string>
     <!-- XBUT: submission contact call button -->
     <string name="submission_contact_button_call">"Call"</string>
     <!-- XBUT: submission contact enter tan button -->
diff --git a/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/http/playbook/PlaybookImplTest.kt b/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/http/playbook/PlaybookImplTest.kt
new file mode 100644
index 0000000000000000000000000000000000000000..60cf0a738269c3df3724c686ea7aba3c42f3c918
--- /dev/null
+++ b/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/http/playbook/PlaybookImplTest.kt
@@ -0,0 +1,164 @@
+package de.rki.coronawarnapp.http.playbook
+
+import de.rki.coronawarnapp.exception.http.InternalServerErrorException
+import de.rki.coronawarnapp.service.submission.KeyType
+import de.rki.coronawarnapp.util.newWebRequestBuilder
+import kotlinx.coroutines.runBlocking
+import okhttp3.mockwebserver.MockResponse
+import okhttp3.mockwebserver.MockWebServer
+import org.hamcrest.MatcherAssert.assertThat
+import org.hamcrest.Matchers
+import org.hamcrest.Matchers.equalTo
+import org.junit.Assert.fail
+import org.junit.Test
+
+class PlaybookImplTest {
+
+    @Test
+    fun hasRequestPattern_initialRegistration(): Unit = runBlocking {
+        val server = MockWebServer()
+        server.start()
+
+        server.enqueue(MockResponse().setBody("""{"registrationToken":"response"}"""))
+        server.enqueue(MockResponse().setBody("{}"))
+        server.enqueue(MockResponse().setBody("{}"))
+
+        PlaybookImpl(server.newWebRequestBuilder())
+            .initialRegistration("9A3B578UMG", KeyType.TELETAN)
+
+        // ensure request order is 2x verification and 1x submission
+        assertRequestPattern(server)
+    }
+
+    @Test
+    fun hasRequestPattern_submission(): Unit = runBlocking {
+        val server = MockWebServer()
+        server.start()
+
+        server.enqueue(MockResponse().setBody("""{"tan":"response"}"""))
+        server.enqueue(MockResponse().setBody("{}"))
+        server.enqueue(MockResponse().setBody("{}"))
+
+        PlaybookImpl(server.newWebRequestBuilder())
+            .submission("token", listOf())
+
+        // ensure request order is 2x verification and 1x submission
+        assertRequestPattern(server)
+    }
+
+    @Test
+    fun hasRequestPattern_testResult(): Unit = runBlocking {
+        val server = MockWebServer()
+        server.start()
+
+        server.enqueue(MockResponse().setBody("""{"testResult":0}"""))
+        server.enqueue(MockResponse().setBody("{}"))
+        server.enqueue(MockResponse().setBody("{}"))
+
+        PlaybookImpl(server.newWebRequestBuilder())
+            .testResult("token")
+
+        // ensure request order is 2x verification and 1x submission
+        assertRequestPattern(server)
+    }
+
+    @Test
+    fun hasRequestPattern_dummy(): Unit = runBlocking {
+        val server = MockWebServer()
+        server.start()
+
+        server.enqueue(MockResponse().setBody("{}"))
+        server.enqueue(MockResponse().setBody("{}"))
+        server.enqueue(MockResponse().setBody("{}"))
+
+        PlaybookImpl(server.newWebRequestBuilder())
+            .dummy()
+
+        // ensure request order is 2x verification and 1x submission
+        assertRequestPattern(server)
+    }
+
+    @Test
+    fun shouldIgnoreFailuresForDummyRequests(): Unit = runBlocking {
+        val server = MockWebServer()
+        server.start()
+
+        val expectedRegistrationToken = "token"
+        server.enqueue(MockResponse().setBody("""{"registrationToken":"$expectedRegistrationToken"}"""))
+        server.enqueue(MockResponse().setResponseCode(500))
+        server.enqueue(MockResponse().setResponseCode(500))
+
+        val registrationToken = PlaybookImpl(server.newWebRequestBuilder())
+            .initialRegistration("key", KeyType.GUID)
+
+        assertThat(registrationToken, equalTo(expectedRegistrationToken))
+    }
+
+    @Test
+    fun hasRequestPatternWhenRealRequestFails_initialRegistration(): Unit = runBlocking {
+        val server = MockWebServer()
+        server.start()
+
+        server.enqueue(MockResponse().setResponseCode(500))
+        server.enqueue(MockResponse().setBody("{}"))
+        server.enqueue(MockResponse().setBody("{}"))
+
+        try {
+
+            PlaybookImpl(server.newWebRequestBuilder())
+                .initialRegistration("9A3B578UMG", KeyType.TELETAN)
+            fail("exception propagation expected")
+        } catch (e: InternalServerErrorException) {
+        }
+
+        // ensure request order is 2x verification and 1x submission
+        assertRequestPattern(server)
+    }
+
+    @Test
+    fun hasRequestPatternWhenRealRequestFails_testResult(): Unit = runBlocking {
+        val server = MockWebServer()
+        server.start()
+
+        server.enqueue(MockResponse().setResponseCode(500))
+        server.enqueue(MockResponse().setBody("{}"))
+        server.enqueue(MockResponse().setBody("{}"))
+
+        try {
+
+            PlaybookImpl(server.newWebRequestBuilder())
+                .testResult("token")
+            fail("exception propagation expected")
+        } catch (e: InternalServerErrorException) {
+        }
+
+        // ensure request order is 2x verification and 1x submission
+        assertRequestPattern(server)
+    }
+
+    @Test
+    fun hasRequestPatternWhenRealRequestFails_submission(): Unit = runBlocking {
+        val server = MockWebServer()
+        server.start()
+
+        server.enqueue(MockResponse().setResponseCode(500))
+        server.enqueue(MockResponse().setBody("{}"))
+        server.enqueue(MockResponse().setBody("{}"))
+
+        try {
+            PlaybookImpl(server.newWebRequestBuilder())
+                .submission("token", listOf())
+            fail("exception propagation expected")
+        } catch (e: InternalServerErrorException) {
+        }
+
+        // ensure request order is 2x verification and 1x submission
+        assertRequestPattern(server)
+    }
+
+    private fun assertRequestPattern(server: MockWebServer) {
+        assertThat(server.takeRequest().path, Matchers.startsWith("/verification/"))
+        assertThat(server.takeRequest().path, Matchers.startsWith("/verification/"))
+        assertThat(server.takeRequest().path, Matchers.startsWith("/submission/"))
+    }
+}
diff --git a/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/http/service/SubmissionServiceTest.kt b/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/http/service/SubmissionServiceTest.kt
new file mode 100644
index 0000000000000000000000000000000000000000..d8eae0c49d434fdee968072fa9afb1302672df73
--- /dev/null
+++ b/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/http/service/SubmissionServiceTest.kt
@@ -0,0 +1,43 @@
+package de.rki.coronawarnapp.http.service
+
+import de.rki.coronawarnapp.util.headerSizeIgnoringContentLength
+import de.rki.coronawarnapp.util.newWebRequestBuilder
+import kotlinx.coroutines.runBlocking
+import okhttp3.mockwebserver.MockResponse
+import okhttp3.mockwebserver.MockWebServer
+import org.junit.Assert
+import org.junit.Test
+
+class SubmissionServiceTest {
+
+    @Test
+    fun allRequestHaveSameFootprintForPlausibleDeniability(): Unit = runBlocking {
+
+        val server = MockWebServer()
+        server.start()
+
+        val webRequestBuilder = server.newWebRequestBuilder()
+
+        val authCodeExample = "39ec4930-7a1f-4d5d-921f-bfad3b6f1269"
+
+        server.enqueue(MockResponse().setBody("{}"))
+        webRequestBuilder.asyncSubmitKeysToServer(authCodeExample, listOf())
+
+        server.enqueue(MockResponse().setBody("{}"))
+        webRequestBuilder.asyncFakeSubmission()
+
+        val requests = listOf(
+            server.takeRequest(),
+            server.takeRequest()
+        )
+
+        // ensure all request have same size (header & body)
+        requests.zipWithNext().forEach { (a, b) ->
+            Assert.assertEquals(
+                "Header size mismatch: ",
+                a.headerSizeIgnoringContentLength(),
+                b.headerSizeIgnoringContentLength()
+            )
+        }
+    }
+}
diff --git a/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/http/service/VerificationServiceTest.kt b/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/http/service/VerificationServiceTest.kt
new file mode 100644
index 0000000000000000000000000000000000000000..3dde34e4171d63c625a2d6db9a50acb6f19d2ee2
--- /dev/null
+++ b/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/http/service/VerificationServiceTest.kt
@@ -0,0 +1,60 @@
+package de.rki.coronawarnapp.http.service
+
+import de.rki.coronawarnapp.service.submission.KeyType
+import de.rki.coronawarnapp.util.headerSizeIgnoringContentLength
+import de.rki.coronawarnapp.util.newWebRequestBuilder
+import kotlinx.coroutines.runBlocking
+import okhttp3.mockwebserver.MockResponse
+import okhttp3.mockwebserver.MockWebServer
+import org.hamcrest.MatcherAssert.assertThat
+import org.hamcrest.Matchers.equalTo
+import org.junit.Test
+
+class VerificationServiceTest {
+
+    @Test
+    fun allRequestHaveSameFootprintForPlausibleDeniability(): Unit = runBlocking {
+
+        val server = MockWebServer()
+        server.start()
+
+        val webRequestBuilder = server.newWebRequestBuilder()
+
+        val guidExample = "3BF1D4-1C6003DD-733D-41F1-9F30-F85FA7406BF7"
+        val teletanExample = "9A3B578UMG"
+        val registrationTokenExample = "63b4d3ff-e0de-4bd4-90c1-17c2bb683a2f"
+
+        server.enqueue(MockResponse().setBody("{}"))
+        webRequestBuilder.asyncGetRegistrationToken(guidExample, KeyType.GUID)
+
+        server.enqueue(MockResponse().setBody("{}"))
+        webRequestBuilder.asyncGetRegistrationToken(teletanExample, KeyType.TELETAN)
+
+        server.enqueue(MockResponse().setBody("{}"))
+        webRequestBuilder.asyncGetTestResult(registrationTokenExample)
+
+        server.enqueue(MockResponse().setBody("{}"))
+        webRequestBuilder.asyncGetTan(registrationTokenExample)
+
+        server.enqueue(MockResponse().setBody("{}"))
+        webRequestBuilder.asyncFakeVerification()
+
+        val requests = listOf(
+            server.takeRequest(),
+            server.takeRequest(),
+            server.takeRequest(),
+            server.takeRequest(),
+            server.takeRequest()
+        )
+
+        // ensure all request have same size (header & body)
+        requests.forEach { assertThat(it.bodySize, equalTo(250L)) }
+
+        requests.zipWithNext().forEach { (a, b) ->
+            assertThat(
+                a.headerSizeIgnoringContentLength(),
+                equalTo(b.headerSizeIgnoringContentLength())
+            )
+        }
+    }
+}
diff --git a/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/service/diagnosiskey/DiagnosisKeyConstantsTest.kt b/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/service/diagnosiskey/DiagnosisKeyConstantsTest.kt
index a81429b89ffb85e8b111da534c4226365966a713..a7a85c268817a012eb0d012de8aea2703a1935a5 100644
--- a/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/service/diagnosiskey/DiagnosisKeyConstantsTest.kt
+++ b/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/service/diagnosiskey/DiagnosisKeyConstantsTest.kt
@@ -9,15 +9,15 @@ class DiagnosisKeyConstantsTest {
     fun allDiagnosisKeyConstants() {
         Assert.assertEquals(DiagnosisKeyConstants.HOUR, "hour")
         Assert.assertEquals(DiagnosisKeyConstants.SERVER_ERROR_CODE_403, 403)
-        Assert.assertEquals(DiagnosisKeyConstants.INDEX_DOWNLOAD_URL, "/version/v1/index.txt")
-        Assert.assertEquals(DiagnosisKeyConstants.DIAGNOSIS_KEYS_DOWNLOAD_URL, "/version/v1/diagnosis-keys")
-        Assert.assertEquals(DiagnosisKeyConstants.DIAGNOSIS_KEYS_SUBMISSION_URL, "/version/v1/diagnosis-keys")
-        Assert.assertEquals(DiagnosisKeyConstants.PARAMETERS_COUNTRY_DOWNLOAD_URL, "/version/v1/parameters/country")
-        Assert.assertEquals(DiagnosisKeyConstants.APPCONFIG_COUNTRY_DOWNLOAD_URL, "/version/v1/configuration/country")
+        Assert.assertEquals(DiagnosisKeyConstants.INDEX_DOWNLOAD_URL, "version/v1/index.txt")
+        Assert.assertEquals(DiagnosisKeyConstants.DIAGNOSIS_KEYS_DOWNLOAD_URL, "version/v1/diagnosis-keys")
+        Assert.assertEquals(DiagnosisKeyConstants.DIAGNOSIS_KEYS_SUBMISSION_URL, "version/v1/diagnosis-keys")
+        Assert.assertEquals(DiagnosisKeyConstants.PARAMETERS_COUNTRY_DOWNLOAD_URL, "version/v1/parameters/country")
+        Assert.assertEquals(DiagnosisKeyConstants.APPCONFIG_COUNTRY_DOWNLOAD_URL, "version/v1/configuration/country")
         Assert.assertEquals(
             DiagnosisKeyConstants.COUNTRY_APPCONFIG_DOWNLOAD_URL,
-            "/version/v1/configuration/country/DE/app_config"
+            "version/v1/configuration/country/DE/app_config"
         )
-        Assert.assertEquals(DiagnosisKeyConstants.AVAILABLE_DATES_URL, "/version/v1/diagnosis-keys/country/DE/date")
+        Assert.assertEquals(DiagnosisKeyConstants.AVAILABLE_DATES_URL, "version/v1/diagnosis-keys/country/DE/date")
     }
 }
diff --git a/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/service/submission/SubmissionConstantsTest.kt b/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/service/submission/SubmissionConstantsTest.kt
index a26f301262271fcff02d4f93d918306ce3d9f810..98efa5fec86386ae2035ec6699f6a62b743e42b0 100644
--- a/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/service/submission/SubmissionConstantsTest.kt
+++ b/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/service/submission/SubmissionConstantsTest.kt
@@ -7,8 +7,10 @@ class SubmissionConstantsTest {
 
     @Test
     fun allSubmissionConstants() {
-        Assert.assertEquals(SubmissionConstants.QR_CODE_KEY_TYPE, "GUID")
-        Assert.assertEquals(SubmissionConstants.TELE_TAN_KEY_TYPE, "TELETAN")
+        // TODO: Should we really keep these now?
+        Assert.assertEquals(KeyType.GUID.name, "GUID")
+        Assert.assertEquals(KeyType.TELETAN.name, "TELETAN")
+
         Assert.assertEquals(SubmissionConstants.REGISTRATION_TOKEN_URL, "version/v1/registrationToken")
         Assert.assertEquals(SubmissionConstants.TEST_RESULT_URL, "version/v1/testresult")
         Assert.assertEquals(SubmissionConstants.TAN_REQUEST_URL, "version/v1/tan")
@@ -18,5 +20,11 @@ class SubmissionConstantsTest {
         Assert.assertEquals(SubmissionConstants.GUID_SEPARATOR, '?')
 
         Assert.assertEquals(SubmissionConstants.SERVER_ERROR_CODE_400, 400)
+
+        // dummy token passes server verification
+        Assert.assertTrue(
+            Regex("^[a-f0-9]{8}-[a-f0-9]{4}-4[a-f0-9]{3}-[89aAbB][a-f0-9]{3}-[a-f0-9]{12}\$")
+                .matches(SubmissionConstants.DUMMY_REGISTRATION_TOKEN)
+        )
     }
 }
diff --git a/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/service/submission/SubmissionServiceTest.kt b/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/service/submission/SubmissionServiceTest.kt
index f086a73f7ab9354afd7587edaf436ee61a765dae..9d1f958c6895c1dcac2e4984294c9e00e769e83a 100644
--- a/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/service/submission/SubmissionServiceTest.kt
+++ b/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/service/submission/SubmissionServiceTest.kt
@@ -3,12 +3,15 @@ package de.rki.coronawarnapp.service.submission
 import de.rki.coronawarnapp.exception.NoGUIDOrTANSetException
 import de.rki.coronawarnapp.exception.NoRegistrationTokenSetException
 import de.rki.coronawarnapp.http.WebRequestBuilder
+import de.rki.coronawarnapp.http.playbook.BackgroundNoise
 import de.rki.coronawarnapp.storage.LocalData
 import de.rki.coronawarnapp.transaction.SubmitDiagnosisKeysTransaction
 import de.rki.coronawarnapp.util.formatter.TestResult
+import io.mockk.MockKAnnotations
 import io.mockk.Runs
 import io.mockk.coEvery
 import io.mockk.every
+import io.mockk.impl.annotations.MockK
 import io.mockk.just
 import io.mockk.mockkObject
 import io.mockk.verify
@@ -22,11 +25,23 @@ class SubmissionServiceTest {
     private val guid = "123456-12345678-1234-4DA7-B166-B86D85475064"
     private val registrationToken = "asdjnskjfdniuewbheboqudnsojdff"
 
+    @MockK
+    private lateinit var webRequestBuilder: WebRequestBuilder
+
+    @MockK
+    private lateinit var backgroundNoise: BackgroundNoise
+
     @Before
     fun setUp() {
-        mockkObject(LocalData)
-        mockkObject(WebRequestBuilder)
+        MockKAnnotations.init(this)
+        mockkObject(WebRequestBuilder.Companion)
+        every { WebRequestBuilder.getInstance() } returns webRequestBuilder
+
+        mockkObject(BackgroundNoise.Companion)
+        every { BackgroundNoise.getInstance() } returns backgroundNoise
+
         mockkObject(SubmitDiagnosisKeysTransaction)
+        mockkObject(LocalData)
 
         every { LocalData.teletan() } returns null
         every { LocalData.testGUID() } returns null
@@ -49,9 +64,9 @@ class SubmissionServiceTest {
         every { LocalData.devicePairingSuccessfulTimestamp(any()) } just Runs
 
         coEvery {
-            WebRequestBuilder.getInstance()
-                .asyncGetRegistrationToken(any(), SubmissionConstants.QR_CODE_KEY_TYPE)
+            webRequestBuilder.asyncGetRegistrationToken(any(), KeyType.GUID)
         } returns registrationToken
+        every { backgroundNoise.scheduleDummyPattern() } just Runs
 
         runBlocking {
             SubmissionService.asyncRegisterDevice()
@@ -61,6 +76,7 @@ class SubmissionServiceTest {
             LocalData.registrationToken(registrationToken)
             LocalData.devicePairingSuccessfulTimestamp(any())
             LocalData.testGUID(null)
+            backgroundNoise.scheduleDummyPattern()
         }
     }
 
@@ -73,9 +89,9 @@ class SubmissionServiceTest {
         every { LocalData.devicePairingSuccessfulTimestamp(any()) } just Runs
 
         coEvery {
-            WebRequestBuilder.getInstance()
-                .asyncGetRegistrationToken(any(), SubmissionConstants.TELE_TAN_KEY_TYPE)
+            webRequestBuilder.asyncGetRegistrationToken(any(), KeyType.TELETAN)
         } returns registrationToken
+        every { backgroundNoise.scheduleDummyPattern() } just Runs
 
         runBlocking {
             SubmissionService.asyncRegisterDevice()
@@ -85,6 +101,7 @@ class SubmissionServiceTest {
             LocalData.registrationToken(registrationToken)
             LocalData.devicePairingSuccessfulTimestamp(any())
             LocalData.teletan(null)
+            backgroundNoise.scheduleDummyPattern()
         }
     }
 
@@ -98,9 +115,7 @@ class SubmissionServiceTest {
     @Test
     fun requestTestResultSucceeds() {
         every { LocalData.registrationToken() } returns registrationToken
-        coEvery {
-            WebRequestBuilder.getInstance().asyncGetTestResult(registrationToken)
-        } returns TestResult.NEGATIVE.value
+        coEvery { webRequestBuilder.asyncGetTestResult(registrationToken) } returns TestResult.NEGATIVE.value
 
         runBlocking {
             assertThat(SubmissionService.asyncRequestTestResult(), equalTo(TestResult.NEGATIVE))
diff --git a/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/storage/ExposureSummaryRepositoryTest.kt b/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/storage/ExposureSummaryRepositoryTest.kt
index 0fbfc2dcf9d916426dbe26b8fed14690e341295a..b4a6ffd64b8a5ba18289f74bd437da2b0d63e769 100644
--- a/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/storage/ExposureSummaryRepositoryTest.kt
+++ b/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/storage/ExposureSummaryRepositoryTest.kt
@@ -1,17 +1,20 @@
 package de.rki.coronawarnapp.storage
 
 import com.google.android.gms.nearby.exposurenotification.ExposureSummary
+import de.rki.coronawarnapp.nearby.InternalExposureNotificationClient
 import io.mockk.MockKAnnotations
 import io.mockk.coEvery
 import io.mockk.coVerify
 import io.mockk.every
 import io.mockk.impl.annotations.MockK
 import io.mockk.mockk
+import io.mockk.mockkObject
 import io.mockk.unmockkAll
 import kotlinx.coroutines.runBlocking
 import org.junit.After
 import org.junit.Before
 import org.junit.Test
+import java.util.UUID
 
 /**
  * ExposureSummaryRepository test.
@@ -27,6 +30,10 @@ class ExposureSummaryRepositoryTest {
         MockKAnnotations.init(this)
         repository = ExposureSummaryRepository(dao)
 
+        mockkObject(InternalExposureNotificationClient)
+        coEvery { InternalExposureNotificationClient.asyncGetExposureSummary(any()) } returns buildSummary()
+        coEvery { InternalExposureNotificationClient.asyncIsEnabled() } returns true
+
         coEvery { dao.getExposureSummaryEntities() } returns listOf()
         coEvery { dao.getLatestExposureSummary() } returns null
         coEvery { dao.insertExposureSummaryEntity(any()) } returns 0
@@ -52,10 +59,11 @@ class ExposureSummaryRepositoryTest {
     @Test
     fun testGetLatest() {
         runBlocking {
-            repository.getLatestExposureSummary()
+            val token = UUID.randomUUID().toString()
+            repository.getLatestExposureSummary(token)
 
             coVerify {
-                dao.getLatestExposureSummary()
+                InternalExposureNotificationClient.asyncGetExposureSummary(token)
             }
         }
     }
@@ -81,6 +89,22 @@ class ExposureSummaryRepositoryTest {
         }
     }
 
+    private fun buildSummary(
+        maxRisk: Int = 0,
+        lowAttenuation: Int = 0,
+        midAttenuation: Int = 0,
+        highAttenuation: Int = 0
+    ): ExposureSummary {
+        val intArray = IntArray(3)
+        intArray[0] = lowAttenuation
+        intArray[1] = midAttenuation
+        intArray[2] = highAttenuation
+        return ExposureSummary.ExposureSummaryBuilder()
+            .setMaximumRiskScore(maxRisk)
+            .setAttenuationDurations(intArray)
+            .build()
+    }
+
     @After
     fun cleanUp() {
         unmockkAll()
diff --git a/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/transaction/RiskLevelTransactionTest.kt b/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/transaction/RiskLevelTransactionTest.kt
index 288032cc3c743718d8a121865f65309fa775b5f1..3e30b2306e42f8d187ff9b35f8ba487b8d87c71d 100644
--- a/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/transaction/RiskLevelTransactionTest.kt
+++ b/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/transaction/RiskLevelTransactionTest.kt
@@ -34,6 +34,7 @@ import kotlinx.coroutines.runBlocking
 import org.junit.After
 import org.junit.Before
 import org.junit.Test
+import java.util.UUID
 import java.util.concurrent.TimeUnit
 
 class RiskLevelTransactionTest {
@@ -68,6 +69,7 @@ class RiskLevelTransactionTest {
         every { RiskLevel.riskLevelChangedBetweenLowAndHigh(any(), any()) } returns false
         every { LocalData.lastTimeRiskLevelCalculation() } returns System.currentTimeMillis()
         every { LocalData.lastTimeRiskLevelCalculation(any()) } just Runs
+        every { LocalData.googleApiToken() } returns UUID.randomUUID().toString()
         every { ConnectivityHelper.isNetworkEnabled(any()) } returns true
         every { CoronaWarnApplication.getAppContext() } returns context
     }
@@ -247,7 +249,7 @@ class RiskLevelTransactionTest {
 
         // the risk score of the last exposure summary is above the high min threshold
         coEvery { ApplicationConfigurationService.asyncRetrieveApplicationConfiguration() } returns testAppConfig
-        coEvery { esRepositoryMock.getLatestExposureSummary() } returns testExposureSummary
+        coEvery { InternalExposureNotificationClient.asyncGetExposureSummary(any()) } returns testExposureSummary
 
         runBlocking {
 
@@ -309,7 +311,7 @@ class RiskLevelTransactionTest {
 
         // the exposure summary risk score is not below high min score
         coEvery { ApplicationConfigurationService.asyncRetrieveApplicationConfiguration() } returns testAppConfig
-        coEvery { esRepositoryMock.getLatestExposureSummary() } returns testExposureSummary
+        coEvery { InternalExposureNotificationClient.asyncGetExposureSummary(any()) } returns testExposureSummary
 
         runBlocking {
 
@@ -373,7 +375,7 @@ class RiskLevelTransactionTest {
         every { TimeVariables.getTimeActiveTracingDuration() } returns twoHoursAboveMinActiveTracingDuration
 
         coEvery { ApplicationConfigurationService.asyncRetrieveApplicationConfiguration() } returns testAppConfig
-        coEvery { esRepositoryMock.getLatestExposureSummary() } returns testExposureSummary
+        coEvery { InternalExposureNotificationClient.asyncGetExposureSummary(any()) } returns testExposureSummary
 
         runBlocking {
 
diff --git a/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/transaction/SubmitDiagnosisKeysTransactionTest.kt b/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/transaction/SubmitDiagnosisKeysTransactionTest.kt
index 60bef8b27d0be54040c8009818e7aa47b992682d..c43d6b9ebd0d1fc9e9c3ef6d4cb9925941e5317f 100644
--- a/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/transaction/SubmitDiagnosisKeysTransactionTest.kt
+++ b/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/transaction/SubmitDiagnosisKeysTransactionTest.kt
@@ -2,15 +2,18 @@ package de.rki.coronawarnapp.transaction
 
 import KeyExportFormat
 import com.google.android.gms.nearby.exposurenotification.TemporaryExposureKey
+import de.rki.coronawarnapp.http.WebRequestBuilder
+import de.rki.coronawarnapp.http.playbook.BackgroundNoise
 import de.rki.coronawarnapp.nearby.InternalExposureNotificationClient
-import de.rki.coronawarnapp.service.diagnosiskey.DiagnosisKeyService
 import de.rki.coronawarnapp.service.submission.SubmissionService
 import de.rki.coronawarnapp.storage.LocalData
 import de.rki.coronawarnapp.worker.BackgroundWorkScheduler
+import io.mockk.MockKAnnotations
 import io.mockk.Runs
 import io.mockk.coEvery
 import io.mockk.coVerifyOrder
 import io.mockk.every
+import io.mockk.impl.annotations.MockK
 import io.mockk.just
 import io.mockk.mockkObject
 import io.mockk.slot
@@ -23,30 +26,45 @@ import org.junit.Before
 import org.junit.Test
 
 class SubmitDiagnosisKeysTransactionTest {
+
+    @MockK
+    private lateinit var webRequestBuilder: WebRequestBuilder
+
+    @MockK
+    private lateinit var backgroundNoise: BackgroundNoise
+
     private val authString = "authString"
+    private val registrationToken = "123"
 
     @Before
     fun setUp() {
+        MockKAnnotations.init(this)
+
+        mockkObject(WebRequestBuilder.Companion)
+        every { WebRequestBuilder.getInstance() } returns webRequestBuilder
+
+        mockkObject(BackgroundNoise.Companion)
+        every { BackgroundNoise.getInstance() } returns backgroundNoise
+
         mockkObject(LocalData)
         mockkObject(SubmissionService)
         mockkObject(InternalExposureNotificationClient)
-        mockkObject(DiagnosisKeyService)
         mockkObject(BackgroundWorkScheduler)
         every { BackgroundWorkScheduler.stopWorkScheduler() } just Runs
         every { LocalData.numberOfSuccessfulSubmissions(any()) } just Runs
-        coEvery { SubmissionService.asyncRequestAuthCode(any()) } returns authString
+        coEvery { webRequestBuilder.asyncGetTan(registrationToken) } returns authString
     }
 
     @Test
     fun testTransactionNoKeys() {
         coEvery { InternalExposureNotificationClient.asyncGetTemporaryExposureKeyHistory() } returns listOf()
-        coEvery { DiagnosisKeyService.asyncSubmitKeys(authString, listOf()) } just Runs
+        coEvery { webRequestBuilder.asyncSubmitKeysToServer(authString, listOf()) } just Runs
 
         runBlocking {
-            SubmitDiagnosisKeysTransaction.start("123", listOf())
+            SubmitDiagnosisKeysTransaction.start(registrationToken, listOf())
 
             coVerifyOrder {
-                DiagnosisKeyService.asyncSubmitKeys(authString, listOf())
+                webRequestBuilder.asyncSubmitKeysToServer(authString, listOf())
                 SubmissionService.submissionSuccessful()
             }
         }
@@ -64,13 +82,15 @@ class SubmitDiagnosisKeysTransactionTest {
         coEvery { InternalExposureNotificationClient.asyncGetTemporaryExposureKeyHistory() } returns listOf(
             key
         )
-        coEvery { DiagnosisKeyService.asyncSubmitKeys(authString, capture(testList)) } just Runs
+        coEvery {
+            webRequestBuilder.asyncSubmitKeysToServer(authString, capture(testList))
+        } just Runs
 
         runBlocking {
-            SubmitDiagnosisKeysTransaction.start("123", listOf(key))
+            SubmitDiagnosisKeysTransaction.start(registrationToken, listOf(key))
 
             coVerifyOrder {
-                DiagnosisKeyService.asyncSubmitKeys(authString, any())
+                webRequestBuilder.asyncSubmitKeysToServer(authString, any())
                 SubmissionService.submissionSuccessful()
             }
             assertThat(testList.isCaptured, `is`(true))
diff --git a/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/ui/viewmodel/SubmissionViewModelTest.kt b/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/ui/viewmodel/SubmissionViewModelTest.kt
index 96f2ee16937f9ea18347c8f09aa980011413efaa..a7fa73cbf1963e41a9b698b328dd807e4bda4d97 100644
--- a/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/ui/viewmodel/SubmissionViewModelTest.kt
+++ b/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/ui/viewmodel/SubmissionViewModelTest.kt
@@ -1,10 +1,14 @@
 package de.rki.coronawarnapp.ui.viewmodel
 
 import androidx.arch.core.executor.testing.InstantTaskExecutorRule
+import de.rki.coronawarnapp.http.WebRequestBuilder
+import de.rki.coronawarnapp.http.playbook.BackgroundNoise
 import de.rki.coronawarnapp.storage.LocalData
 import de.rki.coronawarnapp.ui.submission.ScanStatus
+import io.mockk.MockKAnnotations
 import io.mockk.Runs
 import io.mockk.every
+import io.mockk.impl.annotations.MockK
 import io.mockk.just
 import io.mockk.mockkObject
 import org.junit.Assert
@@ -19,10 +23,24 @@ class SubmissionViewModelTest {
     @Rule
     var instantTaskExecutorRule: InstantTaskExecutorRule = InstantTaskExecutorRule()
 
+    @MockK
+    private lateinit var webRequestBuilder: WebRequestBuilder
+
+    @MockK
+    private lateinit var backgroundNoise: BackgroundNoise
+
     @Before
     fun setUp() {
+        MockKAnnotations.init(this)
+
         mockkObject(LocalData)
         every { LocalData.testGUID(any()) } just Runs
+
+        mockkObject(WebRequestBuilder.Companion)
+        every { WebRequestBuilder.getInstance() } returns webRequestBuilder
+
+        mockkObject(BackgroundNoise.Companion)
+        every { BackgroundNoise.getInstance() } returns backgroundNoise
     }
 
     @Test
diff --git a/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/util/MockWebServerUtil.kt b/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/util/MockWebServerUtil.kt
new file mode 100644
index 0000000000000000000000000000000000000000..5a908210db83ae12f96e4b825b10dba3a53667a1
--- /dev/null
+++ b/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/util/MockWebServerUtil.kt
@@ -0,0 +1,50 @@
+package de.rki.coronawarnapp.util
+
+import de.rki.coronawarnapp.http.HttpErrorParser
+import de.rki.coronawarnapp.http.WebRequestBuilder
+import de.rki.coronawarnapp.http.interceptor.RetryInterceptor
+import de.rki.coronawarnapp.http.service.DistributionService
+import de.rki.coronawarnapp.http.service.SubmissionService
+import de.rki.coronawarnapp.http.service.VerificationService
+import de.rki.coronawarnapp.util.security.VerificationKeys
+import okhttp3.OkHttpClient
+import okhttp3.logging.HttpLoggingInterceptor
+import okhttp3.mockwebserver.MockWebServer
+import okhttp3.mockwebserver.RecordedRequest
+import okio.utf8Size
+import retrofit2.Retrofit
+import retrofit2.converter.gson.GsonConverterFactory
+import retrofit2.converter.protobuf.ProtoConverterFactory
+
+fun MockWebServer.newWebRequestBuilder(): WebRequestBuilder {
+    val httpClient = OkHttpClient.Builder()
+        .addInterceptor(HttpLoggingInterceptor().setLevel(HttpLoggingInterceptor.Level.BODY))
+        .addInterceptor(RetryInterceptor())
+        .addInterceptor(HttpErrorParser())
+        .build()
+
+    val retrofit = Retrofit.Builder()
+        .client(httpClient)
+        .addConverterFactory(ProtoConverterFactory.create())
+        .addConverterFactory(GsonConverterFactory.create())
+
+    return WebRequestBuilder(
+        retrofit.baseUrl(this.url("/distribution/")).build()
+            .create(DistributionService::class.java),
+        retrofit.baseUrl(this.url("/verification/")).build()
+            .create(VerificationService::class.java),
+        retrofit.baseUrl(this.url("/submission/")).build()
+            .create(SubmissionService::class.java),
+        VerificationKeys()
+    )
+}
+
+fun RecordedRequest.requestHeaderWithoutContentLength() =
+    listOf(this.requestLine)
+        .plus(
+            this.headers.filter { (k, _) -> k != "Content-Length" }.toString()
+        )
+        .joinToString("\n")
+
+fun RecordedRequest.headerSizeIgnoringContentLength() =
+    requestHeaderWithoutContentLength().utf8Size()
diff --git a/README.md b/README.md
index 42b078628d6ded5db7c9c7bbfddb993db5b2e948..cc6619e197864455b06cf26014baafcafebf7081 100644
--- a/README.md
+++ b/README.md
@@ -51,7 +51,7 @@ The following channels are available for discussions, feedback, and support requ
 | Type                     | Channel                                                |
 | ------------------------ | ------------------------------------------------------ |
 | **General Discussion**   | <a href="https://github.com/corona-warn-app/cwa-documentation/issues/new/choose" title="General Discussion"><img src="https://img.shields.io/github/issues/corona-warn-app/cwa-documentation/question.svg?style=flat-square"></a> </a>   |
-| **Feature Requests**    | <a href="https://github.com/corona-warn-app/cwa-whishlist/issues/new/choose" title="Create Feature Request"><img src="https://img.shields.io/github/issues/corona-warn-app/cwa-wishlist?style=flat-square"></a>  |
+| **Feature Requests**    | <a href="https://github.com/corona-warn-app/cwa-wishlist/issues/new/choose" title="Create Feature Request"><img src="https://img.shields.io/github/issues/corona-warn-app/cwa-wishlist?style=flat-square"></a>  |
 | **Concept Feedback**    | <a href="https://github.com/corona-warn-app/cwa-documentation/issues/new/choose" title="Open Concept Feedback"><img src="https://img.shields.io/github/issues/corona-warn-app/cwa-documentation/architecture.svg?style=flat-square"></a>  |
 | **Android App Issue**    | <a href="https://github.com/corona-warn-app/cwa-app-android/issues/new/choose" title="Open Android Issue"><img src="https://img.shields.io/github/issues/corona-warn-app/cwa-app-android?style=flat-square"></a>  |
 | **Backend Issue**    | <a href="https://github.com/corona-warn-app/cwa-server/issues/new/choose" title="Open Backend Issue"><img src="https://img.shields.io/github/issues/corona-warn-app/cwa-server?style=flat-square"></a>  |
diff --git a/Server-Protocol-Buffer/src/main/proto/keyExportFormat.proto b/Server-Protocol-Buffer/src/main/proto/keyExportFormat.proto
index 55e4cd3f155d0675ad7cfa7b93b0ea9b7af2bd20..3ef93b1da8622faedce917cb40d40e41b1f2d612 100644
--- a/Server-Protocol-Buffer/src/main/proto/keyExportFormat.proto
+++ b/Server-Protocol-Buffer/src/main/proto/keyExportFormat.proto
@@ -29,6 +29,7 @@ message SignatureInfo {
 
 message SubmissionPayload {
     repeated TemporaryExposureKey keys = 1;
+    optional bytes padding = 2;
 }
 
 message TemporaryExposureKey {