diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/covidcertificate/test/core/TestCertificateRepository.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/covidcertificate/test/core/TestCertificateRepository.kt index 17f9632e9498ad08ab3774d1295777245ff923a6..b632cea276213c1ca43a3f1a7046921588cf1046 100644 --- a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/covidcertificate/test/core/TestCertificateRepository.kt +++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/covidcertificate/test/core/TestCertificateRepository.kt @@ -296,6 +296,29 @@ class TestCertificateRepository @Inject constructor( internalData.updateBlocking { emptyMap() } } + suspend fun markCertificateAsSeenByUser(identifier: TestCertificateIdentifier) { + Timber.tag(TAG).d("markCertificateSeenByUser(identifier=%s)", identifier) + + internalData.updateBlocking { + val current = this[identifier] + if (current == null) { + Timber.tag(TAG).w("Can't mark %s as seen, it doesn't exist, racecondition?", identifier) + return@updateBlocking this + } + + if (current.isCertificateRetrievalPending) { + Timber.tag(TAG).w("Can't mark %s as seen, certificate has not been retrieved yet.", identifier) + return@updateBlocking this + } + + val updated = current.copy( + data = processor.updateSeenByUser(current.data, true) + ) + + mutate { this[identifier] = updated } + } + } + companion object { private val TAG = TestCertificateRepository::class.simpleName!! } diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/covidcertificate/test/core/TestCertificateWrapper.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/covidcertificate/test/core/TestCertificateWrapper.kt index 403f2b34d10ab0751429b88da4736072d97bf6c6..0df7c8164ead0b32c0651a94157746965feeeab7 100644 --- a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/covidcertificate/test/core/TestCertificateWrapper.kt +++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/covidcertificate/test/core/TestCertificateWrapper.kt @@ -17,6 +17,8 @@ data class TestCertificateWrapper( val registeredAt = container.registeredAt + val seenByUser = container.certificateSeenByUser + val testCertificate: TestCertificate? by lazy { container.toTestCertificate(valueSets) } diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/covidcertificate/test/core/storage/PCRCertificateData.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/covidcertificate/test/core/storage/PCRCertificateData.kt index 2fe7dcb304f97d7f8a5dfa079194d5bbc5bc2c66..d53a1d54b8bd82a026349e87f191443e7564fb4f 100644 --- a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/covidcertificate/test/core/storage/PCRCertificateData.kt +++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/covidcertificate/test/core/storage/PCRCertificateData.kt @@ -40,6 +40,9 @@ data class PCRCertificateData internal constructor( @SerializedName("labId") override val labId: String? = null, + + @SerializedName("certificateSeenByUser") + override val certificateSeenByUser: Boolean = false, ) : StoredTestCertificateData { // Otherwise GSON unsafes reflection to create this class, and sets the LAZY to null diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/covidcertificate/test/core/storage/RACertificateData.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/covidcertificate/test/core/storage/RACertificateData.kt index 8b87ecb424f012e4432e04e82536c5ff864ace23..fe10fabb6604501b72a8f73f6482095e834db3dc 100644 --- a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/covidcertificate/test/core/storage/RACertificateData.kt +++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/covidcertificate/test/core/storage/RACertificateData.kt @@ -40,6 +40,9 @@ data class RACertificateData( @SerializedName("labId") override val labId: String? = null, + + @SerializedName("certificateSeenByUser") + override val certificateSeenByUser: Boolean = false, ) : StoredTestCertificateData { // Otherwise GSON unsafes reflection to create this class, and sets the LAZY to null diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/covidcertificate/test/core/storage/StoredTestCertificateData.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/covidcertificate/test/core/storage/StoredTestCertificateData.kt index 16c307f8ecfdb83e2017b26bdb532653f3f67d94..9ce2281d176f35a686386dcea9203446f856edea 100644 --- a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/covidcertificate/test/core/storage/StoredTestCertificateData.kt +++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/covidcertificate/test/core/storage/StoredTestCertificateData.kt @@ -19,4 +19,5 @@ interface StoredTestCertificateData { val encryptedDccCose: ByteString? val testCertificateQrCode: String? val labId: String? + val certificateSeenByUser: Boolean } diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/covidcertificate/test/core/storage/TestCertificateProcessor.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/covidcertificate/test/core/storage/TestCertificateProcessor.kt index 4d7e14c25ec6582142e155f6fd4a0cd1fa090f44..3bf83340955ed2479b4c31217c36bba7154eca40 100644 --- a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/covidcertificate/test/core/storage/TestCertificateProcessor.kt +++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/covidcertificate/test/core/storage/TestCertificateProcessor.kt @@ -150,6 +150,17 @@ class TestCertificateProcessor @Inject constructor( } } + internal suspend fun updateSeenByUser( + data: StoredTestCertificateData, + seenByUser: Boolean, + ): StoredTestCertificateData { + Timber.tag(TAG).d("updateSeenByUser(data=%s, seenByUser=%b)", data, seenByUser) + return when (data.type) { + CoronaTest.Type.PCR -> (data as PCRCertificateData).copy(certificateSeenByUser = seenByUser) + CoronaTest.Type.RAPID_ANTIGEN -> (data as RACertificateData).copy(certificateSeenByUser = seenByUser) + } + } + companion object { private val TAG = TestCertificateProcessor::class.simpleName!! } diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/covidcertificate/test/ui/CertificatesFragment.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/covidcertificate/test/ui/CertificatesFragment.kt index f83587427e2bb2db0edccd20f58054192323ae6d..72d7113c3da5d9c8aa9a1797593b3f86a9ebda5e 100644 --- a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/covidcertificate/test/ui/CertificatesFragment.kt +++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/covidcertificate/test/ui/CertificatesFragment.kt @@ -43,7 +43,12 @@ class CertificatesFragment : Fragment(R.layout.fragment_certificates), AutoInjec adapter = certificatesAdapter } } - + viewModel.markNewCertsAsSeen.observe2(this) { + /** + * This just needs to stay subscribed while the UI is open. + * It causes new certificates to be marked seen automatically. + */ + } viewModel.screenItems.observe2(this) { items -> certificatesAdapter.update(items) } viewModel.events.observe2(this) { event -> when (event) { diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/covidcertificate/test/ui/CertificatesViewModel.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/covidcertificate/test/ui/CertificatesViewModel.kt index 0ac9d633983e176c2de5ef4bef3a22660b585d36..a531a8205e68c236dc653afcce1860cb31809de4 100644 --- a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/covidcertificate/test/ui/CertificatesViewModel.kt +++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/covidcertificate/test/ui/CertificatesViewModel.kt @@ -2,7 +2,6 @@ package de.rki.coronawarnapp.covidcertificate.test.ui import android.content.Context import androidx.lifecycle.LiveData -import androidx.lifecycle.asLiveData import dagger.assisted.AssistedFactory import dagger.assisted.AssistedInject import de.rki.coronawarnapp.contactdiary.util.getLocale @@ -26,7 +25,11 @@ import de.rki.coronawarnapp.util.di.AppContext import de.rki.coronawarnapp.util.ui.SingleLiveEvent import de.rki.coronawarnapp.util.viewmodel.CWAViewModel import de.rki.coronawarnapp.util.viewmodel.SimpleCWAViewModelFactory +import kotlinx.coroutines.flow.catch import kotlinx.coroutines.flow.combine +import kotlinx.coroutines.flow.map +import kotlinx.coroutines.flow.onEach +import timber.log.Timber class CertificatesViewModel @AssistedInject constructor( vaccinationRepository: VaccinationRepository, @@ -42,6 +45,18 @@ class CertificatesViewModel @AssistedInject constructor( val events = SingleLiveEvent<CertificatesFragmentEvents>() + val markNewCertsAsSeen = testCertificateRepository.certificates + .onEach { wrappers -> + wrappers + .filter { !it.seenByUser && !it.isCertificateRetrievalPending } + .forEach { + testCertificateRepository.markCertificateAsSeenByUser(it.identifier) + } + } + .map { } + .catch { Timber.w("Failed to mark certificates as seen.") } + .asLiveData2() + private fun refreshTestCertificate(identifier: TestCertificateIdentifier) { launch { val error = testCertificateRepository.refresh(identifier).mapNotNull { it.error }.singleOrNull() @@ -82,7 +97,8 @@ class CertificatesViewModel @AssistedInject constructor( addAll(certificates.toCertificateItems()) } } - }.asLiveData() + } + .asLiveData2() private fun Set<VaccinatedPerson>.toCertificateItems(): List<CertificatesItem> = map { vaccinatedPerson -> when (vaccinatedPerson.getVaccinationStatus()) { 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 698550e696ba035b1021e37c0eb0cb3eec7329c2..6f74ae24d081e3fe81e96e40d2e08d9bc642518a 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 @@ -26,13 +26,13 @@ import de.rki.coronawarnapp.ui.setupWithNavController2 import de.rki.coronawarnapp.ui.submission.qrcode.consent.SubmissionConsentFragment import de.rki.coronawarnapp.util.AppShortcuts import de.rki.coronawarnapp.util.CWADebug -import de.rki.coronawarnapp.util.ContextExtensions.getColorCompat import de.rki.coronawarnapp.util.DialogHelper import de.rki.coronawarnapp.util.device.PowerManagement import de.rki.coronawarnapp.util.di.AppInjector import de.rki.coronawarnapp.util.shortcuts.AppShortcutsHelper.Companion.getShortcutExtra import de.rki.coronawarnapp.util.ui.findNavController import de.rki.coronawarnapp.util.ui.findNestedGraph +import de.rki.coronawarnapp.util.ui.updateCountBadge import de.rki.coronawarnapp.util.viewmodel.CWAViewModelFactoryProvider import de.rki.coronawarnapp.util.viewmodel.cwaViewModels import org.joda.time.LocalDate @@ -103,16 +103,11 @@ class MainActivity : AppCompatActivity(), HasAndroidInjector { } vm.activeCheckIns.observe(this) { count -> - val targetId = R.id.trace_location_attendee_nav_graph - binding.mainBottomNavigation.apply { - if (count > 0) { - val badge = getOrCreateBadge(targetId) - badge.number = count - badge.badgeTextColor = getColorCompat(android.R.color.white) - } else { - removeBadge(targetId) - } - } + binding.mainBottomNavigation.updateCountBadge(R.id.trace_location_attendee_nav_graph, count) + } + + vm.newCertificates.observe(this) { count -> + binding.mainBottomNavigation.updateCountBadge(R.id.green_certificate_graph, count) } if (savedInstanceState == null) { diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/main/MainActivityViewModel.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/main/MainActivityViewModel.kt index 6fe194da45ba54ed22a245032879f0a93aeb8556..6890d05c4e7cbfbb73d9a5dfdcded9e7b0238435 100644 --- a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/main/MainActivityViewModel.kt +++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/main/MainActivityViewModel.kt @@ -2,10 +2,10 @@ package de.rki.coronawarnapp.ui.main import androidx.lifecycle.LiveData import androidx.lifecycle.MutableLiveData -import androidx.lifecycle.asLiveData import dagger.assisted.AssistedFactory import dagger.assisted.AssistedInject import de.rki.coronawarnapp.contactdiary.ui.ContactDiarySettings +import de.rki.coronawarnapp.covidcertificate.test.core.TestCertificateRepository import de.rki.coronawarnapp.covidcertificate.vaccination.core.VaccinationSettings import de.rki.coronawarnapp.environment.EnvironmentSetup import de.rki.coronawarnapp.playbook.BackgroundNoise @@ -31,7 +31,8 @@ class MainActivityViewModel @AssistedInject constructor( private val onboardingSettings: OnboardingSettings, private val traceLocationSettings: TraceLocationSettings, private val vaccinationSettings: VaccinationSettings, - checkInRepository: CheckInRepository + checkInRepository: CheckInRepository, + testCertificateRepository: TestCertificateRepository, ) : CWAViewModel( dispatcherProvider = dispatcherProvider ) { @@ -49,7 +50,13 @@ class MainActivityViewModel @AssistedInject constructor( val activeCheckIns = checkInRepository.checkInsWithinRetention .map { checkins -> checkins.filter { !it.completed }.size } - .asLiveData(context = dispatcherProvider.Default) + .asLiveData2() + + val newCertificates = testCertificateRepository.certificates + .map { certs -> + certs.filter { !it.seenByUser && !it.isCertificateRetrievalPending }.size + } + .asLiveData2() init { if (CWADebug.isDeviceForTestersBuild) { diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/util/ui/BottomNavigationViewExtensions.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/util/ui/BottomNavigationViewExtensions.kt new file mode 100644 index 0000000000000000000000000000000000000000..e118feb598543f94085928d719c1850abbf3b246 --- /dev/null +++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/util/ui/BottomNavigationViewExtensions.kt @@ -0,0 +1,15 @@ +package de.rki.coronawarnapp.util.ui + +import androidx.annotation.IdRes +import com.google.android.material.bottomnavigation.BottomNavigationView +import de.rki.coronawarnapp.util.ContextExtensions.getColorCompat + +fun BottomNavigationView.updateCountBadge(@IdRes badgeId: Int, count: Int) { + if (count > 0) { + val badge = getOrCreateBadge(badgeId) + badge.number = count + badge.badgeTextColor = context.getColorCompat(android.R.color.white) + } else { + removeBadge(badgeId) + } +} diff --git a/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/covidcertificate/storage/TestCertificateStorageTest.kt b/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/covidcertificate/storage/TestCertificateStorageTest.kt index 449f154a80d0a3b24da537e9cc5f3158724878cc..70ecfb98a7af021524c9fe1d3d5b533ff6df870c 100644 --- a/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/covidcertificate/storage/TestCertificateStorageTest.kt +++ b/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/covidcertificate/storage/TestCertificateStorageTest.kt @@ -79,7 +79,8 @@ class TestCertificateStorageTest : BaseTest() { "rsaPrivateKey": "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", "certificateReceivedAt": 123456789, "encryptedDataEncryptionkey": "ZW5jcnlwdGVkRGF0YUVuY3J5cHRpb25rZXk\u003d", - "testCertificateQrCode": "${certificateTestData.personATest1CertQRCodeString}" + "testCertificateQrCode": "${certificateTestData.personATest1CertQRCodeString}", + "certificateSeenByUser": false } ] """.toComparableJsonPretty() @@ -95,7 +96,8 @@ class TestCertificateStorageTest : BaseTest() { "rsaPrivateKey": "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", "certificateReceivedAt": 123456789, "encryptedDataEncryptionkey": "ZW5jcnlwdGVkRGF0YUVuY3J5cHRpb25rZXk\u003d", - "testCertificateQrCode": "${certificateTestData.personATest2CertQRCodeString}" + "testCertificateQrCode": "${certificateTestData.personATest2CertQRCodeString}", + "certificateSeenByUser": true } ] """.toComparableJsonPretty() diff --git a/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/covidcertificate/test/TestCertificateTestData.kt b/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/covidcertificate/test/TestCertificateTestData.kt index e6da753eb92a102b7916032147d183d729219e3d..3082a41b586ef74bbeed644dd8f272421d2d9869 100644 --- a/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/covidcertificate/test/TestCertificateTestData.kt +++ b/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/covidcertificate/test/TestCertificateTestData.kt @@ -61,7 +61,8 @@ class TestCertificateTestData @Inject constructor( rsaPrivateKey = privateKey, certificateReceivedAt = Instant.ofEpochMilli(123456789), encryptedDataEncryptionkey = "ZW5jcnlwdGVkRGF0YUVuY3J5cHRpb25rZXk=".decodeBase64()!!, - testCertificateQrCode = personATest2CertQRCodeString + testCertificateQrCode = personATest2CertQRCodeString, + certificateSeenByUser = true ) } diff --git a/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/main/MainActivityViewModelTest.kt b/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/main/MainActivityViewModelTest.kt index 7207e5d906348755d0391d887d1ba26c67c8103e..f57087d56331d08052724adc50dfa99c6e9fc151 100644 --- a/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/main/MainActivityViewModelTest.kt +++ b/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/main/MainActivityViewModelTest.kt @@ -1,6 +1,7 @@ package de.rki.coronawarnapp.main import de.rki.coronawarnapp.contactdiary.ui.ContactDiarySettings +import de.rki.coronawarnapp.covidcertificate.test.core.TestCertificateRepository import de.rki.coronawarnapp.covidcertificate.vaccination.core.VaccinationSettings import de.rki.coronawarnapp.environment.EnvironmentSetup import de.rki.coronawarnapp.playbook.BackgroundNoise @@ -16,6 +17,7 @@ import io.mockk.every import io.mockk.impl.annotations.MockK import io.mockk.mockkObject import kotlinx.coroutines.flow.MutableStateFlow +import kotlinx.coroutines.flow.emptyFlow import org.junit.jupiter.api.BeforeEach import org.junit.jupiter.api.Test import org.junit.jupiter.api.extension.ExtendWith @@ -36,6 +38,7 @@ class MainActivityViewModelTest : BaseTest() { @MockK lateinit var traceLocationSettings: TraceLocationSettings @MockK lateinit var checkInRepository: CheckInRepository @MockK lateinit var vaccinationSettings: VaccinationSettings + @MockK lateinit var testCertificateRepository: TestCertificateRepository @BeforeEach fun setup() { @@ -50,6 +53,7 @@ class MainActivityViewModelTest : BaseTest() { ) every { onboardingSettings.isBackgroundCheckDone } returns true every { checkInRepository.checkInsWithinRetention } returns MutableStateFlow(listOf()) + every { testCertificateRepository.certificates } returns emptyFlow() } private fun createInstance(): MainActivityViewModel = MainActivityViewModel( @@ -62,6 +66,7 @@ class MainActivityViewModelTest : BaseTest() { checkInRepository = checkInRepository, traceLocationSettings = traceLocationSettings, vaccinationSettings = vaccinationSettings, + testCertificateRepository = testCertificateRepository, ) @Test