diff --git a/.idea/codeStyles/Project.xml b/.idea/codeStyles/Project.xml
index 32327027218..aa533f1bc24 100644
--- a/.idea/codeStyles/Project.xml
+++ b/.idea/codeStyles/Project.xml
@@ -125,6 +125,8 @@
+
+
diff --git a/Corona-Warn-App/build.gradle b/Corona-Warn-App/build.gradle
index 1d3229d5b65..384bcddf02b 100644
--- a/Corona-Warn-App/build.gradle
+++ b/Corona-Warn-App/build.gradle
@@ -276,6 +276,8 @@ dependencies {
testImplementation "io.kotest:kotest-runner-junit5:4.2.0"
testImplementation "io.kotest:kotest-assertions-core-jvm:4.2.0"
testImplementation "io.kotest:kotest-property-jvm:4.2.0"
+ androidTestImplementation "io.kotest:kotest-assertions-core-jvm:4.2.0"
+ androidTestImplementation "io.kotest:kotest-property-jvm:4.2.0"
// Testing - Instrumentation
androidTestImplementation 'androidx.test:runner:1.2.0'
diff --git a/Corona-Warn-App/schemas/de.rki.coronawarnapp.diagnosiskeys.storage.KeyCacheDatabase/1.json b/Corona-Warn-App/schemas/de.rki.coronawarnapp.diagnosiskeys.storage.KeyCacheDatabase/1.json
new file mode 100644
index 00000000000..72e78dde4ed
--- /dev/null
+++ b/Corona-Warn-App/schemas/de.rki.coronawarnapp.diagnosiskeys.storage.KeyCacheDatabase/1.json
@@ -0,0 +1,76 @@
+{
+ "formatVersion": 1,
+ "database": {
+ "version": 1,
+ "identityHash": "c4ef5f7d4d9672d11c8eb97a63d4a3c5",
+ "entities": [
+ {
+ "tableName": "keyfiles",
+ "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` TEXT NOT NULL, `type` TEXT NOT NULL, `location` TEXT NOT NULL, `day` TEXT NOT NULL, `hour` TEXT, `createdAt` TEXT NOT NULL, `checksumMD5` TEXT, `completed` INTEGER NOT NULL, PRIMARY KEY(`id`))",
+ "fields": [
+ {
+ "fieldPath": "id",
+ "columnName": "id",
+ "affinity": "TEXT",
+ "notNull": true
+ },
+ {
+ "fieldPath": "type",
+ "columnName": "type",
+ "affinity": "TEXT",
+ "notNull": true
+ },
+ {
+ "fieldPath": "location",
+ "columnName": "location",
+ "affinity": "TEXT",
+ "notNull": true
+ },
+ {
+ "fieldPath": "day",
+ "columnName": "day",
+ "affinity": "TEXT",
+ "notNull": true
+ },
+ {
+ "fieldPath": "hour",
+ "columnName": "hour",
+ "affinity": "TEXT",
+ "notNull": false
+ },
+ {
+ "fieldPath": "createdAt",
+ "columnName": "createdAt",
+ "affinity": "TEXT",
+ "notNull": true
+ },
+ {
+ "fieldPath": "checksumMD5",
+ "columnName": "checksumMD5",
+ "affinity": "TEXT",
+ "notNull": false
+ },
+ {
+ "fieldPath": "isDownloadComplete",
+ "columnName": "completed",
+ "affinity": "INTEGER",
+ "notNull": true
+ }
+ ],
+ "primaryKey": {
+ "columnNames": [
+ "id"
+ ],
+ "autoGenerate": false
+ },
+ "indices": [],
+ "foreignKeys": []
+ }
+ ],
+ "views": [],
+ "setupQueries": [
+ "CREATE TABLE IF NOT EXISTS room_master_table (id INTEGER PRIMARY KEY,identity_hash TEXT)",
+ "INSERT OR REPLACE INTO room_master_table (id,identity_hash) VALUES(42, 'c4ef5f7d4d9672d11c8eb97a63d4a3c5')"
+ ]
+ }
+}
\ No newline at end of file
diff --git a/Corona-Warn-App/schemas/de.rki.coronawarnapp.storage.keycache.KeyCacheDatabase/1.json b/Corona-Warn-App/schemas/de.rki.coronawarnapp.storage.keycache.KeyCacheDatabase/1.json
new file mode 100644
index 00000000000..9d856a5a015
--- /dev/null
+++ b/Corona-Warn-App/schemas/de.rki.coronawarnapp.storage.keycache.KeyCacheDatabase/1.json
@@ -0,0 +1,82 @@
+{
+ "formatVersion": 1,
+ "database": {
+ "version": 1,
+ "identityHash": "03f6e8cba631c8ef60e506006913a1ad",
+ "entities": [
+ {
+ "tableName": "keyfiles",
+ "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` TEXT NOT NULL, `type` TEXT NOT NULL, `location` TEXT NOT NULL, `day` TEXT NOT NULL, `hour` TEXT, `sourceUrl` TEXT NOT NULL, `createdAt` TEXT NOT NULL, `checksumMD5` TEXT, `completed` INTEGER NOT NULL, PRIMARY KEY(`id`))",
+ "fields": [
+ {
+ "fieldPath": "id",
+ "columnName": "id",
+ "affinity": "TEXT",
+ "notNull": true
+ },
+ {
+ "fieldPath": "type",
+ "columnName": "type",
+ "affinity": "TEXT",
+ "notNull": true
+ },
+ {
+ "fieldPath": "location",
+ "columnName": "location",
+ "affinity": "TEXT",
+ "notNull": true
+ },
+ {
+ "fieldPath": "day",
+ "columnName": "day",
+ "affinity": "TEXT",
+ "notNull": true
+ },
+ {
+ "fieldPath": "hour",
+ "columnName": "hour",
+ "affinity": "TEXT",
+ "notNull": false
+ },
+ {
+ "fieldPath": "sourceUrl",
+ "columnName": "sourceUrl",
+ "affinity": "TEXT",
+ "notNull": true
+ },
+ {
+ "fieldPath": "createdAt",
+ "columnName": "createdAt",
+ "affinity": "TEXT",
+ "notNull": true
+ },
+ {
+ "fieldPath": "checksumMD5",
+ "columnName": "checksumMD5",
+ "affinity": "TEXT",
+ "notNull": false
+ },
+ {
+ "fieldPath": "isDownloadComplete",
+ "columnName": "completed",
+ "affinity": "INTEGER",
+ "notNull": true
+ }
+ ],
+ "primaryKey": {
+ "columnNames": [
+ "id"
+ ],
+ "autoGenerate": false
+ },
+ "indices": [],
+ "foreignKeys": []
+ }
+ ],
+ "views": [],
+ "setupQueries": [
+ "CREATE TABLE IF NOT EXISTS room_master_table (id INTEGER PRIMARY KEY,identity_hash TEXT)",
+ "INSERT OR REPLACE INTO room_master_table (id,identity_hash) VALUES(42, '03f6e8cba631c8ef60e506006913a1ad')"
+ ]
+ }
+}
\ No newline at end of file
diff --git a/Corona-Warn-App/src/androidTest/java/de/rki/coronawarnapp/diagnosiskeys/storage/KeyCacheDatabaseTest.kt b/Corona-Warn-App/src/androidTest/java/de/rki/coronawarnapp/diagnosiskeys/storage/KeyCacheDatabaseTest.kt
new file mode 100644
index 00000000000..ac0ccdefe87
--- /dev/null
+++ b/Corona-Warn-App/src/androidTest/java/de/rki/coronawarnapp/diagnosiskeys/storage/KeyCacheDatabaseTest.kt
@@ -0,0 +1,79 @@
+package de.rki.coronawarnapp.diagnosiskeys.storage
+
+import android.content.Context
+import androidx.test.core.app.ApplicationProvider
+import androidx.test.ext.junit.runners.AndroidJUnit4
+import de.rki.coronawarnapp.diagnosiskeys.server.LocationCode
+import io.kotest.matchers.shouldBe
+import kotlinx.coroutines.runBlocking
+import org.joda.time.Instant
+import org.joda.time.LocalDate
+import org.joda.time.LocalTime
+import org.junit.Test
+import org.junit.runner.RunWith
+
+@RunWith(AndroidJUnit4::class)
+class KeyCacheDatabaseTest {
+ private val database = KeyCacheDatabase.Factory(
+ ApplicationProvider.getApplicationContext()
+ ).create()
+ private val dao = database.cachedKeyFiles()
+
+ @Test
+ fun crud() {
+ val keyDay = CachedKeyInfo(
+ type = CachedKeyInfo.Type.COUNTRY_DAY,
+ location = LocationCode("DE"),
+ day = LocalDate.now(),
+ hour = null,
+ createdAt = Instant.now()
+ )
+ val keyHour = CachedKeyInfo(
+ type = CachedKeyInfo.Type.COUNTRY_HOUR,
+ location = LocationCode("DE"),
+ day = LocalDate.now(),
+ hour = LocalTime.now(),
+ createdAt = Instant.now()
+ )
+ runBlocking {
+ dao.clear()
+
+ dao.insertEntry(keyDay)
+ dao.insertEntry(keyHour)
+ dao.getAllEntries() shouldBe listOf(keyDay, keyHour)
+ dao.getEntriesForType(CachedKeyInfo.Type.COUNTRY_DAY.typeValue) shouldBe listOf(keyDay)
+ dao.getEntriesForType(CachedKeyInfo.Type.COUNTRY_HOUR.typeValue) shouldBe listOf(keyHour)
+
+ dao.updateDownloadState(keyDay.toDownloadUpdate("coffee"))
+ dao.getEntriesForType(CachedKeyInfo.Type.COUNTRY_DAY.typeValue).single().apply {
+ isDownloadComplete shouldBe true
+ checksumMD5 shouldBe "coffee"
+ }
+ dao.getEntriesForType(CachedKeyInfo.Type.COUNTRY_HOUR.typeValue).single().apply {
+ isDownloadComplete shouldBe false
+ checksumMD5 shouldBe null
+ }
+
+ dao.updateDownloadState(keyHour.toDownloadUpdate("with milk"))
+ dao.getEntriesForType(CachedKeyInfo.Type.COUNTRY_DAY.typeValue).single().apply {
+ isDownloadComplete shouldBe true
+ checksumMD5 shouldBe "coffee"
+ }
+ dao.getEntriesForType(CachedKeyInfo.Type.COUNTRY_HOUR.typeValue).single().apply {
+ isDownloadComplete shouldBe true
+ checksumMD5 shouldBe "with milk"
+ }
+
+ dao.deleteEntry(keyDay)
+ dao.getAllEntries() shouldBe listOf(
+ keyHour.copy(
+ isDownloadComplete = true,
+ checksumMD5 = "with milk"
+ )
+ )
+
+ dao.clear()
+ dao.getAllEntries() shouldBe emptyList()
+ }
+ }
+}
diff --git a/Corona-Warn-App/src/androidTest/java/de/rki/coronawarnapp/storage/keycache/KeyCacheDaoTest.kt b/Corona-Warn-App/src/androidTest/java/de/rki/coronawarnapp/storage/keycache/KeyCacheDaoTest.kt
deleted file mode 100644
index 31f173f6c73..00000000000
--- a/Corona-Warn-App/src/androidTest/java/de/rki/coronawarnapp/storage/keycache/KeyCacheDaoTest.kt
+++ /dev/null
@@ -1,88 +0,0 @@
-package de.rki.coronawarnapp.storage.keycache
-
-import android.content.Context
-import androidx.room.Room
-import androidx.test.core.app.ApplicationProvider
-import androidx.test.ext.junit.runners.AndroidJUnit4
-import com.google.common.truth.Truth.assertThat
-import de.rki.coronawarnapp.storage.AppDatabase
-import kotlinx.coroutines.runBlocking
-import org.junit.After
-import org.junit.Before
-import org.junit.Test
-import org.junit.runner.RunWith
-
-/**
- * KeyCacheDao test.
- */
-@RunWith(AndroidJUnit4::class)
-class KeyCacheDaoTest {
- private lateinit var keyCacheDao: KeyCacheDao
- private lateinit var db: AppDatabase
-
- @Before
- fun setUp() {
- val context = ApplicationProvider.getApplicationContext()
- db = Room.inMemoryDatabaseBuilder(
- context, AppDatabase::class.java
- ).build()
- keyCacheDao = db.dateDao()
- }
-
- /**
- * Test Create / Read / Delete DB operations.
- */
- @Test
- fun testCRDOperations() {
- runBlocking {
- val dates = KeyCacheEntity().apply {
- this.id = "0"
- this.path = "0"
- this.type = 0
- }
- val hours = KeyCacheEntity().apply {
- this.id = "1"
- this.path = "1"
- this.type = 1
- }
-
- assertThat(keyCacheDao.getAllEntries().isEmpty()).isTrue()
-
- keyCacheDao.insertEntry(dates)
- keyCacheDao.insertEntry(hours)
-
- var all = keyCacheDao.getAllEntries()
-
- assertThat(all.size).isEqualTo(2)
-
- val selectedDates = keyCacheDao.getDates()
- assertThat(selectedDates.size).isEqualTo(1)
- assertThat(selectedDates[0].type).isEqualTo(0)
- assertThat(selectedDates[0].id).isEqualTo(dates.id)
-
- val selectedHours = keyCacheDao.getHours()
- assertThat(selectedHours.size).isEqualTo(1)
- assertThat(selectedHours[0].type).isEqualTo(1)
- assertThat(selectedHours[0].id).isEqualTo(hours.id)
-
- keyCacheDao.clearHours()
-
- all = keyCacheDao.getAllEntries()
- assertThat(all.size).isEqualTo(1)
- assertThat(all[0].type).isEqualTo(0)
-
- keyCacheDao.insertEntry(hours)
-
- assertThat(keyCacheDao.getAllEntries().size).isEqualTo(2)
-
- keyCacheDao.clear()
-
- assertThat(keyCacheDao.getAllEntries().isEmpty()).isTrue()
- }
- }
-
- @After
- fun closeDb() {
- db.close()
- }
-}
diff --git a/Corona-Warn-App/src/androidTest/java/de/rki/coronawarnapp/util/security/DBPasswordTest.kt b/Corona-Warn-App/src/androidTest/java/de/rki/coronawarnapp/util/security/DBPasswordTest.kt
index 5f1267524ea..efbab656804 100644
--- a/Corona-Warn-App/src/androidTest/java/de/rki/coronawarnapp/util/security/DBPasswordTest.kt
+++ b/Corona-Warn-App/src/androidTest/java/de/rki/coronawarnapp/util/security/DBPasswordTest.kt
@@ -22,7 +22,8 @@ package de.rki.coronawarnapp.util.security
import android.content.Context
import androidx.test.core.app.ApplicationProvider
import de.rki.coronawarnapp.storage.AppDatabase
-import de.rki.coronawarnapp.storage.keycache.KeyCacheEntity
+import de.rki.coronawarnapp.storage.tracing.TracingIntervalEntity
+import io.kotest.matchers.shouldBe
import kotlinx.coroutines.runBlocking
import net.sqlcipher.database.SQLiteException
import org.hamcrest.Matchers.equalTo
@@ -33,8 +34,6 @@ import org.junit.Before
import org.junit.Test
import org.junit.runner.RunWith
import org.junit.runners.JUnit4
-import java.util.UUID
-import kotlin.random.Random
@RunWith(JUnit4::class)
class DBPasswordTest {
@@ -70,16 +69,14 @@ class DBPasswordTest {
@Test
fun canLoadDataFromEncryptedDatabase() {
runBlocking {
- val id = UUID.randomUUID().toString()
- val path = UUID.randomUUID().toString()
- val type = Random.nextInt(1000)
-
- insertFakeEntity(id, path, type)
- val keyCacheEntity = loadFakeEntity()
-
- assertThat(keyCacheEntity.id, equalTo(id))
- assertThat(keyCacheEntity.path, equalTo(path))
- assertThat(keyCacheEntity.type, equalTo(type))
+ val from = 123L
+ val to = 456L
+ insertFakeEntity(from, to)
+
+ loadFakeEntity().apply {
+ this.from shouldBe from
+ this.to shouldBe to
+ }
}
}
@@ -95,34 +92,32 @@ class DBPasswordTest {
@Test(expected = SQLiteException::class)
fun loadingDataFromDatabaseWillFailWhenPassphraseIsIncorrect() {
runBlocking {
- val id = UUID.randomUUID().toString()
- val path = UUID.randomUUID().toString()
- val type = Random.nextInt(1000)
- insertFakeEntity(id, path, type)
+ val from = 123L
+ val to = 456L
+ insertFakeEntity(from, to)
clearSharedPreferences()
AppDatabase.resetInstance()
- val keyCacheEntity = loadFakeEntity()
- assertThat(keyCacheEntity.id, equalTo(id))
- assertThat(keyCacheEntity.path, equalTo(path))
- assertThat(keyCacheEntity.type, equalTo(type))
+ loadFakeEntity().apply {
+ this.from shouldBe from
+ this.to shouldBe to
+ }
}
}
private suspend fun insertFakeEntity(
- id: String,
- path: String,
- type: Int
+ from: Long,
+ to: Long
) {
- db.dateDao().insertEntry(KeyCacheEntity().apply {
- this.id = id
- this.path = path
- this.type = type
+ db.tracingIntervalDao().insertInterval(TracingIntervalEntity().apply {
+ this.from = from
+ this.to = to
})
}
- private suspend fun loadFakeEntity(): KeyCacheEntity = db.dateDao().getAllEntries().first()
+ private suspend fun loadFakeEntity(): TracingIntervalEntity =
+ db.tracingIntervalDao().getAllIntervals().first()
private fun clearSharedPreferences() =
SecurityHelper.globalEncryptedSharedPreferencesInstance.edit().clear().commit()
diff --git a/Corona-Warn-App/src/androidTest/java/de/rki/coronawarnapp/util/security/VerificationKeysTest.kt b/Corona-Warn-App/src/androidTest/java/de/rki/coronawarnapp/util/security/VerificationKeysTest.kt
new file mode 100644
index 00000000000..f43f22095c6
--- /dev/null
+++ b/Corona-Warn-App/src/androidTest/java/de/rki/coronawarnapp/util/security/VerificationKeysTest.kt
@@ -0,0 +1,71 @@
+package de.rki.coronawarnapp.util.security
+
+import de.rki.coronawarnapp.exception.CwaSecurityException
+import io.kotest.assertions.throwables.shouldThrow
+import io.kotest.matchers.shouldBe
+import okio.ByteString.Companion.decodeHex
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.junit.runners.JUnit4
+
+@RunWith(JUnit4::class)
+class VerificationKeysTest {
+
+ private fun createTool() = VerificationKeys()
+
+ @Test
+ fun goodBinaryAndSignature() {
+ val tool = createTool()
+ tool.hasInvalidSignature(
+ GOOD_BINARY.decodeHex().toByteArray(),
+ GOOD_SIGNATURE.decodeHex().toByteArray()
+ ) shouldBe false
+ }
+
+ @Test
+ fun badBinaryGoodSignature() {
+ val tool = createTool()
+ tool.hasInvalidSignature(
+ "123ABC".decodeHex().toByteArray(),
+ GOOD_SIGNATURE.decodeHex().toByteArray()
+ ) shouldBe true
+ }
+
+ @Test
+ fun goodBinaryBadSignature() {
+ val tool = createTool()
+ shouldThrow {
+ tool.hasInvalidSignature(
+ GOOD_BINARY.decodeHex().toByteArray(),
+ "123ABC".decodeHex().toByteArray()
+ )
+ }
+ }
+
+ @Test
+ fun badEverything() {
+ val tool = createTool()
+ shouldThrow {
+ tool.hasInvalidSignature(
+ "123ABC".decodeHex().toByteArray(),
+ "123ABC".decodeHex().toByteArray()
+ )
+ }
+ }
+
+ companion object {
+ private const val GOOD_BINARY =
+ "080b124d0a230a034c4f57180f221a68747470733a2f2f7777772e636f726f6e617761726e2e6170700a26" +
+ "0a0448494748100f1848221a68747470733a2f2f7777772e636f726f6e617761726e2e6170701a" +
+ "640a10080110021803200428053006380740081100000000000049401a0a200128013001380140" +
+ "012100000000000049402a10080510051805200528053005380540053100000000000034403a0e" +
+ "1001180120012801300138014001410000000000004940221c0a040837103f1212090000000000" +
+ "00f03f11000000000000e03f20192a1a0a0a0a041008180212021005120c0a0408011804120408" +
+ "011804"
+ private const val GOOD_SIGNATURE =
+ "0a87010a380a1864652e726b692e636f726f6e617761726e6170702d6465761a02763122033236322a1331" +
+ "2e322e3834302e31303034352e342e332e321001180122473045022100cf32ff24ea18a1ffcc7f" +
+ "f4c9fe8d1808cecbc5a37e3e1d4c9ce682120450958c022064bf124b6973a9b510a43d479ff93e" +
+ "0ef97a5b893c7af4abc4a8d399969cd8a0"
+ }
+}
diff --git a/Corona-Warn-App/src/deviceForTesters/java/de.rki.coronawarnapp/RiskLevelAndKeyRetrievalBenchmark.kt b/Corona-Warn-App/src/deviceForTesters/java/de.rki.coronawarnapp/RiskLevelAndKeyRetrievalBenchmark.kt
index 85b980a36e0..e92c287573f 100644
--- a/Corona-Warn-App/src/deviceForTesters/java/de.rki.coronawarnapp/RiskLevelAndKeyRetrievalBenchmark.kt
+++ b/Corona-Warn-App/src/deviceForTesters/java/de.rki.coronawarnapp/RiskLevelAndKeyRetrievalBenchmark.kt
@@ -5,9 +5,9 @@ import android.text.format.Formatter
import de.rki.coronawarnapp.exception.ExceptionCategory
import de.rki.coronawarnapp.exception.TransactionException
import de.rki.coronawarnapp.exception.reporting.report
-import de.rki.coronawarnapp.storage.keycache.KeyCacheRepository
import de.rki.coronawarnapp.transaction.RetrieveDiagnosisKeysTransaction
import de.rki.coronawarnapp.transaction.RiskLevelTransaction
+import de.rki.coronawarnapp.util.di.AppInjector
import timber.log.Timber
import kotlin.system.measureTimeMillis
@@ -19,8 +19,7 @@ class RiskLevelAndKeyRetrievalBenchmark(
/**
* the key cache instance used to store queried dates and hours
*/
- private val keyCache =
- KeyCacheRepository.getDateRepository(context)
+ private val keyCache = AppInjector.component.keyCacheRepository
/**
* Calls the RetrieveDiagnosisKeysTransaction and RiskLevelTransaction and measures them.
@@ -36,7 +35,7 @@ class RiskLevelAndKeyRetrievalBenchmark(
var resultInfo = StringBuilder()
.append(
"MEASUREMENT Running for Countries:\n " +
- "${countries?.joinToString(", ")}\n\n"
+ "${countries.joinToString(", ")}\n\n"
)
.append("Result: \n\n")
.append("#\t Combined \t Download \t Sub \t Risk \t File # \t F. size\n")
diff --git a/Corona-Warn-App/src/deviceForTesters/java/de.rki.coronawarnapp/TestForAPIFragment.kt b/Corona-Warn-App/src/deviceForTesters/java/de.rki.coronawarnapp/TestForAPIFragment.kt
index ac579527077..1e457e5ad9f 100644
--- a/Corona-Warn-App/src/deviceForTesters/java/de.rki.coronawarnapp/TestForAPIFragment.kt
+++ b/Corona-Warn-App/src/deviceForTesters/java/de.rki.coronawarnapp/TestForAPIFragment.kt
@@ -33,6 +33,7 @@ import com.google.zxing.integration.android.IntentIntegrator
import com.google.zxing.integration.android.IntentResult
import com.google.zxing.qrcode.QRCodeWriter
import de.rki.coronawarnapp.databinding.FragmentTestForAPIBinding
+import de.rki.coronawarnapp.diagnosiskeys.server.LocationCode
import de.rki.coronawarnapp.exception.ExceptionCategory
import de.rki.coronawarnapp.exception.ExceptionCategory.INTERNAL
import de.rki.coronawarnapp.exception.TransactionException
@@ -50,8 +51,8 @@ import de.rki.coronawarnapp.storage.LocalData
import de.rki.coronawarnapp.storage.tracing.TracingIntervalRepository
import de.rki.coronawarnapp.transaction.RiskLevelTransaction
import de.rki.coronawarnapp.ui.viewmodel.TracingViewModel
-import de.rki.coronawarnapp.util.CachedKeyFileHolder
import de.rki.coronawarnapp.util.KeyFileHelper
+import de.rki.coronawarnapp.util.di.AppInjector
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
@@ -60,7 +61,6 @@ import org.joda.time.DateTimeZone
import timber.log.Timber
import java.io.File
import java.lang.reflect.Type
-import java.util.Date
import java.util.UUID
@SuppressWarnings("TooManyFunctions", "MagicNumber", "LongMethod")
@@ -321,9 +321,9 @@ class TestForAPIFragment : Fragment(), InternalExposureNotificationPermissionHel
lastSetCountries = countryCodes
// Trigger asyncFetchFiles which will use all Countries passed as parameter
- val currentDate = Date(System.currentTimeMillis())
lifecycleScope.launch {
- CachedKeyFileHolder.asyncFetchFiles(currentDate, countryCodes)
+ val locationCodes = countryCodes.map { LocationCode(it) }
+ AppInjector.component.keyFileDownloader.asyncFetchKeyFiles(locationCodes)
updateCountryStatusLabel()
}
}
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 14ddf7a9291..945ddca4e51 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
@@ -27,7 +27,6 @@ import de.rki.coronawarnapp.server.protocols.AppleLegacyKeyExchange
import de.rki.coronawarnapp.service.applicationconfiguration.ApplicationConfigurationService
import de.rki.coronawarnapp.sharing.ExposureSharingService
import de.rki.coronawarnapp.storage.AppDatabase
-import de.rki.coronawarnapp.storage.FileStorageHelper
import de.rki.coronawarnapp.storage.LocalData
import de.rki.coronawarnapp.storage.RiskLevelRepository
import de.rki.coronawarnapp.transaction.RetrieveDiagnosisKeysTransaction
@@ -36,6 +35,7 @@ import de.rki.coronawarnapp.ui.viewmodel.SettingsViewModel
import de.rki.coronawarnapp.ui.viewmodel.SubmissionViewModel
import de.rki.coronawarnapp.ui.viewmodel.TracingViewModel
import de.rki.coronawarnapp.util.KeyFileHelper
+import de.rki.coronawarnapp.util.di.AppInjector
import de.rki.coronawarnapp.util.security.SecurityHelper
import kotlinx.android.synthetic.deviceForTesters.fragment_test_risk_level_calculation.*
import kotlinx.coroutines.Dispatchers
@@ -112,7 +112,7 @@ class TestRiskLevelCalculation : Fragment() {
// Database Reset
AppDatabase.reset(requireContext())
// Export File Reset
- FileStorageHelper.getAllFilesInKeyExportDirectory().forEach { it.delete() }
+ AppInjector.component.keyCacheRepository.clear()
LocalData.lastCalculatedRiskLevel(RiskLevel.UNDETERMINED.raw)
LocalData.lastSuccessfullyCalculatedRiskLevel(RiskLevel.UNDETERMINED.raw)
@@ -130,6 +130,12 @@ class TestRiskLevelCalculation : Fragment() {
}
}
+ binding.buttonClearDiagnosisKeyCache.setOnClickListener {
+ lifecycleScope.launch {
+ AppInjector.component.keyCacheRepository.clear()
+ }
+ }
+
startObserving()
}
diff --git a/Corona-Warn-App/src/deviceForTesters/res/layout/fragment_test_for_a_p_i.xml b/Corona-Warn-App/src/deviceForTesters/res/layout/fragment_test_for_a_p_i.xml
index 2452245478a..09ac7491525 100644
--- a/Corona-Warn-App/src/deviceForTesters/res/layout/fragment_test_for_a_p_i.xml
+++ b/Corona-Warn-App/src/deviceForTesters/res/layout/fragment_test_for_a_p_i.xml
@@ -1,5 +1,7 @@
-
+
@@ -241,8 +243,7 @@
android:id="@+id/input_country_codes_editText"
android:layout_width="0dp"
android:layout_height="wrap_content"
- android:layout_weight="1"
- />
+ android:layout_weight="1" />