Skip to content
Snippets Groups Projects
Unverified Commit 44238f01 authored by BMItter's avatar BMItter Committed by GitHub
Browse files

Adjust Diagnosis key file provider to prevent deprecation (EXPOSUREAPP-3896) (#1700)

* Added isAtLeast to ENFVersion

* Use provideDiagnosisKeys with DiagnosisKeyFileProvider on supported version

* better Version of DefaultENFVersion

* Added tests for DefaultENFVersion

* added missing onSuccessListener

* Adjusted tests for new methods
parent 4639c98d
No related branches found
No related tags found
No related merge requests found
package de.rki.coronawarnapp.nearby.modules.diagnosiskeyprovider package de.rki.coronawarnapp.nearby.modules.diagnosiskeyprovider
import com.google.android.gms.common.api.ApiException import com.google.android.gms.common.api.ApiException
import com.google.android.gms.nearby.exposurenotification.DiagnosisKeyFileProvider
import com.google.android.gms.nearby.exposurenotification.ExposureNotificationClient import com.google.android.gms.nearby.exposurenotification.ExposureNotificationClient
import de.rki.coronawarnapp.exception.reporting.ReportingConstants import de.rki.coronawarnapp.exception.reporting.ReportingConstants
import de.rki.coronawarnapp.nearby.modules.version.ENFVersion import de.rki.coronawarnapp.nearby.modules.version.ENFVersion
...@@ -35,10 +36,19 @@ class DefaultDiagnosisKeyProvider @Inject constructor( ...@@ -35,10 +36,19 @@ class DefaultDiagnosisKeyProvider @Inject constructor(
// return false // return false
} }
val keyFilesList = keyFiles.toList()
val provideDiagnosisKeysTask = if (enfVersion.isAtLeast(ENFVersion.V1_7)) {
Timber.i("Provide diagnosis keys with DiagnosisKeyFileProvider")
val diagnosisKeyFileProvider = DiagnosisKeyFileProvider(keyFilesList)
enfClient.provideDiagnosisKeys(diagnosisKeyFileProvider)
} else {
Timber.i("Provide diagnosis keys as list")
enfClient.provideDiagnosisKeys(keyFilesList)
}
return suspendCoroutine { cont -> return suspendCoroutine { cont ->
Timber.d("Performing key submission.") Timber.d("Performing key submission.")
enfClient provideDiagnosisKeysTask
.provideDiagnosisKeys(keyFiles.toList())
.addOnSuccessListener { cont.resume(true) } .addOnSuccessListener { cont.resume(true) }
.addOnFailureListener { .addOnFailureListener {
val wrappedException = val wrappedException =
......
...@@ -9,6 +9,7 @@ import javax.inject.Singleton ...@@ -9,6 +9,7 @@ import javax.inject.Singleton
import kotlin.coroutines.resume import kotlin.coroutines.resume
import kotlin.coroutines.resumeWithException import kotlin.coroutines.resumeWithException
import kotlin.coroutines.suspendCoroutine import kotlin.coroutines.suspendCoroutine
import kotlin.math.abs
@Singleton @Singleton
class DefaultENFVersion @Inject constructor( class DefaultENFVersion @Inject constructor(
...@@ -39,9 +40,28 @@ class DefaultENFVersion @Inject constructor( ...@@ -39,9 +40,28 @@ class DefaultENFVersion @Inject constructor(
} }
} }
override suspend fun isAtLeast(compareVersion: Long): Boolean {
if (!compareVersion.isCorrectVersionLength) throw IllegalArgumentException("given version has incorrect length")
getENFClientVersion()?.let { currentENFClientVersion ->
Timber.i("Comparing current ENF client version $currentENFClientVersion with $compareVersion")
return currentENFClientVersion >= compareVersion
}
return false
}
private suspend fun internalGetENFClientVersion(): Long = suspendCoroutine { cont -> private suspend fun internalGetENFClientVersion(): Long = suspendCoroutine { cont ->
client.version client.version
.addOnSuccessListener { cont.resume(it) } .addOnSuccessListener { cont.resume(it) }
.addOnFailureListener { cont.resumeWithException(it) } .addOnFailureListener { cont.resumeWithException(it) }
} }
// check if a raw long has the correct length to be considered an API version
private val Long.isCorrectVersionLength
get(): Boolean = abs(this).toString().length == GOOGLE_API_VERSION_FIELD_LENGTH
companion object {
private const val GOOGLE_API_VERSION_FIELD_LENGTH = 8
}
} }
...@@ -12,7 +12,15 @@ interface ENFVersion { ...@@ -12,7 +12,15 @@ interface ENFVersion {
*/ */
suspend fun requireMinimumVersion(required: Long) suspend fun requireMinimumVersion(required: Long)
/**
* Indicates if the client runs above a certain version
*
* @return isAboveVersion, if connected to an old unsupported version, return false
*/
suspend fun isAtLeast(compareVersion: Long): Boolean
companion object { companion object {
const val V1_6 = 16000000L const val V1_6 = 16000000L
const val V1_7 = 17000000L
} }
} }
package de.rki.coronawarnapp.nearby.modules.diagnosiskeyprovider package de.rki.coronawarnapp.nearby.modules.diagnosiskeyprovider
import com.google.android.gms.nearby.exposurenotification.DiagnosisKeyFileProvider
import com.google.android.gms.nearby.exposurenotification.ExposureNotificationClient import com.google.android.gms.nearby.exposurenotification.ExposureNotificationClient
import de.rki.coronawarnapp.nearby.modules.version.ENFVersion import de.rki.coronawarnapp.nearby.modules.version.ENFVersion
import de.rki.coronawarnapp.nearby.modules.version.OutdatedENFVersionException import de.rki.coronawarnapp.nearby.modules.version.OutdatedENFVersionException
...@@ -36,6 +37,8 @@ class DefaultDiagnosisKeyProviderTest : BaseTest() { ...@@ -36,6 +37,8 @@ class DefaultDiagnosisKeyProviderTest : BaseTest() {
coEvery { googleENFClient.provideDiagnosisKeys(any<List<File>>()) } returns MockGMSTask.forValue(null) coEvery { googleENFClient.provideDiagnosisKeys(any<List<File>>()) } returns MockGMSTask.forValue(null)
coEvery { googleENFClient.provideDiagnosisKeys(any<DiagnosisKeyFileProvider>()) } returns MockGMSTask.forValue(null)
coEvery { enfVersion.requireMinimumVersion(any()) } returns Unit coEvery { enfVersion.requireMinimumVersion(any()) } returns Unit
} }
...@@ -70,7 +73,23 @@ class DefaultDiagnosisKeyProviderTest : BaseTest() { ...@@ -70,7 +73,23 @@ class DefaultDiagnosisKeyProviderTest : BaseTest() {
} }
@Test @Test
fun `key provision is used on newer ENF versions`() { fun `key provision is used with DiagnosisKeyFileProvider on ENF versions from 1_7 upwards`() {
coEvery { enfVersion.isAtLeast(any()) } returns true
val provider = createProvider()
runBlocking { provider.provideDiagnosisKeys(exampleKeyFiles) } shouldBe true
coVerifySequence {
submissionQuota.consumeQuota(1)
googleENFClient.provideDiagnosisKeys(any<DiagnosisKeyFileProvider>())
}
}
@Test
fun `key provision is used with key list on ENF versions 1_6`() {
coEvery { enfVersion.isAtLeast(any()) } returns false
val provider = createProvider() val provider = createProvider()
runBlocking { provider.provideDiagnosisKeys(exampleKeyFiles) } shouldBe true runBlocking { provider.provideDiagnosisKeys(exampleKeyFiles) } shouldBe true
...@@ -81,9 +100,11 @@ class DefaultDiagnosisKeyProviderTest : BaseTest() { ...@@ -81,9 +100,11 @@ class DefaultDiagnosisKeyProviderTest : BaseTest() {
} }
} }
@Test @Test
fun `quota is just monitored`() { fun `quota is just monitored`() {
coEvery { submissionQuota.consumeQuota(any()) } returns false coEvery { submissionQuota.consumeQuota(any()) } returns false
coEvery { enfVersion.isAtLeast(any()) } returns true
val provider = createProvider() val provider = createProvider()
...@@ -91,7 +112,7 @@ class DefaultDiagnosisKeyProviderTest : BaseTest() { ...@@ -91,7 +112,7 @@ class DefaultDiagnosisKeyProviderTest : BaseTest() {
coVerifySequence { coVerifySequence {
submissionQuota.consumeQuota(1) submissionQuota.consumeQuota(1)
googleENFClient.provideDiagnosisKeys(exampleKeyFiles) googleENFClient.provideDiagnosisKeys(any<DiagnosisKeyFileProvider>())
} }
} }
......
...@@ -109,4 +109,54 @@ internal class DefaultENFVersionTest { ...@@ -109,4 +109,54 @@ internal class DefaultENFVersionTest {
} }
} }
} }
@Test
fun `isAtLeast is true for newer version`() {
every { client.version } returns MockGMSTask.forValue(ENFVersion.V1_7)
runBlockingTest {
createInstance().isAtLeast(ENFVersion.V1_6) shouldBe true
}
}
@Test
fun `isAtLeast is true for equal version`() {
every { client.version } returns MockGMSTask.forValue(ENFVersion.V1_6)
runBlockingTest {
createInstance().isAtLeast(ENFVersion.V1_6) shouldBe true
}
}
@Test
fun `isAtLeast is false for older version`() {
every { client.version } returns MockGMSTask.forValue(ENFVersion.V1_6)
runBlockingTest {
createInstance().isAtLeast(ENFVersion.V1_7) shouldBe false
}
}
@Test
fun `invalid input for isAtLeast throws IllegalArgumentException`() {
runBlockingTest {
shouldThrow<IllegalArgumentException> {
createInstance().isAtLeast(16)
}
}
}
@Test
fun `isAtLeast returns false when client not connected`() {
every { client.version } returns MockGMSTask.forError(ApiException(Status(API_NOT_CONNECTED)))
runBlockingTest {
createInstance().apply {
shouldNotThrowAny {
isAtLeast(ENFVersion.V1_6) shouldBe false
isAtLeast(ENFVersion.V1_7) shouldBe false
}
}
}
}
} }
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment