diff --git a/Corona-Warn-App/build.gradle b/Corona-Warn-App/build.gradle index 07b49cd3c4699cfce56cd2f44945d730183b6bb9..06191fd03f637ca09a0d6667492c8d6102cd781e 100644 --- a/Corona-Warn-App/build.gradle +++ b/Corona-Warn-App/build.gradle @@ -303,7 +303,7 @@ configurations.all { dependencies { // KOTLIN - def coroutineVersion = "1.4.2" + def coroutineVersion = "1.5.0" implementation "org.jetbrains.kotlinx:kotlinx-coroutines-core:$coroutineVersion" implementation "org.jetbrains.kotlinx:kotlinx-coroutines-android:$coroutineVersion" implementation "org.jetbrains.kotlinx:kotlinx-coroutines-play-services:$coroutineVersion" diff --git a/Corona-Warn-App/src/deviceForTesters/java/de/rki/coronawarnapp/test/coronatest/ui/CoronaTestTestFragment.kt b/Corona-Warn-App/src/deviceForTesters/java/de/rki/coronawarnapp/test/coronatest/ui/CoronaTestTestFragment.kt index 16d5cdc4527c205bcc11b49f7efb91ffa3d56e22..1209ca39b3c81070e61673188466c2ba08f30234 100644 --- a/Corona-Warn-App/src/deviceForTesters/java/de/rki/coronawarnapp/test/coronatest/ui/CoronaTestTestFragment.kt +++ b/Corona-Warn-App/src/deviceForTesters/java/de/rki/coronawarnapp/test/coronatest/ui/CoronaTestTestFragment.kt @@ -66,7 +66,7 @@ class CoronaTestTestFragment : Fragment(R.layout.fragment_test_coronatest), Auto } vm.pcrtState.observe2(this) { - binding.pcrtData.text = it.getNiceTextForHumans(requireContext()) + binding.pcrtData.text = it.getNiceTextForHumans() } binding.apply { pcrtDeleteAction.setOnClickListener { vm.deletePCRT() } @@ -74,7 +74,7 @@ class CoronaTestTestFragment : Fragment(R.layout.fragment_test_coronatest), Auto } vm.ratState.observe2(this) { - binding.ratData.text = it.getNiceTextForHumans(requireContext()) + binding.ratData.text = it.getNiceTextForHumans() } binding.apply { ratDeleteAction.setOnClickListener { vm.deleteRAT() } diff --git a/Corona-Warn-App/src/deviceForTesters/java/de/rki/coronawarnapp/test/coronatest/ui/CoronaTestTestFragmentViewModel.kt b/Corona-Warn-App/src/deviceForTesters/java/de/rki/coronawarnapp/test/coronatest/ui/CoronaTestTestFragmentViewModel.kt index 1f5a05014104c4351e03b1e35f2bd50ebfe035a3..df524f3e15299e9f137bd1c73706e1fea68eca5d 100644 --- a/Corona-Warn-App/src/deviceForTesters/java/de/rki/coronawarnapp/test/coronatest/ui/CoronaTestTestFragmentViewModel.kt +++ b/Corona-Warn-App/src/deviceForTesters/java/de/rki/coronawarnapp/test/coronatest/ui/CoronaTestTestFragmentViewModel.kt @@ -1,6 +1,5 @@ package de.rki.coronawarnapp.test.coronatest.ui -import android.content.Context import androidx.lifecycle.asLiveData import com.journeyapps.barcodescanner.BarcodeResult import dagger.assisted.AssistedFactory @@ -100,7 +99,7 @@ class CoronaTestTestFragmentViewModel @AssistedInject constructor( data class PCRTState( val coronaTest: PCRCoronaTest? ) { - fun getNiceTextForHumans(context: Context): String { + fun getNiceTextForHumans(): String { return coronaTest ?.toString() ?.replace("PCRCoronaTest(", "") @@ -113,7 +112,7 @@ class CoronaTestTestFragmentViewModel @AssistedInject constructor( data class RATState( val coronaTest: RACoronaTest? ) { - fun getNiceTextForHumans(context: Context): String { + fun getNiceTextForHumans(): String { return coronaTest ?.toString() ?.replace("RACoronaTest(", "") diff --git a/Corona-Warn-App/src/deviceForTesters/java/de/rki/coronawarnapp/test/tasks/testtask/TestTask.kt b/Corona-Warn-App/src/deviceForTesters/java/de/rki/coronawarnapp/test/tasks/testtask/TestTask.kt index 45c6a1a39cb71af33faf15ee88baf8433099c4a4..7562774206b3f5a528bc1612ea7dc0fdb1407008 100644 --- a/Corona-Warn-App/src/deviceForTesters/java/de/rki/coronawarnapp/test/tasks/testtask/TestTask.kt +++ b/Corona-Warn-App/src/deviceForTesters/java/de/rki/coronawarnapp/test/tasks/testtask/TestTask.kt @@ -3,11 +3,13 @@ package de.rki.coronawarnapp.test.tasks.testtask import de.rki.coronawarnapp.task.Task import de.rki.coronawarnapp.task.TaskCancellationException import de.rki.coronawarnapp.task.TaskFactory +import de.rki.coronawarnapp.task.common.Finished +import de.rki.coronawarnapp.task.common.ProgressResult +import de.rki.coronawarnapp.task.common.Started import de.rki.coronawarnapp.task.common.DefaultProgress -import kotlinx.coroutines.channels.ConflatedBroadcastChannel import kotlinx.coroutines.delay import kotlinx.coroutines.flow.Flow -import kotlinx.coroutines.flow.asFlow +import kotlinx.coroutines.flow.MutableStateFlow import org.joda.time.Duration import org.joda.time.Instant import timber.log.Timber @@ -16,8 +18,8 @@ import javax.inject.Provider class TestTask @Inject constructor() : Task<DefaultProgress, TestTask.Result> { - private val internalProgress = ConflatedBroadcastChannel<DefaultProgress>() - override val progress: Flow<DefaultProgress> = internalProgress.asFlow() + private val internalProgress = MutableStateFlow<DefaultProgress>(Started) + override val progress: Flow<DefaultProgress> = internalProgress private var isCanceled = false @@ -28,13 +30,12 @@ class TestTask @Inject constructor() : Task<DefaultProgress, TestTask.Result> { if (isCanceled) throw TaskCancellationException() } } finally { - internalProgress.close() + internalProgress.value = Finished } private suspend fun runSafely(arguments: Arguments): Result { for (it in 1..10) { - internalProgress.send(DefaultProgress("${arguments.prefix}: ${Instant.now()}")) - + internalProgress.value = ProgressResult("${arguments.prefix}: ${Instant.now()}") delay(1000) if (isCanceled) break diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/CoronaWarnApplication.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/CoronaWarnApplication.kt index 0145584b0d9c32f272b62e77a1159ff96c643d17..3ed502671e04c4b8701db640498740185c7e9f5a 100644 --- a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/CoronaWarnApplication.kt +++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/CoronaWarnApplication.kt @@ -36,12 +36,13 @@ import de.rki.coronawarnapp.task.TaskController import de.rki.coronawarnapp.util.BuildVersionWrap import de.rki.coronawarnapp.util.CWADebug import de.rki.coronawarnapp.util.WatchdogService +import de.rki.coronawarnapp.util.coroutine.AppScope import de.rki.coronawarnapp.util.device.ForegroundState import de.rki.coronawarnapp.util.di.AppInjector import de.rki.coronawarnapp.util.di.ApplicationComponent import de.rki.coronawarnapp.util.hasAPILevel import de.rki.coronawarnapp.vaccination.core.execution.VaccinationUpdateScheduler -import kotlinx.coroutines.GlobalScope +import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.flow.launchIn import kotlinx.coroutines.flow.onEach import org.conscrypt.Conscrypt @@ -81,6 +82,9 @@ class CoronaWarnApplication : Application(), HasAndroidInjector { @Inject lateinit var raTestResultAvailableNotificationService: RATTestResultAvailableNotificationService @Inject lateinit var vaccinationUpdateScheduler: VaccinationUpdateScheduler + @AppScope + @Inject lateinit var appScope: CoroutineScope + @LogHistoryTree @Inject lateinit var rollingLogHistory: Timber.Tree override fun onCreate() { @@ -113,7 +117,7 @@ class CoronaWarnApplication : Application(), HasAndroidInjector { foregroundState.isInForeground .onEach { isAppInForeground = it } - .launchIn(GlobalScope) + .launchIn(appScope) Timber.v("Setting up contact diary work scheduler") contactDiaryWorkScheduler.setup() diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/contactdiary/retention/ContactDiaryCleanTask.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/contactdiary/retention/ContactDiaryCleanTask.kt index 84a790910d2e197e902526256e1cd94f3ecdf5e6..b6a76a2471226424e34c35161eead806bbc26c02 100644 --- a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/contactdiary/retention/ContactDiaryCleanTask.kt +++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/contactdiary/retention/ContactDiaryCleanTask.kt @@ -3,9 +3,10 @@ package de.rki.coronawarnapp.contactdiary.retention import de.rki.coronawarnapp.task.Task import de.rki.coronawarnapp.task.TaskFactory import de.rki.coronawarnapp.task.common.DefaultProgress -import kotlinx.coroutines.channels.ConflatedBroadcastChannel +import de.rki.coronawarnapp.task.common.Finished +import de.rki.coronawarnapp.task.common.Started import kotlinx.coroutines.flow.Flow -import kotlinx.coroutines.flow.asFlow +import kotlinx.coroutines.flow.MutableStateFlow import org.joda.time.Duration import timber.log.Timber import javax.inject.Inject @@ -15,8 +16,8 @@ class ContactDiaryCleanTask @Inject constructor( private val retentionCalculation: ContactDiaryRetentionCalculation ) : Task<DefaultProgress, Task.Result> { - private val internalProgress = ConflatedBroadcastChannel<DefaultProgress>() - override val progress: Flow<DefaultProgress> = internalProgress.asFlow() + private val internalProgress = MutableStateFlow<DefaultProgress>(Started) + override val progress: Flow<DefaultProgress> = internalProgress private var isCanceled = false @@ -38,7 +39,7 @@ class ContactDiaryCleanTask @Inject constructor( throw error } finally { Timber.i("Finished (isCanceled=$isCanceled).") - internalProgress.close() + internalProgress.value = Finished } override suspend fun cancel() { diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/diagnosiskeys/download/DownloadDiagnosisKeysTask.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/diagnosiskeys/download/DownloadDiagnosisKeysTask.kt index ba1448d41337ec126c6f9de5dc27f234dba858b3..be7784d24b6031a82c5e2d3070c7dc2eeab9f593 100644 --- a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/diagnosiskeys/download/DownloadDiagnosisKeysTask.kt +++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/diagnosiskeys/download/DownloadDiagnosisKeysTask.kt @@ -15,9 +15,8 @@ import de.rki.coronawarnapp.task.TaskFactory import de.rki.coronawarnapp.task.TaskFactory.Config.CollisionBehavior import de.rki.coronawarnapp.util.TimeStamper import de.rki.coronawarnapp.util.ui.toLazyString -import kotlinx.coroutines.channels.ConflatedBroadcastChannel import kotlinx.coroutines.flow.Flow -import kotlinx.coroutines.flow.asFlow +import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.flow.first import org.joda.time.Duration import org.joda.time.Instant @@ -37,8 +36,8 @@ class DownloadDiagnosisKeysTask @Inject constructor( private val coronaTestRepository: CoronaTestRepository, ) : Task<DownloadDiagnosisKeysTask.Progress, DownloadDiagnosisKeysTask.Result> { - private val internalProgress = ConflatedBroadcastChannel<Progress>() - override val progress: Flow<Progress> = internalProgress.asFlow() + private val internalProgress = MutableStateFlow<Progress>(Progress.Started) + override val progress: Flow<Progress> = internalProgress private var isCanceled = false @@ -67,8 +66,8 @@ class DownloadDiagnosisKeysTask @Inject constructor( // RETRIEVE RISK SCORE PARAMETERS val exposureConfig: ConfigData = appConfigProvider.getAppConfig() - internalProgress.send(Progress.ApiSubmissionStarted) - internalProgress.send(Progress.KeyFilesDownloadStarted) + internalProgress.value = Progress.ApiSubmissionStarted + internalProgress.value = Progress.KeyFilesDownloadStarted val requestedCountries = arguments.requestedCountries val keySyncResult = getAvailableKeyFiles(requestedCountries) @@ -104,12 +103,7 @@ class DownloadDiagnosisKeysTask @Inject constructor( val availableKeyFiles = keySyncResult.availableKeys.map { it.path } val totalFileSize = availableKeyFiles.fold(0L, { acc, file -> file.length() + acc }) - internalProgress.send( - Progress.KeyFilesDownloadFinished( - availableKeyFiles.size, - totalFileSize - ) - ) + internalProgress.value = Progress.KeyFilesDownloadFinished(availableKeyFiles.size, totalFileSize) // remember version code of this execution for next time settings.updateLastVersionCodeToCurrent() @@ -127,7 +121,7 @@ class DownloadDiagnosisKeysTask @Inject constructor( ) Timber.tag(TAG).d("Diagnosis Keys provided (success=%s)", isSubmissionSuccessful) - internalProgress.send(Progress.ApiSubmissionFinished) + internalProgress.value = Progress.ApiSubmissionFinished return Result() } catch (error: Exception) { @@ -138,7 +132,7 @@ class DownloadDiagnosisKeysTask @Inject constructor( throw error } finally { Timber.i("Finished (isCanceled=$isCanceled).") - internalProgress.close() + internalProgress.value = Progress.Finished } } @@ -218,6 +212,8 @@ class DownloadDiagnosisKeysTask @Inject constructor( class Result : Task.Result sealed class Progress : Task.Progress { + object Started : Progress() + object Finished : Progress() object ApiSubmissionStarted : Progress() object ApiSubmissionFinished : Progress() diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/presencetracing/risk/execution/PresenceTracingWarningTask.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/presencetracing/risk/execution/PresenceTracingWarningTask.kt index ea7b2eece6db44ee9736e3c964240429d3775a14..a55f59dbd258a45c9ba9252411bed5b2173cbd84 100644 --- a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/presencetracing/risk/execution/PresenceTracingWarningTask.kt +++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/presencetracing/risk/execution/PresenceTracingWarningTask.kt @@ -15,10 +15,9 @@ import de.rki.coronawarnapp.presencetracing.warning.storage.TraceWarningReposito import de.rki.coronawarnapp.task.Task import de.rki.coronawarnapp.task.TaskCancellationException import de.rki.coronawarnapp.task.TaskFactory -import de.rki.coronawarnapp.util.TimeStamper -import kotlinx.coroutines.channels.ConflatedBroadcastChannel +import de.rki.coronawarnapp.task.common.Finished import kotlinx.coroutines.flow.Flow -import kotlinx.coroutines.flow.asFlow +import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.flow.first import kotlinx.coroutines.flow.firstOrNull import org.joda.time.Duration @@ -27,7 +26,6 @@ import javax.inject.Inject import javax.inject.Provider class PresenceTracingWarningTask @Inject constructor( - private val timeStamper: TimeStamper, private val syncTool: TraceWarningPackageSyncTool, private val checkInWarningMatcher: CheckInWarningMatcher, private val presenceTracingRiskRepository: PresenceTracingRiskRepository, @@ -38,8 +36,9 @@ class PresenceTracingWarningTask @Inject constructor( private val autoCheckOut: AutoCheckOut, ) : Task<PresenceTracingWarningTaskProgress, PresenceTracingWarningTask.Result> { - private val internalProgress = ConflatedBroadcastChannel<PresenceTracingWarningTaskProgress>() - override val progress: Flow<PresenceTracingWarningTaskProgress> = internalProgress.asFlow() + private val internalProgress = + MutableStateFlow<PresenceTracingWarningTaskProgress>(PresenceTracingWarningTaskProgress.Started) + override val progress: Flow<PresenceTracingWarningTaskProgress> = internalProgress private var isCanceled = false @@ -65,7 +64,7 @@ class PresenceTracingWarningTask @Inject constructor( throw error } finally { Timber.i("Finished (isCanceled=$isCanceled).") - internalProgress.close() + internalProgress.value = PresenceTracingWarningTaskProgress.Finished } private suspend fun doWork(): Result { @@ -75,7 +74,7 @@ class PresenceTracingWarningTask @Inject constructor( presenceTracingRiskMapper.clearConfig() Timber.tag(TAG).d("Syncing packages.") - internalProgress.send(PresenceTracingWarningTaskProgress.Downloading()) + internalProgress.value = PresenceTracingWarningTaskProgress.Downloading() val syncResult = syncTool.syncPackages() @@ -119,7 +118,7 @@ class PresenceTracingWarningTask @Inject constructor( } Timber.tag(TAG).d("Running check-in matcher.") - internalProgress.send(PresenceTracingWarningTaskProgress.Calculating()) + internalProgress.value = PresenceTracingWarningTaskProgress.Calculating() val matcherResult = checkInWarningMatcher.process( checkIns = checkIns, diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/presencetracing/risk/execution/PresenceTracingWarningTaskProgress.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/presencetracing/risk/execution/PresenceTracingWarningTaskProgress.kt index a7c9869954c5a4435f65ffcb772b09648bd64a85..acd57eb491e0ffade32bba02e03d4c81094d7ee2 100644 --- a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/presencetracing/risk/execution/PresenceTracingWarningTaskProgress.kt +++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/presencetracing/risk/execution/PresenceTracingWarningTaskProgress.kt @@ -6,6 +6,14 @@ import de.rki.coronawarnapp.util.ui.LazyString sealed class PresenceTracingWarningTaskProgress : Task.Progress { + object Started : PresenceTracingWarningTaskProgress() { + override val primaryMessage: LazyString = CachedString { "" } + } + + object Finished : PresenceTracingWarningTaskProgress() { + override val primaryMessage: LazyString = CachedString { "" } + } + data class Downloading( override val primaryMessage: LazyString = CachedString { "" } ) : PresenceTracingWarningTaskProgress() diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/risk/RiskLevelTask.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/risk/RiskLevelTask.kt index cab719c6c8faeeb36b4c8c43ed266f39f42c166f..29b46a9ce6a242921afb35ad2a8d338b0f0ff577 100644 --- a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/risk/RiskLevelTask.kt +++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/risk/RiskLevelTask.kt @@ -18,12 +18,13 @@ import de.rki.coronawarnapp.risk.storage.RiskLevelStorage import de.rki.coronawarnapp.task.Task import de.rki.coronawarnapp.task.TaskCancellationException import de.rki.coronawarnapp.task.TaskFactory +import de.rki.coronawarnapp.task.common.Finished +import de.rki.coronawarnapp.task.common.Started import de.rki.coronawarnapp.task.common.DefaultProgress import de.rki.coronawarnapp.util.TimeStamper import de.rki.coronawarnapp.util.device.BackgroundModeStatus -import kotlinx.coroutines.channels.ConflatedBroadcastChannel import kotlinx.coroutines.flow.Flow -import kotlinx.coroutines.flow.asFlow +import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.flow.first import org.joda.time.Duration import org.joda.time.Instant @@ -45,8 +46,8 @@ class RiskLevelTask @Inject constructor( private val analyticsExposureWindowCollector: AnalyticsExposureWindowCollector, ) : Task<DefaultProgress, EwRiskLevelTaskResult> { - private val internalProgress = ConflatedBroadcastChannel<DefaultProgress>() - override val progress: Flow<DefaultProgress> = internalProgress.asFlow() + private val internalProgress = MutableStateFlow<DefaultProgress>(Started) + override val progress: Flow<DefaultProgress> = internalProgress private var isCanceled = false @@ -56,7 +57,7 @@ class RiskLevelTask @Inject constructor( val configData: ConfigData = appConfigProvider.getAppConfig() determineRiskLevelResult(configData).also { - Timber.i("Risklevel determined: %s", it) + Timber.i("Risk level determined: %s", it) checkCancel() @@ -71,7 +72,7 @@ class RiskLevelTask @Inject constructor( throw error } finally { Timber.i("Finished (isCanceled=$isCanceled).") - internalProgress.close() + internalProgress.value = Finished } private suspend fun determineRiskLevelResult(configData: ConfigData): EwRiskLevelTaskResult { diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/submission/task/SubmissionTask.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/submission/task/SubmissionTask.kt index bf8c50d1dfadb1311526b939be3deaaede65c962..01ba0e6a4676c9c61050b2b5748c5341aab47abc 100644 --- a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/submission/task/SubmissionTask.kt +++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/submission/task/SubmissionTask.kt @@ -20,11 +20,12 @@ import de.rki.coronawarnapp.submission.data.tekhistory.TEKHistoryStorage import de.rki.coronawarnapp.task.Task import de.rki.coronawarnapp.task.TaskCancellationException import de.rki.coronawarnapp.task.TaskFactory +import de.rki.coronawarnapp.task.common.Finished +import de.rki.coronawarnapp.task.common.Started import de.rki.coronawarnapp.task.common.DefaultProgress import de.rki.coronawarnapp.util.TimeStamper -import kotlinx.coroutines.channels.ConflatedBroadcastChannel import kotlinx.coroutines.flow.Flow -import kotlinx.coroutines.flow.asFlow +import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.flow.first import org.joda.time.Duration import timber.log.Timber @@ -47,8 +48,8 @@ class SubmissionTask @Inject constructor( private val coronaTestRepository: CoronaTestRepository, ) : Task<DefaultProgress, SubmissionTask.Result> { - private val internalProgress = ConflatedBroadcastChannel<DefaultProgress>() - override val progress: Flow<DefaultProgress> = internalProgress.asFlow() + private val internalProgress = MutableStateFlow<DefaultProgress>(Started) + override val progress: Flow<DefaultProgress> = internalProgress private var isCanceled = false @@ -85,7 +86,7 @@ class SubmissionTask @Inject constructor( throw error } finally { Timber.i("Finished (isCanceled=$isCanceled).") - internalProgress.close() + internalProgress.value = Finished } } diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/task/TaskController.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/task/TaskController.kt index 1f2ed9d8415f5220febbf7d72c7d340438d66676..41f0ac32e908c32f0ba329c5c97656307c11854b 100644 --- a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/task/TaskController.kt +++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/task/TaskController.kt @@ -63,7 +63,7 @@ class TaskController @Inject constructor( } /** - * Don't re-use taskrequests, create new requests for each submission. + * Don't re-use task requests, create new requests for each submission. * They contain unique IDs. */ fun submit(request: TaskRequest) { @@ -71,7 +71,7 @@ class TaskController @Inject constructor( throw MissingTaskFactoryException(request::class) } Timber.tag(TAG).i("Task submitted: %s", request) - taskQueue.offer(request) + taskQueue.trySend(request) } suspend fun cancel(requestId: UUID) = internalTaskData.updateSafely { diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/task/common/DefaultProgress.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/task/common/DefaultProgress.kt index 3d3912df9e6d6f65fe79df8ef0b11fa5552ece89..0f3dcf89befdf71a0c7d65334d91d747929d51e2 100644 --- a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/task/common/DefaultProgress.kt +++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/task/common/DefaultProgress.kt @@ -2,13 +2,12 @@ package de.rki.coronawarnapp.task.common import de.rki.coronawarnapp.task.Task import de.rki.coronawarnapp.util.ui.CachedString -import de.rki.coronawarnapp.util.ui.LazyString -data class DefaultProgress constructor( - override val primaryMessage: LazyString -) : Task.Progress { - - constructor( - primary: String - ) : this(CachedString { primary }) +sealed class DefaultProgress(progressMessage: String) : Task.Progress { + override val primaryMessage = CachedString { progressMessage } } + +object Started : DefaultProgress("Started") +object Finished : DefaultProgress("Finished") + +data class ProgressResult(val progressMessage: String) : DefaultProgress(progressMessage) diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/vaccination/core/execution/VaccinationUpdateScheduler.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/vaccination/core/execution/VaccinationUpdateScheduler.kt index 5a1f61e59c1e8cb87611907a0f8ebbc38578260c..5393642f6da98b91c3e16e73b3260c7bedb1a8cc 100644 --- a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/vaccination/core/execution/VaccinationUpdateScheduler.kt +++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/vaccination/core/execution/VaccinationUpdateScheduler.kt @@ -44,7 +44,7 @@ class VaccinationUpdateScheduler @Inject constructor( } vaccinationRepository.vaccinationInfos - .map { vaccinatedPersons -> + .map { false // NOOP, but we want to keep the logic for now } .distinctUntilChanged() @@ -59,11 +59,11 @@ class VaccinationUpdateScheduler @Inject constructor( // If there is a pending check or we have stale data, we refresh immediately when opening the app combine( // Pending checks? - vaccinationRepository.vaccinationInfos.map { persons -> + vaccinationRepository.vaccinationInfos.map { false // NOOP, but we want to keep the logic for now }.distinctUntilChanged(), // Stale data? - vaccinationRepository.vaccinationInfos.map { persons -> + vaccinationRepository.vaccinationInfos.map { false // NOOP, but we want to keep the logic for now }.distinctUntilChanged(), foregroundState.isInForeground diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/vaccination/core/execution/task/VaccinationUpdateTask.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/vaccination/core/execution/task/VaccinationUpdateTask.kt index 3f02678f087144b55d3b1d2bc4de05d19223ee27..fdb14d5e90df4e916c192a18b504460112397c4e 100644 --- a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/vaccination/core/execution/task/VaccinationUpdateTask.kt +++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/vaccination/core/execution/task/VaccinationUpdateTask.kt @@ -4,24 +4,23 @@ import de.rki.coronawarnapp.appconfig.AppConfigProvider import de.rki.coronawarnapp.bugreporting.reportProblem import de.rki.coronawarnapp.task.Task import de.rki.coronawarnapp.task.TaskFactory +import de.rki.coronawarnapp.task.common.Finished +import de.rki.coronawarnapp.task.common.Started import de.rki.coronawarnapp.task.common.DefaultProgress -import de.rki.coronawarnapp.util.TimeStamper import de.rki.coronawarnapp.vaccination.core.repository.VaccinationRepository -import kotlinx.coroutines.channels.ConflatedBroadcastChannel import kotlinx.coroutines.flow.Flow -import kotlinx.coroutines.flow.asFlow +import kotlinx.coroutines.flow.MutableStateFlow import org.joda.time.Duration import timber.log.Timber import javax.inject.Inject import javax.inject.Provider class VaccinationUpdateTask @Inject constructor( - private val timeStamper: TimeStamper, private val vaccinationRepository: VaccinationRepository, ) : Task<DefaultProgress, VaccinationUpdateTask.Result> { - private val internalProgress = ConflatedBroadcastChannel<DefaultProgress>() - override val progress: Flow<DefaultProgress> = internalProgress.asFlow() + private val internalProgress = MutableStateFlow<DefaultProgress>(Started) + override val progress: Flow<DefaultProgress> = internalProgress private var isCanceled = false @@ -35,7 +34,7 @@ class VaccinationUpdateTask @Inject constructor( throw error } finally { Timber.i("Finished (isCanceled=$isCanceled).") - internalProgress.close() + internalProgress.value = Finished } private suspend fun doWork(): Result { diff --git a/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/CoronaWarnApplicationTest.kt b/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/CoronaWarnApplicationTest.kt index 65ab5efe75b2ee24c625d50fde410893d31d355b..3ac27d32535f18a5afbff9c55e08b70eef31ecb6 100644 --- a/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/CoronaWarnApplicationTest.kt +++ b/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/CoronaWarnApplicationTest.kt @@ -36,6 +36,7 @@ import io.mockk.mockk import io.mockk.mockkObject import io.mockk.mockkStatic import io.mockk.verifySequence +import kotlinx.coroutines.test.TestCoroutineScope import org.conscrypt.Conscrypt import org.junit.jupiter.api.BeforeEach import org.junit.jupiter.api.Test @@ -122,6 +123,7 @@ class CoronaWarnApplicationTest : BaseTest() { app.pcrTestResultAvailableNotificationService = pcrTestResultAvailableNotificationService app.raTestResultAvailableNotificationService = raTestResultAvailableNotificationService app.vaccinationUpdateScheduler = vaccinationUpdateScheduler + app.appScope = TestCoroutineScope() app.rollingLogHistory = object : Timber.Tree() { override fun log(priority: Int, tag: String?, message: String, t: Throwable?) { // NOOP diff --git a/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/presencetracing/risk/execution/PresenceTracingWarningTaskTest.kt b/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/presencetracing/risk/execution/PresenceTracingWarningTaskTest.kt index 98d7ace516554e1496faa5d6e0c784999f0db1c4..5fd04aacfcf35840aad5b9b69a704e07e4d16014 100644 --- a/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/presencetracing/risk/execution/PresenceTracingWarningTaskTest.kt +++ b/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/presencetracing/risk/execution/PresenceTracingWarningTaskTest.kt @@ -14,7 +14,6 @@ import de.rki.coronawarnapp.presencetracing.warning.download.TraceWarningPackage import de.rki.coronawarnapp.presencetracing.warning.storage.TraceWarningPackage import de.rki.coronawarnapp.presencetracing.warning.storage.TraceWarningRepository import de.rki.coronawarnapp.server.protocols.internal.pt.TraceWarning -import de.rki.coronawarnapp.util.TimeStamper import io.kotest.assertions.throwables.shouldThrow import io.kotest.matchers.comparables.shouldBeLessThan import io.kotest.matchers.shouldNotBe @@ -31,7 +30,6 @@ import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.flow.flowOf import kotlinx.coroutines.test.runBlockingTest import org.joda.time.Duration -import org.joda.time.Instant import org.junit.jupiter.api.BeforeEach import org.junit.jupiter.api.Test import testhelpers.BaseTest @@ -39,7 +37,6 @@ import java.io.IOException class PresenceTracingWarningTaskTest : BaseTest() { - @MockK lateinit var timeStamper: TimeStamper @MockK lateinit var syncTool: TraceWarningPackageSyncTool @MockK lateinit var checkInWarningMatcher: CheckInWarningMatcher @MockK lateinit var presenceTracingRiskRepository: PresenceTracingRiskRepository @@ -61,7 +58,6 @@ class PresenceTracingWarningTaskTest : BaseTest() { every { coronaTestRepository.coronaTests } returns coronaTests - every { timeStamper.nowUTC } returns Instant.ofEpochMilli(9000) coEvery { syncTool.syncPackages() } returns TraceWarningPackageSyncTool.SyncResult(successful = true) coEvery { checkInWarningMatcher.process(any(), any()) } answers { CheckInWarningMatcher.Result( @@ -95,7 +91,6 @@ class PresenceTracingWarningTaskTest : BaseTest() { } private fun createInstance() = PresenceTracingWarningTask( - timeStamper = timeStamper, syncTool = syncTool, checkInWarningMatcher = checkInWarningMatcher, presenceTracingRiskRepository = presenceTracingRiskRepository, diff --git a/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/task/TaskControllerTest.kt b/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/task/TaskControllerTest.kt index 71370335eeb30b6f17ba1c479cb12a3d0c467da3..cdd01e22da45ec349d12ffc1b8d200eb63db0fd7 100644 --- a/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/task/TaskControllerTest.kt +++ b/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/task/TaskControllerTest.kt @@ -3,6 +3,7 @@ package de.rki.coronawarnapp.task import de.rki.coronawarnapp.bugreporting.reportProblem import de.rki.coronawarnapp.exception.reporting.report import de.rki.coronawarnapp.task.common.DefaultTaskRequest +import de.rki.coronawarnapp.task.common.Finished import de.rki.coronawarnapp.task.testtasks.SkippingTask import de.rki.coronawarnapp.task.testtasks.alerterror.AlertErrorTask import de.rki.coronawarnapp.task.testtasks.precondition.PreconditionTask @@ -41,30 +42,29 @@ import org.junit.jupiter.api.AfterEach import org.junit.jupiter.api.BeforeEach import org.junit.jupiter.api.Test import testhelpers.BaseIOTest +import testhelpers.coroutines.runBlockingTest2 import testhelpers.coroutines.test import testhelpers.extensions.isAfterOrEqual import java.io.File import java.io.FileNotFoundException import java.util.UUID -import javax.inject.Provider class TaskControllerTest : BaseIOTest() { private val taskFactoryMap: MutableMap< Class<out Task<Task.Progress, Task.Result>>, - TaskFactory<out Task.Progress, out Task.Result> - > = mutableMapOf() + TaskFactory<out Task.Progress, out Task.Result>> = mutableMapOf() @MockK lateinit var timeStamper: TimeStamper private val testDir = File(IO_TEST_BASEDIR, this::class.java.simpleName) - private val timeoutFactory = spyk(TimeoutTask.Factory(Provider { TimeoutTask() })) - private val timeoutFactory2 = spyk(TimeoutTask2.Factory(Provider { TimeoutTask2() })) - private val queueingFactory = spyk(QueueingTask.Factory(Provider { QueueingTask() })) - private val skippingFactory = spyk(SkippingTask.Factory(Provider { SkippingTask() })) - private val preconditionFactory = spyk(PreconditionTask.Factory(Provider { PreconditionTask() })) - private val silentErrorFactory = spyk(SilentErrorTask.Factory(Provider { SilentErrorTask() })) - private val alertErrorFactory = spyk(AlertErrorTask.Factory(Provider { AlertErrorTask() })) + private val timeoutFactory = spyk(TimeoutTask.Factory { TimeoutTask() }) + private val timeoutFactory2 = spyk(TimeoutTask2.Factory { TimeoutTask2() }) + private val queueingFactory = spyk(QueueingTask.Factory { QueueingTask() }) + private val skippingFactory = spyk(SkippingTask.Factory { SkippingTask() }) + private val preconditionFactory = spyk(PreconditionTask.Factory { PreconditionTask() }) + private val silentErrorFactory = spyk(SilentErrorTask.Factory { SilentErrorTask() }) + private val alertErrorFactory = spyk(AlertErrorTask.Factory { AlertErrorTask() }) @BeforeEach fun setup() { @@ -96,7 +96,7 @@ class TaskControllerTest : BaseIOTest() { ) @Test - fun `sideeffect free init`() = runBlockingTest { + fun `side effect free init`() = runBlockingTest { shouldNotThrowAny { val instance = createInstance(scope = this) instance.close() @@ -130,7 +130,7 @@ class TaskControllerTest : BaseIOTest() { } @Test - fun `default task execution`() = runBlockingTest { + fun `default task execution`() = runBlockingTest2(ignoreActive = true) { val instance = createInstance(scope = this) val arguments = QueueingTask.Arguments( @@ -166,12 +166,9 @@ class TaskControllerTest : BaseIOTest() { arguments.path.exists() shouldBe true - val lastProgressMessage = progressCollector.latestValue!!.primaryMessage.get(mockk()) - lastProgressMessage shouldBe arguments.values.last() + progressCollector.latestValue shouldBe Finished infoFinished.apply { - // No more progress, task is finished -// progress.first() shouldBe "" taskState.isSuccessful shouldBe true taskState.resultOrThrow shouldNotBe null @@ -195,7 +192,7 @@ class TaskControllerTest : BaseIOTest() { } @Test - fun `failed task yields exception`() = runBlockingTest { + fun `failed task yields exception`() = runBlockingTest2(ignoreActive = true) { val instance = createInstance(scope = this) val arguments = QueueingTask.Arguments( @@ -234,7 +231,7 @@ class TaskControllerTest : BaseIOTest() { } @Test - fun `canceled task yields exception`() = runBlockingTest { + fun `canceled task yields exception`() = runBlockingTest2(ignoreActive = true) { val instance = createInstance(scope = this) val arguments = QueueingTask.Arguments( @@ -258,7 +255,7 @@ class TaskControllerTest : BaseIOTest() { } @Test - fun `queued task execution`() = runBlockingTest { + fun `queued task execution`() = runBlockingTest2(ignoreActive = true) { val instance = createInstance(scope = this) val arguments = QueueingTask.Arguments( @@ -309,7 +306,7 @@ class TaskControllerTest : BaseIOTest() { } @Test - fun `skippable tasks are skipped`() = runBlockingTest { + fun `skippable tasks are skipped`() = runBlockingTest2(ignoreActive = true) { val instance = createInstance(scope = this) val arguments = QueueingTask.Arguments( @@ -354,7 +351,7 @@ class TaskControllerTest : BaseIOTest() { } @Test - fun `tasks with preconditions that are not met are skipped`() = runBlockingTest { + fun `tasks with preconditions that are not met are skipped`() = runBlockingTest2(ignoreActive = true) { val instance = createInstance(scope = this) val request = DefaultTaskRequest(type = PreconditionTask::class) @@ -391,7 +388,7 @@ class TaskControllerTest : BaseIOTest() { } @Test - fun `collision behavior only affects task of same type`() = runBlockingTest { + fun `collision behavior only affects task of same type`() = runBlockingTest2(ignoreActive = true) { val arguments = QueueingTask.Arguments(path = File(testDir, UUID.randomUUID().toString())) arguments.path.exists() shouldBe false @@ -440,7 +437,7 @@ class TaskControllerTest : BaseIOTest() { } @Test - fun `resubmitting a request has no effect`() = runBlockingTest { + fun `resubmitting a request has no effect`() = runBlockingTest2(ignoreActive = true) { val instance = createInstance(scope = this) val arguments = QueueingTask.Arguments( @@ -472,7 +469,7 @@ class TaskControllerTest : BaseIOTest() { } @Test - fun `tasks are timed out according to their config`() = runBlockingTest { + fun `tasks are timed out according to their config`() = runBlockingTest2(ignoreActive = true) { val instance = createInstance(scope = this) val request = DefaultTaskRequest( @@ -497,7 +494,7 @@ class TaskControllerTest : BaseIOTest() { } @Test - fun `timeout starts on execution, not while pending`() = runBlockingTest { + fun `timeout starts on execution, not while pending`() = runBlockingTest2(ignoreActive = true) { val instance = createInstance(scope = this) val taskWithTimeout = DefaultTaskRequest( @@ -538,7 +535,7 @@ class TaskControllerTest : BaseIOTest() { } @Test - fun `parallel tasks can timeout`() = runBlockingTest { + fun `parallel tasks can timeout`() = runBlockingTest2(ignoreActive = true) { val instance = createInstance(scope = this) val task1WithTimeout = DefaultTaskRequest( @@ -591,7 +588,7 @@ class TaskControllerTest : BaseIOTest() { } @Test - fun `old tasks are pruned from history`() = runBlockingTest { + fun `old tasks are pruned from history`() = runBlockingTest2(ignoreActive = true) { val instance = createInstance(scope = this) val expectedFiles = mutableListOf<File>() @@ -631,7 +628,7 @@ class TaskControllerTest : BaseIOTest() { } @Test - fun `silent error handling`() = runBlockingTest { + fun `silent error handling`() = runBlockingTest2(ignoreActive = true) { val error: Throwable = spyk(Throwable()) @@ -643,7 +640,8 @@ class TaskControllerTest : BaseIOTest() { val instance = createInstance(scope = this) - val request = DefaultTaskRequest(type = SilentErrorTask::class, arguments = SilentErrorTask.Arguments(error = error)) + val request = + DefaultTaskRequest(type = SilentErrorTask::class, arguments = SilentErrorTask.Arguments(error = error)) instance.submit(request) val infoFinished = instance.tasks @@ -660,7 +658,7 @@ class TaskControllerTest : BaseIOTest() { } @Test - fun `alert error handling`() = runBlockingTest { + fun `alert error handling`() = runBlockingTest2(ignoreActive = true) { val error: Throwable = spyk(Throwable()) @@ -672,7 +670,8 @@ class TaskControllerTest : BaseIOTest() { val instance = createInstance(scope = this) - val request = DefaultTaskRequest(type = AlertErrorTask::class, arguments = AlertErrorTask.Arguments(error = error)) + val request = + DefaultTaskRequest(type = AlertErrorTask::class, arguments = AlertErrorTask.Arguments(error = error)) instance.submit(request) val infoFinished = instance.tasks diff --git a/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/task/testtasks/alerterror/AlertErrorTask.kt b/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/task/testtasks/alerterror/AlertErrorTask.kt index 05572d15905f6830542c4e80a6c5f82eefc788d9..6d9a5517362982f2753c7a9a3165572f14e7ec00 100644 --- a/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/task/testtasks/alerterror/AlertErrorTask.kt +++ b/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/task/testtasks/alerterror/AlertErrorTask.kt @@ -2,17 +2,18 @@ package de.rki.coronawarnapp.task.testtasks.alerterror import de.rki.coronawarnapp.task.Task import de.rki.coronawarnapp.task.TaskFactory +import de.rki.coronawarnapp.task.common.Finished +import de.rki.coronawarnapp.task.common.Started import de.rki.coronawarnapp.task.common.DefaultProgress -import kotlinx.coroutines.channels.ConflatedBroadcastChannel import kotlinx.coroutines.flow.Flow -import kotlinx.coroutines.flow.asFlow +import kotlinx.coroutines.flow.MutableStateFlow import timber.log.Timber import javax.inject.Provider class AlertErrorTask : Task<DefaultProgress, AlertErrorTask.Result> { - private val internalProgress = ConflatedBroadcastChannel<DefaultProgress>() - override val progress: Flow<DefaultProgress> = internalProgress.asFlow() + private val internalProgress = MutableStateFlow<DefaultProgress>(Started) + override val progress: Flow<DefaultProgress> = internalProgress private var isCanceled = false @@ -22,7 +23,7 @@ class AlertErrorTask : Task<DefaultProgress, AlertErrorTask.Result> { throw arguments.error } finally { Timber.i("Finished (isCanceled=$isCanceled).") - internalProgress.close() + internalProgress.value = Finished } override suspend fun cancel() { diff --git a/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/task/testtasks/precondition/PreconditionTask.kt b/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/task/testtasks/precondition/PreconditionTask.kt index f85bb257879f3808498f3fb69b0eac35cbd7bd09..a8b8c5f4b52842539af52702d9d520bd7b6828ff 100644 --- a/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/task/testtasks/precondition/PreconditionTask.kt +++ b/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/task/testtasks/precondition/PreconditionTask.kt @@ -2,18 +2,19 @@ package de.rki.coronawarnapp.task.testtasks.precondition import de.rki.coronawarnapp.task.Task import de.rki.coronawarnapp.task.TaskFactory +import de.rki.coronawarnapp.task.common.Finished +import de.rki.coronawarnapp.task.common.Started import de.rki.coronawarnapp.task.common.DefaultProgress -import kotlinx.coroutines.channels.ConflatedBroadcastChannel import kotlinx.coroutines.flow.Flow -import kotlinx.coroutines.flow.asFlow +import kotlinx.coroutines.flow.MutableStateFlow import org.joda.time.Duration import timber.log.Timber import javax.inject.Provider class PreconditionTask : Task<DefaultProgress, PreconditionTask.Result> { - private val internalProgress = ConflatedBroadcastChannel<DefaultProgress>() - override val progress: Flow<DefaultProgress> = internalProgress.asFlow() + private val internalProgress = MutableStateFlow<DefaultProgress>(Started) + override val progress: Flow<DefaultProgress> = internalProgress private var isCanceled = false @@ -23,7 +24,7 @@ class PreconditionTask : Task<DefaultProgress, PreconditionTask.Result> { Result() } finally { Timber.i("Finished (isCanceled=$isCanceled).") - internalProgress.close() + internalProgress.value = Finished } override suspend fun cancel() { diff --git a/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/task/testtasks/queue/QueueingTask.kt b/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/task/testtasks/queue/QueueingTask.kt index 0c7d67d9dab2f9243f9043d362741b39614948c2..bb491a02ccf7fe6bb65fca7a2f6821d687583a43 100644 --- a/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/task/testtasks/queue/QueueingTask.kt +++ b/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/task/testtasks/queue/QueueingTask.kt @@ -3,11 +3,13 @@ package de.rki.coronawarnapp.task.testtasks.queue import de.rki.coronawarnapp.task.Task import de.rki.coronawarnapp.task.TaskCancellationException import de.rki.coronawarnapp.task.TaskFactory +import de.rki.coronawarnapp.task.common.Finished +import de.rki.coronawarnapp.task.common.ProgressResult +import de.rki.coronawarnapp.task.common.Started import de.rki.coronawarnapp.task.common.DefaultProgress -import kotlinx.coroutines.channels.ConflatedBroadcastChannel import kotlinx.coroutines.delay import kotlinx.coroutines.flow.Flow -import kotlinx.coroutines.flow.asFlow +import kotlinx.coroutines.flow.MutableStateFlow import org.joda.time.Duration import timber.log.Timber import java.io.File @@ -17,8 +19,8 @@ import javax.inject.Provider open class QueueingTask @Inject constructor() : Task<DefaultProgress, QueueingTask.Result> { - private val internalProgress = ConflatedBroadcastChannel<DefaultProgress>() - override val progress: Flow<DefaultProgress> = internalProgress.asFlow() + private val internalProgress = MutableStateFlow<DefaultProgress>(Started) + override val progress: Flow<DefaultProgress> = internalProgress private var isCanceled = false @@ -29,7 +31,7 @@ open class QueueingTask @Inject constructor() : Task<DefaultProgress, QueueingTa } } finally { Timber.i("Finished (isCanceled=$isCanceled).") - internalProgress.close() + internalProgress.value = Finished } private suspend fun runSafely(arguments: Arguments): Result { @@ -40,7 +42,7 @@ open class QueueingTask @Inject constructor() : Task<DefaultProgress, QueueingTa arguments.path.appendText(it) Timber.v("Progress message: $it") - internalProgress.send(DefaultProgress(it)) + internalProgress.value = ProgressResult(it) delay(arguments.delay) } diff --git a/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/task/testtasks/silenterror/SilentErrorTask.kt b/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/task/testtasks/silenterror/SilentErrorTask.kt index 81d6dfc42ee1f5d74ad11ad86d3c899d5530eed9..ca995ef75e8db528cbd8086d833b9509d596e584 100644 --- a/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/task/testtasks/silenterror/SilentErrorTask.kt +++ b/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/task/testtasks/silenterror/SilentErrorTask.kt @@ -2,17 +2,18 @@ package de.rki.coronawarnapp.task.testtasks.silenterror import de.rki.coronawarnapp.task.Task import de.rki.coronawarnapp.task.TaskFactory +import de.rki.coronawarnapp.task.common.Finished +import de.rki.coronawarnapp.task.common.Started import de.rki.coronawarnapp.task.common.DefaultProgress -import kotlinx.coroutines.channels.ConflatedBroadcastChannel import kotlinx.coroutines.flow.Flow -import kotlinx.coroutines.flow.asFlow +import kotlinx.coroutines.flow.MutableStateFlow import timber.log.Timber import javax.inject.Provider class SilentErrorTask : Task<DefaultProgress, SilentErrorTask.Result> { - private val internalProgress = ConflatedBroadcastChannel<DefaultProgress>() - override val progress: Flow<DefaultProgress> = internalProgress.asFlow() + private val internalProgress = MutableStateFlow<DefaultProgress>(Started) + override val progress: Flow<DefaultProgress> = internalProgress private var isCanceled = false @@ -22,7 +23,7 @@ class SilentErrorTask : Task<DefaultProgress, SilentErrorTask.Result> { throw arguments.error } finally { Timber.i("Finished (isCanceled=$isCanceled).") - internalProgress.close() + internalProgress.value = Finished } override suspend fun cancel() { diff --git a/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/task/testtasks/timeout/BaseTimeoutTask.kt b/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/task/testtasks/timeout/BaseTimeoutTask.kt index bafa28a2cb134a3c02fe723dd90eb2b9139b1e49..af06ee295d85f500fe3a7e27682df2369dbe5b4e 100644 --- a/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/task/testtasks/timeout/BaseTimeoutTask.kt +++ b/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/task/testtasks/timeout/BaseTimeoutTask.kt @@ -3,18 +3,19 @@ package de.rki.coronawarnapp.task.testtasks.timeout import de.rki.coronawarnapp.task.Task import de.rki.coronawarnapp.task.TaskCancellationException import de.rki.coronawarnapp.task.TaskFactory +import de.rki.coronawarnapp.task.common.Finished +import de.rki.coronawarnapp.task.common.Started import de.rki.coronawarnapp.task.common.DefaultProgress -import kotlinx.coroutines.channels.ConflatedBroadcastChannel import kotlinx.coroutines.delay import kotlinx.coroutines.flow.Flow -import kotlinx.coroutines.flow.asFlow +import kotlinx.coroutines.flow.MutableStateFlow import timber.log.Timber import javax.inject.Provider abstract class BaseTimeoutTask : Task<DefaultProgress, TimeoutTaskResult> { - private val internalProgress = ConflatedBroadcastChannel<DefaultProgress>() - override val progress: Flow<DefaultProgress> = internalProgress.asFlow() + private val internalProgress = MutableStateFlow<DefaultProgress>(Started) + override val progress: Flow<DefaultProgress> = internalProgress private var isCanceled = false @@ -25,7 +26,7 @@ abstract class BaseTimeoutTask : Task<DefaultProgress, TimeoutTaskResult> { } } finally { Timber.i("Finished (isCanceled=$isCanceled).") - internalProgress.close() + internalProgress.value = Finished } private suspend fun runSafely(arguments: TimeoutTaskArguments): TimeoutTaskResult { diff --git a/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/vaccination/core/execution/task/VaccinationUpdateTaskTest.kt b/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/vaccination/core/execution/task/VaccinationUpdateTaskTest.kt index d1e7a0c15b92f14756e51e205f09478ba52bcb39..59c1af64093c344318739a48559cbbb27884342f 100644 --- a/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/vaccination/core/execution/task/VaccinationUpdateTaskTest.kt +++ b/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/vaccination/core/execution/task/VaccinationUpdateTaskTest.kt @@ -1,38 +1,29 @@ package de.rki.coronawarnapp.vaccination.core.execution.task -import de.rki.coronawarnapp.util.TimeStamper import de.rki.coronawarnapp.vaccination.core.repository.VaccinationRepository import io.mockk.MockKAnnotations import io.mockk.Runs import io.mockk.coEvery import io.mockk.coVerify -import io.mockk.every import io.mockk.impl.annotations.MockK import io.mockk.just import kotlinx.coroutines.test.runBlockingTest -import org.joda.time.Instant import org.junit.jupiter.api.BeforeEach import org.junit.jupiter.api.Test import testhelpers.BaseTest class VaccinationUpdateTaskTest : BaseTest() { - @MockK lateinit var timeStamper: TimeStamper @MockK lateinit var vaccinationRepository: VaccinationRepository - private val currentInstant = Instant.ofEpochSecond(1611764225) - @BeforeEach fun setUp() { MockKAnnotations.init(this) - every { timeStamper.nowUTC } returns currentInstant - coEvery { vaccinationRepository.refresh(any()) } just Runs } private fun createInstance() = VaccinationUpdateTask( - timeStamper = timeStamper, vaccinationRepository = vaccinationRepository )