diff --git a/Corona-Warn-App/src/androidTest/java/de/rki/coronawarnapp/ui/main/home/HomeFragmentTest.kt b/Corona-Warn-App/src/androidTest/java/de/rki/coronawarnapp/ui/main/home/HomeFragmentTest.kt index c2a342df7c6a458246ff5d99dd3aab976f7e4d61..2d009a5ea6dd88ee5cca081d470c594c7f5b83ef 100644 --- a/Corona-Warn-App/src/androidTest/java/de/rki/coronawarnapp/ui/main/home/HomeFragmentTest.kt +++ b/Corona-Warn-App/src/androidTest/java/de/rki/coronawarnapp/ui/main/home/HomeFragmentTest.kt @@ -10,7 +10,7 @@ import dagger.android.ContributesAndroidInjector import de.rki.coronawarnapp.R import de.rki.coronawarnapp.appconfig.AppConfigProvider import de.rki.coronawarnapp.main.CWASettings -import de.rki.coronawarnapp.notification.TestResultNotificationService +import de.rki.coronawarnapp.notification.ShareTestResultNotificationService import de.rki.coronawarnapp.storage.TracingRepository import de.rki.coronawarnapp.submission.SubmissionRepository import de.rki.coronawarnapp.submission.ui.homecards.SubmissionStateProvider @@ -58,7 +58,7 @@ class HomeFragmentTest : BaseUITest() { @MockK lateinit var tracingStateProviderFactory: TracingStateProvider.Factory @MockK lateinit var submissionStateProvider: SubmissionStateProvider @MockK lateinit var tracingRepository: TracingRepository - @MockK lateinit var testResultNotificationService: TestResultNotificationService + @MockK lateinit var shareTestResultNotificationService: ShareTestResultNotificationService @MockK lateinit var submissionRepository: SubmissionRepository @MockK lateinit var cwaSettings: CWASettings @MockK lateinit var appConfigProvider: AppConfigProvider @@ -249,7 +249,7 @@ class HomeFragmentTest : BaseUITest() { errorResetTool = errorResetTool, tracingRepository = tracingRepository, tracingStateProviderFactory = tracingStateProviderFactory, - testResultNotificationService = testResultNotificationService, + shareTestResultNotificationService = shareTestResultNotificationService, appConfigProvider = appConfigProvider, tracingStatus = tracingStatus, submissionRepository = submissionRepository, diff --git a/Corona-Warn-App/src/androidTest/java/de/rki/coronawarnapp/ui/submission/SubmissionTestResultConsentGivenFragmentTest.kt b/Corona-Warn-App/src/androidTest/java/de/rki/coronawarnapp/ui/submission/SubmissionTestResultConsentGivenFragmentTest.kt index 87c51b46a4bcef15ec7daa619bd1d9cc33ce825b..ea219bce3f7b7cab71254f6962f517a4fd8ef008 100644 --- a/Corona-Warn-App/src/androidTest/java/de/rki/coronawarnapp/ui/submission/SubmissionTestResultConsentGivenFragmentTest.kt +++ b/Corona-Warn-App/src/androidTest/java/de/rki/coronawarnapp/ui/submission/SubmissionTestResultConsentGivenFragmentTest.kt @@ -12,6 +12,7 @@ import androidx.test.ext.junit.runners.AndroidJUnit4 import dagger.Module import dagger.android.ContributesAndroidInjector import de.rki.coronawarnapp.R +import de.rki.coronawarnapp.notification.TestResultAvailableNotificationService import de.rki.coronawarnapp.submission.SubmissionRepository import de.rki.coronawarnapp.submission.auto.AutoSubmission import de.rki.coronawarnapp.ui.submission.testresult.TestResultUIState @@ -43,6 +44,7 @@ class SubmissionTestResultConsentGivenFragmentTest : BaseUITest() { @MockK lateinit var submissionRepository: SubmissionRepository @MockK lateinit var autoSubmission: AutoSubmission + @MockK lateinit var testResultAvailableNotificationService: TestResultAvailableNotificationService @Rule @JvmField @@ -61,6 +63,7 @@ class SubmissionTestResultConsentGivenFragmentTest : BaseUITest() { SubmissionTestResultConsentGivenViewModel( submissionRepository, autoSubmission, + testResultAvailableNotificationService, TestDispatcherProvider ) ) diff --git a/Corona-Warn-App/src/androidTest/java/de/rki/coronawarnapp/ui/submission/SubmissionTestResultFragmentTest.kt b/Corona-Warn-App/src/androidTest/java/de/rki/coronawarnapp/ui/submission/SubmissionTestResultFragmentTest.kt index fcffa178151600f2dd5505f24724b7386112d467..a26a8585fc21fb8700db7bb3ed3e0d1402db1552 100644 --- a/Corona-Warn-App/src/androidTest/java/de/rki/coronawarnapp/ui/submission/SubmissionTestResultFragmentTest.kt +++ b/Corona-Warn-App/src/androidTest/java/de/rki/coronawarnapp/ui/submission/SubmissionTestResultFragmentTest.kt @@ -10,7 +10,7 @@ import androidx.test.ext.junit.runners.AndroidJUnit4 import dagger.Module import dagger.android.ContributesAndroidInjector import de.rki.coronawarnapp.R -import de.rki.coronawarnapp.notification.TestResultNotificationService +import de.rki.coronawarnapp.notification.ShareTestResultNotificationService import de.rki.coronawarnapp.submission.SubmissionRepository import de.rki.coronawarnapp.ui.submission.testresult.TestResultUIState import de.rki.coronawarnapp.ui.submission.testresult.pending.SubmissionTestResultPendingFragment @@ -42,7 +42,7 @@ class SubmissionTestResultFragmentTest : BaseUITest() { lateinit var viewModel: SubmissionTestResultPendingViewModel @MockK lateinit var submissionRepository: SubmissionRepository - @MockK lateinit var testResultNotificationService: TestResultNotificationService + @MockK lateinit var shareTestResultNotificationService: ShareTestResultNotificationService @Rule @JvmField @@ -61,7 +61,7 @@ class SubmissionTestResultFragmentTest : BaseUITest() { viewModel = spyk( SubmissionTestResultPendingViewModel( TestDispatcherProvider, - testResultNotificationService, + shareTestResultNotificationService, submissionRepository ) ) diff --git a/Corona-Warn-App/src/androidTest/java/de/rki/coronawarnapp/ui/submission/SubmissionTestResultNegativeFragmentTest.kt b/Corona-Warn-App/src/androidTest/java/de/rki/coronawarnapp/ui/submission/SubmissionTestResultNegativeFragmentTest.kt index 8cee4e05bf24ac19e6d5a25131d8a477802812e2..a10ad9e78408bf348114b42a58aa5847bf6f717f 100644 --- a/Corona-Warn-App/src/androidTest/java/de/rki/coronawarnapp/ui/submission/SubmissionTestResultNegativeFragmentTest.kt +++ b/Corona-Warn-App/src/androidTest/java/de/rki/coronawarnapp/ui/submission/SubmissionTestResultNegativeFragmentTest.kt @@ -4,6 +4,7 @@ import androidx.lifecycle.MutableLiveData import androidx.test.ext.junit.runners.AndroidJUnit4 import dagger.Module import dagger.android.ContributesAndroidInjector +import de.rki.coronawarnapp.notification.TestResultAvailableNotificationService import de.rki.coronawarnapp.submission.SubmissionRepository import de.rki.coronawarnapp.ui.submission.testresult.TestResultUIState import de.rki.coronawarnapp.ui.submission.testresult.negative.SubmissionTestResultNegativeFragment @@ -33,6 +34,7 @@ class SubmissionTestResultNegativeFragmentTest : BaseUITest() { lateinit var viewModel: SubmissionTestResultNegativeViewModel @MockK lateinit var submissionRepository: SubmissionRepository + @MockK lateinit var testResultAvailableNotificationService: TestResultAvailableNotificationService @Rule @JvmField @@ -51,7 +53,8 @@ class SubmissionTestResultNegativeFragmentTest : BaseUITest() { viewModel = spyk( SubmissionTestResultNegativeViewModel( TestDispatcherProvider, - submissionRepository + submissionRepository, + testResultAvailableNotificationService ) ) diff --git a/Corona-Warn-App/src/androidTest/java/de/rki/coronawarnapp/ui/submission/SubmissionTestResultNoConsentGivenFragmentTest.kt b/Corona-Warn-App/src/androidTest/java/de/rki/coronawarnapp/ui/submission/SubmissionTestResultNoConsentGivenFragmentTest.kt index 7d975ac18a2e190e9882291c5479c0f9c809237d..6ca970ca1307b49bb8eb61480227d0b9f811ab74 100644 --- a/Corona-Warn-App/src/androidTest/java/de/rki/coronawarnapp/ui/submission/SubmissionTestResultNoConsentGivenFragmentTest.kt +++ b/Corona-Warn-App/src/androidTest/java/de/rki/coronawarnapp/ui/submission/SubmissionTestResultNoConsentGivenFragmentTest.kt @@ -4,6 +4,7 @@ import androidx.lifecycle.MutableLiveData import androidx.test.ext.junit.runners.AndroidJUnit4 import dagger.Module import dagger.android.ContributesAndroidInjector +import de.rki.coronawarnapp.notification.TestResultAvailableNotificationService import de.rki.coronawarnapp.submission.SubmissionRepository import de.rki.coronawarnapp.ui.submission.testresult.TestResultUIState import de.rki.coronawarnapp.ui.submission.testresult.positive.SubmissionTestResultNoConsentFragment @@ -30,6 +31,7 @@ import java.util.Date class SubmissionTestResultNoConsentGivenFragmentTest : BaseUITest() { @MockK lateinit var submissionRepository: SubmissionRepository + @MockK lateinit var testResultAvailableNotificationService: TestResultAvailableNotificationService @Rule @JvmField @@ -44,7 +46,7 @@ class SubmissionTestResultNoConsentGivenFragmentTest : BaseUITest() { fun setup() { MockKAnnotations.init(this, relaxed = true) viewModel = - spyk(SubmissionTestResultNoConsentViewModel(submissionRepository)) + spyk(SubmissionTestResultNoConsentViewModel(submissionRepository, testResultAvailableNotificationService)) setupMockViewModel(object : SubmissionTestResultNoConsentViewModel.Factory { override fun create(): SubmissionTestResultNoConsentViewModel = viewModel }) diff --git a/Corona-Warn-App/src/androidTest/java/de/rki/coronawarnapp/worker/DiagnosisTestResultRetrievalPeriodicWorkerTest.kt b/Corona-Warn-App/src/androidTest/java/de/rki/coronawarnapp/worker/DiagnosisTestResultRetrievalPeriodicWorkerTest.kt index 5544f81e8ad0f0f95844f51ac2a9a993b8dac052..a03e1e2d6b85de6e16abffe7cd3cfe48770dc9e4 100644 --- a/Corona-Warn-App/src/androidTest/java/de/rki/coronawarnapp/worker/DiagnosisTestResultRetrievalPeriodicWorkerTest.kt +++ b/Corona-Warn-App/src/androidTest/java/de/rki/coronawarnapp/worker/DiagnosisTestResultRetrievalPeriodicWorkerTest.kt @@ -45,7 +45,7 @@ class DiagnosisTestResultRetrievalPeriodicWorkerTest { @Before fun setUp() { LocalData.registrationToken("test token") - LocalData.isTestResultNotificationSent(false) + LocalData.isTestResultAvailableNotificationSent(false) mockkObject(LocalData) mockkObject(BackgroundWorkScheduler) @@ -179,12 +179,12 @@ class DiagnosisTestResultRetrievalPeriodicWorkerTest { val workInfo = workManager.getWorkInfoById(request.id).get() if (isCancelTest) { assertThat(workInfo.state, `is`((WorkInfo.State.CANCELLED))) - assertThat(LocalData.isTestResultNotificationSent(), `is`(false)) + assertThat(LocalData.isTestResultAvailableNotificationSent(), `is`(false)) } else { when (result) { TestResult.POSITIVE, TestResult.NEGATIVE, TestResult.INVALID -> { assertThat(workInfo.state, `is`((WorkInfo.State.CANCELLED))) - assertThat(LocalData.isTestResultNotificationSent(), `is`(true)) + assertThat(LocalData.isTestResultAvailableNotificationSent(), `is`(true)) } TestResult.PENDING -> { assertThat(workInfo.runAttemptCount, `is`(0)) diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/exception/CwaSecurityException.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/exception/CwaSecurityException.kt index 80305a5f1cf1cbb1aa4e3a234ab7f447bd206318..40a222d074a4bc3abc253df90badf8d478d5b6f6 100644 --- a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/exception/CwaSecurityException.kt +++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/exception/CwaSecurityException.kt @@ -6,6 +6,6 @@ import de.rki.coronawarnapp.exception.reporting.ReportedException class CwaSecurityException(cause: Throwable) : ReportedException( ErrorCodes.CWA_SECURITY_PROBLEM.code, "Something went wrong during a critical part of the application ensuring security, please refer" + - " to the details for more information", + " to the details for more information", cause ) diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/notification/NotificationConstants.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/notification/NotificationConstants.kt index f67e446dfabfe9091e517089e5b8a824ab8e536d..0b7f77325a683ae696fae6e7a1cab5248df17dea 100644 --- a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/notification/NotificationConstants.kt +++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/notification/NotificationConstants.kt @@ -18,7 +18,6 @@ object NotificationConstants { const val DEADMAN_NOTIFICATION_ID: NotificationId = 3 const val NEW_MESSAGE_RISK_LEVEL_SCORE_NOTIFICATION_ID: NotificationId = 110 - const val NEW_MESSAGE_TEST_RESULT_NOTIFICATION_ID: NotificationId = 120 const val TEST_RESULT_AVAILABLE_NOTIFICATION_ID: NotificationId = 130 const val INCORRECT_DEVICE_TIME_NOTIFICATION_ID: NotificationId = 140 } diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/notification/NotificationReceiver.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/notification/NotificationReceiver.kt index 3d2b6970a8a7eb31de6f3258fd17f4088eb538a8..ea0021a012cb782da316a10a98716e48d98512ce 100644 --- a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/notification/NotificationReceiver.kt +++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/notification/NotificationReceiver.kt @@ -13,14 +13,14 @@ typealias NotificationId = Int class NotificationReceiver : BroadcastReceiver() { - @Inject lateinit var testResultNotificationService: TestResultNotificationService + @Inject lateinit var shareTestResultNotificationService: ShareTestResultNotificationService override fun onReceive(context: Context, intent: Intent) { AndroidInjection.inject(this, context) when (val notificationId = intent.getIntExtra(NOTIFICATION_ID, Int.MIN_VALUE)) { POSITIVE_RESULT_NOTIFICATION_ID -> { Timber.tag(TAG).v("NotificationReceiver received intent to show a positive test result notification") - testResultNotificationService.showPositiveTestResultNotification(notificationId) + shareTestResultNotificationService.showSharePositiveTestResultNotification(notificationId) } else -> Timber.tag(TAG).d("NotificationReceiver received an undefined notificationId: %s", notificationId) diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/notification/TestResultNotificationService.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/notification/ShareTestResultNotificationService.kt similarity index 75% rename from Corona-Warn-App/src/main/java/de/rki/coronawarnapp/notification/TestResultNotificationService.kt rename to Corona-Warn-App/src/main/java/de/rki/coronawarnapp/notification/ShareTestResultNotificationService.kt index 4bffacf4c39a1d080cb2dacbd9cb050331322af8..f18af548a82fda119acb5f6380691e98e73c6d72 100644 --- a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/notification/TestResultNotificationService.kt +++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/notification/ShareTestResultNotificationService.kt @@ -14,16 +14,16 @@ import de.rki.coronawarnapp.util.di.AppContext import timber.log.Timber import javax.inject.Inject -class TestResultNotificationService @Inject constructor( +class ShareTestResultNotificationService @Inject constructor( @AppContext private val context: Context, private val timeStamper: TimeStamper, private val notificationHelper: NotificationHelper ) { - fun schedulePositiveTestResultReminder() { - if (LocalData.numberOfRemainingPositiveTestResultReminders < 0) { + fun scheduleSharePositiveTestResultReminder() { + if (LocalData.numberOfRemainingSharePositiveTestResultReminders < 0) { Timber.v("Schedule positive test result notification") - LocalData.numberOfRemainingPositiveTestResultReminders = POSITIVE_RESULT_NOTIFICATION_TOTAL_COUNT + LocalData.numberOfRemainingSharePositiveTestResultReminders = POSITIVE_RESULT_NOTIFICATION_TOTAL_COUNT notificationHelper.scheduleRepeatingNotification( timeStamper.nowUTC.plus(POSITIVE_RESULT_NOTIFICATION_INITIAL_OFFSET), POSITIVE_RESULT_NOTIFICATION_INTERVAL, @@ -34,9 +34,9 @@ class TestResultNotificationService @Inject constructor( } } - fun showPositiveTestResultNotification(notificationId: Int) { - if (LocalData.numberOfRemainingPositiveTestResultReminders > 0) { - LocalData.numberOfRemainingPositiveTestResultReminders -= 1 + fun showSharePositiveTestResultNotification(notificationId: Int) { + if (LocalData.numberOfRemainingSharePositiveTestResultReminders > 0) { + LocalData.numberOfRemainingSharePositiveTestResultReminders -= 1 val pendingIntent = NavDeepLinkBuilder(context) .setGraph(R.navigation.nav_graph) .setComponentName(MainActivity::class.java) @@ -54,14 +54,14 @@ class TestResultNotificationService @Inject constructor( } } - fun cancelPositiveTestResultNotification() { + fun cancelSharePositiveTestResultNotification() { notificationHelper.cancelFutureNotifications(POSITIVE_RESULT_NOTIFICATION_ID) Timber.v("Future positive test result notifications have been canceled") } - fun resetPositiveTestResultNotification() { - cancelPositiveTestResultNotification() - LocalData.numberOfRemainingPositiveTestResultReminders = Int.MIN_VALUE + fun resetSharePositiveTestResultNotification() { + cancelSharePositiveTestResultNotification() + LocalData.numberOfRemainingSharePositiveTestResultReminders = Int.MIN_VALUE Timber.v("Positive test result notification counter has been reset") } } diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/notification/TestResultAvailableNotification.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/notification/TestResultAvailableNotificationService.kt similarity index 91% rename from Corona-Warn-App/src/main/java/de/rki/coronawarnapp/notification/TestResultAvailableNotification.kt rename to Corona-Warn-App/src/main/java/de/rki/coronawarnapp/notification/TestResultAvailableNotificationService.kt index 80cdfa7569c5c609e065ab47685e582a5607a4a3..bc97a7ba3bfc35b29e4f2e814053c795ca7f81eb 100644 --- a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/notification/TestResultAvailableNotification.kt +++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/notification/TestResultAvailableNotificationService.kt @@ -11,14 +11,14 @@ import kotlinx.coroutines.flow.first import javax.inject.Inject import javax.inject.Provider -class TestResultAvailableNotification @Inject constructor( +class TestResultAvailableNotificationService @Inject constructor( @AppContext private val context: Context, private val foregroundState: ForegroundState, private val navDeepLinkBuilderProvider: Provider<NavDeepLinkBuilder>, private val notificationHelper: NotificationHelper ) { - suspend fun showTestResultNotification(testResult: TestResult) { + suspend fun showTestResultAvailableNotification(testResult: TestResult) { if (foregroundState.isInForeground.first()) return val pendingIntent = navDeepLinkBuilderProvider.get().apply { @@ -35,7 +35,7 @@ class TestResultAvailableNotification @Inject constructor( ) } - fun cancelTestResultNotification() { + fun cancelTestResultAvailableNotification() { notificationHelper.cancelCurrentNotification(NotificationConstants.TEST_RESULT_AVAILABLE_NOTIFICATION_ID) } diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/storage/LocalData.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/storage/LocalData.kt index c129cbe1e1e3f04f55871a729b111ab677444521..b22bf0f54c88e09130bd24ee19c2d84bdba25f3a 100644 --- a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/storage/LocalData.kt +++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/storage/LocalData.kt @@ -17,8 +17,6 @@ import timber.log.Timber */ object LocalData { - private val TAG: String? = LocalData::class.simpleName - private const val PREFERENCE_INTEROPERABILITY_IS_USED_AT_LEAST_ONCE = "preference_interoperability_is_used_at_least_once" @@ -235,7 +233,7 @@ object LocalData { * * @return boolean */ - fun isTestResultNotificationSent(): Boolean { + fun isTestResultAvailableNotificationSent(): Boolean { return getSharedPreferenceInstance().getBoolean( CoronaWarnApplication.getAppContext() .getString(R.string.preference_test_result_notification), @@ -249,7 +247,7 @@ object LocalData { * * @param value boolean */ - fun isTestResultNotificationSent(value: Boolean) = + fun isTestResultAvailableNotificationSent(value: Boolean) = getSharedPreferenceInstance().edit(true) { putBoolean( CoronaWarnApplication.getAppContext() @@ -338,7 +336,7 @@ object LocalData { } private const val PKEY_POSITIVE_TEST_RESULT_REMINDER_COUNT = "preference_positive_test_result_reminder_count" - var numberOfRemainingPositiveTestResultReminders: Int + var numberOfRemainingSharePositiveTestResultReminders: Int get() = getSharedPreferenceInstance().getInt(PKEY_POSITIVE_TEST_RESULT_REMINDER_COUNT, Int.MIN_VALUE) set(value) = getSharedPreferenceInstance().edit(true) { putInt(PKEY_POSITIVE_TEST_RESULT_REMINDER_COUNT, value) @@ -354,18 +352,6 @@ object LocalData { false ) - /** - * Toggles the decision if background jobs are enabled - * - */ - fun toggleBackgroundJobEnabled() = getSharedPreferenceInstance().edit(true) { - putBoolean( - CoronaWarnApplication.getAppContext() - .getString(R.string.preference_background_job_allowed), - !isBackgroundJobEnabled() - ) - } - /** * Gets the boolean if the user has mobile data enabled * @@ -376,18 +362,6 @@ object LocalData { false ) - /** - * Toggles the boolean if the user has mobile data enabled - * - */ - fun toggleMobileDataEnabled() = getSharedPreferenceInstance().edit(true) { - putBoolean( - CoronaWarnApplication.getAppContext() - .getString(R.string.preference_mobile_data_allowed), - !isMobileDataEnabled() - ) - } - /**************************************************** * SUBMISSION DATA ****************************************************/ @@ -516,6 +490,7 @@ object LocalData { } fun clear() { + // If you make use of a FlowPreference, you need to manually clear it here Timber.w("LocalData.clear()") } } diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/submission/SubmissionRepository.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/submission/SubmissionRepository.kt index 31230866a800a1d551dc06f1bcc42719cedcc688..faf48fe87616a866f9bc0d9c41107ac810dee267 100644 --- a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/submission/SubmissionRepository.kt +++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/submission/SubmissionRepository.kt @@ -164,6 +164,9 @@ class SubmissionRepository @Inject constructor( } } + suspend fun asyncRequestTestResult(registrationToken: String): TestResult = + submissionService.asyncRequestTestResult(registrationToken) + private suspend fun fetchTestResult(registrationToken: String): DeviceUIState = try { val testResult = submissionService.asyncRequestTestResult(registrationToken) updateTestResult(testResult) @@ -181,7 +184,7 @@ class SubmissionRepository @Inject constructor( LocalData.initialPollingForTestResultTimeStamp(0L) LocalData.initialTestResultReceivedTimestamp(0L) LocalData.isAllowedToSubmitDiagnosisKeys(false) - LocalData.isTestResultNotificationSent(false) + LocalData.isTestResultAvailableNotificationSent(false) } private fun deriveUiState(testResult: TestResult?): DeviceUIState = when (testResult) { 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 645d931705e03c7a31ce17aa3a6e35a5b80371aa..d15bfac4ba67cd13dd6cc7ebe40ca7d6c306f021 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 @@ -3,8 +3,8 @@ package de.rki.coronawarnapp.submission.task import com.google.android.gms.nearby.exposurenotification.TemporaryExposureKey import de.rki.coronawarnapp.appconfig.AppConfigProvider import de.rki.coronawarnapp.exception.NoRegistrationTokenSetException -import de.rki.coronawarnapp.notification.TestResultAvailableNotification -import de.rki.coronawarnapp.notification.TestResultNotificationService +import de.rki.coronawarnapp.notification.ShareTestResultNotificationService +import de.rki.coronawarnapp.notification.TestResultAvailableNotificationService import de.rki.coronawarnapp.playbook.Playbook import de.rki.coronawarnapp.storage.LocalData import de.rki.coronawarnapp.submission.SubmissionSettings @@ -34,8 +34,8 @@ class SubmissionTask @Inject constructor( private val submissionSettings: SubmissionSettings, private val autoSubmission: AutoSubmission, private val timeStamper: TimeStamper, - private val testResultNotificationService: TestResultNotificationService, - private val testResultAvailableNotification: TestResultAvailableNotification + private val shareTestResultNotificationService: ShareTestResultNotificationService, + private val testResultAvailableNotificationService: TestResultAvailableNotificationService ) : Task<DefaultProgress, SubmissionTask.Result> { private val internalProgress = ConflatedBroadcastChannel<DefaultProgress>() @@ -155,8 +155,8 @@ class SubmissionTask @Inject constructor( BackgroundWorkScheduler.stopWorkScheduler() LocalData.numberOfSuccessfulSubmissions(1) - testResultNotificationService.cancelPositiveTestResultNotification() - testResultAvailableNotification.cancelTestResultNotification() + shareTestResultNotificationService.cancelSharePositiveTestResultNotification() + testResultAvailableNotificationService.cancelTestResultAvailableNotification() } data class Arguments( diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/main/home/HomeFragmentViewModel.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/main/home/HomeFragmentViewModel.kt index a279229c686d324a967d52e425b08b57024f3cfd..ae1e6dead791e1c565e51782f3976f9fa97c66c6 100644 --- a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/main/home/HomeFragmentViewModel.kt +++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/main/home/HomeFragmentViewModel.kt @@ -6,7 +6,7 @@ import androidx.navigation.NavDirections import com.squareup.inject.assisted.AssistedInject import de.rki.coronawarnapp.appconfig.AppConfigProvider import de.rki.coronawarnapp.main.CWASettings -import de.rki.coronawarnapp.notification.TestResultNotificationService +import de.rki.coronawarnapp.notification.ShareTestResultNotificationService import de.rki.coronawarnapp.risk.TimeVariables import de.rki.coronawarnapp.storage.LocalData import de.rki.coronawarnapp.storage.TracingRepository @@ -71,7 +71,7 @@ class HomeFragmentViewModel @AssistedInject constructor( tracingStateProviderFactory: TracingStateProvider.Factory, submissionStateProvider: SubmissionStateProvider, private val tracingRepository: TracingRepository, - private val testResultNotificationService: TestResultNotificationService, + private val shareTestResultNotificationService: ShareTestResultNotificationService, private val submissionRepository: SubmissionRepository, private val cwaSettings: CWASettings, appConfigProvider: AppConfigProvider @@ -241,7 +241,7 @@ class HomeFragmentViewModel @AssistedInject constructor( } } } - .also { testResultNotificationService.schedulePositiveTestResultReminder() } + .also { shareTestResultNotificationService.scheduleSharePositiveTestResultReminder() } } // TODO only lazy to keep tests going which would break because of LocalData access diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/settings/SettingsResetViewModel.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/settings/SettingsResetViewModel.kt index d7b3622c569b77d0d7f3f833e09d9d2def173481..ef39ecc6f523788403e31783b56b78c8f8dfc04f 100644 --- a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/settings/SettingsResetViewModel.kt +++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/settings/SettingsResetViewModel.kt @@ -5,7 +5,7 @@ import com.squareup.inject.assisted.AssistedInject import de.rki.coronawarnapp.exception.ExceptionCategory import de.rki.coronawarnapp.exception.reporting.report import de.rki.coronawarnapp.nearby.InternalExposureNotificationClient -import de.rki.coronawarnapp.notification.TestResultNotificationService +import de.rki.coronawarnapp.notification.ShareTestResultNotificationService import de.rki.coronawarnapp.submission.SubmissionRepository import de.rki.coronawarnapp.ui.SingleLiveEvent import de.rki.coronawarnapp.util.DataReset @@ -17,7 +17,7 @@ import de.rki.coronawarnapp.worker.BackgroundWorkScheduler class SettingsResetViewModel @AssistedInject constructor( dispatcherProvider: DispatcherProvider, private val dataReset: DataReset, - private val testResultNotificationService: TestResultNotificationService, + private val shareTestResultNotificationService: ShareTestResultNotificationService, private val submissionRepository: SubmissionRepository ) : CWAViewModel(dispatcherProvider = dispatcherProvider) { @@ -45,7 +45,7 @@ class SettingsResetViewModel @AssistedInject constructor( ExceptionCategory.EXPOSURENOTIFICATION, TAG, null ) } - testResultNotificationService.resetPositiveTestResultNotification() + shareTestResultNotificationService.resetSharePositiveTestResultNotification() dataReset.clearAllLocalData() clickEvent.postValue(SettingsEvents.GoToOnboarding) diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/submission/testresult/invalid/SubmissionTestResultInvalidFragment.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/submission/testresult/invalid/SubmissionTestResultInvalidFragment.kt index daff644571e0c726d680deda285ca807fa7eaed2..e4fcde50e12fc1d1c91af144a7f58ba3306fbe09 100644 --- a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/submission/testresult/invalid/SubmissionTestResultInvalidFragment.kt +++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/submission/testresult/invalid/SubmissionTestResultInvalidFragment.kt @@ -21,7 +21,7 @@ import javax.inject.Inject class SubmissionTestResultInvalidFragment : Fragment(R.layout.fragment_submission_test_result_invalid), AutoInject { @Inject lateinit var viewModelFactory: CWAViewModelFactoryProvider.Factory - private val vm: SubmissionTestResultInvalidViewModel by cwaViewModels { viewModelFactory } + private val viewModel: SubmissionTestResultInvalidViewModel by cwaViewModels { viewModelFactory } private val binding: FragmentSubmissionTestResultInvalidBinding by viewBindingLazy() @@ -33,11 +33,11 @@ class SubmissionTestResultInvalidFragment : Fragment(R.layout.fragment_submissio submissionTestResultHeader.headerButtonBack.buttonIcon.setOnClickListener { popBackStack() } } - vm.testResult.observe2(this) { + viewModel.testResult.observe2(this) { binding.submissionTestResultSection.setTestResultSection(it.deviceUiState, it.testResultReceivedDate) } - vm.routeToScreen.observe2(this) { navDirections -> + viewModel.routeToScreen.observe2(this) { navDirections -> navDirections?.let { doNavigate(it) } ?: popBackStack() } } @@ -45,6 +45,7 @@ class SubmissionTestResultInvalidFragment : Fragment(R.layout.fragment_submissio override fun onResume() { super.onResume() binding.submissionTestResultContainer.sendAccessibilityEvent(AccessibilityEvent.TYPE_ANNOUNCEMENT) + viewModel.onTestOpened() } private fun removeTestAfterConfirmation() { @@ -55,7 +56,7 @@ class SubmissionTestResultInvalidFragment : Fragment(R.layout.fragment_submissio R.string.submission_test_result_dialog_remove_test_button_positive, R.string.submission_test_result_dialog_remove_test_button_negative, positiveButtonFunction = { - vm.deregisterTestFromDevice() + viewModel.deregisterTestFromDevice() } ) DialogHelper.showDialog(removeTestDialog).apply { diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/submission/testresult/invalid/SubmissionTestResultInvalidViewModel.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/submission/testresult/invalid/SubmissionTestResultInvalidViewModel.kt index cea45a1c5b8c81fb79d87fa29d16848a04ee3ae6..ced591754ee8dcbb557a25d7a362551ceb1ef91d 100644 --- a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/submission/testresult/invalid/SubmissionTestResultInvalidViewModel.kt +++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/submission/testresult/invalid/SubmissionTestResultInvalidViewModel.kt @@ -4,6 +4,7 @@ import androidx.lifecycle.LiveData import androidx.lifecycle.asLiveData import androidx.navigation.NavDirections import com.squareup.inject.assisted.AssistedInject +import de.rki.coronawarnapp.notification.TestResultAvailableNotificationService import de.rki.coronawarnapp.submission.SubmissionRepository import de.rki.coronawarnapp.ui.submission.testresult.TestResultUIState import de.rki.coronawarnapp.util.coroutine.DispatcherProvider @@ -15,7 +16,8 @@ import timber.log.Timber class SubmissionTestResultInvalidViewModel @AssistedInject constructor( dispatcherProvider: DispatcherProvider, - private val submissionRepository: SubmissionRepository + private val submissionRepository: SubmissionRepository, + private val testResultAvailableNotificationService: TestResultAvailableNotificationService ) : CWAViewModel(dispatcherProvider = dispatcherProvider) { val routeToScreen = SingleLiveEvent<NavDirections?>() @@ -39,6 +41,11 @@ class SubmissionTestResultInvalidViewModel @AssistedInject constructor( } } + fun onTestOpened() { + submissionRepository.setViewedTestResult() + testResultAvailableNotificationService.cancelTestResultAvailableNotification() + } + @AssistedInject.Factory interface Factory : SimpleCWAViewModelFactory<SubmissionTestResultInvalidViewModel> } diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/submission/testresult/negative/SubmissionTestResultNegativeFragment.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/submission/testresult/negative/SubmissionTestResultNegativeFragment.kt index 8bcec718620fd35770d91251e7f46f8f156eccda..609cec522f708fd4171355299dcb72fce81670b3 100644 --- a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/submission/testresult/negative/SubmissionTestResultNegativeFragment.kt +++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/submission/testresult/negative/SubmissionTestResultNegativeFragment.kt @@ -21,7 +21,7 @@ import javax.inject.Inject class SubmissionTestResultNegativeFragment : Fragment(R.layout.fragment_submission_test_result_negative), AutoInject { @Inject lateinit var viewModelFactory: CWAViewModelFactoryProvider.Factory - private val vm: SubmissionTestResultNegativeViewModel by cwaViewModels { viewModelFactory } + private val viewModel: SubmissionTestResultNegativeViewModel by cwaViewModels { viewModelFactory } private val binding: FragmentSubmissionTestResultNegativeBinding by viewBindingLazy() @@ -33,11 +33,11 @@ class SubmissionTestResultNegativeFragment : Fragment(R.layout.fragment_submissi submissionTestResultHeader.headerButtonBack.buttonIcon.setOnClickListener { popBackStack() } } - vm.testResult.observe2(this) { + viewModel.testResult.observe2(this) { binding.submissionTestResultSection.setTestResultSection(it.deviceUiState, it.testResultReceivedDate) } - vm.routeToScreen.observe2(this) { navDirections -> + viewModel.routeToScreen.observe2(this) { navDirections -> navDirections?.let { doNavigate(it) } ?: popBackStack() } } @@ -45,6 +45,7 @@ class SubmissionTestResultNegativeFragment : Fragment(R.layout.fragment_submissi override fun onResume() { super.onResume() binding.submissionTestResultContainer.sendAccessibilityEvent(AccessibilityEvent.TYPE_ANNOUNCEMENT) + viewModel.onTestOpened() } private fun removeTestAfterConfirmation() { @@ -55,7 +56,7 @@ class SubmissionTestResultNegativeFragment : Fragment(R.layout.fragment_submissi R.string.submission_test_result_dialog_remove_test_button_positive, R.string.submission_test_result_dialog_remove_test_button_negative, positiveButtonFunction = { - vm.deregisterTestFromDevice() + viewModel.deregisterTestFromDevice() } ) DialogHelper.showDialog(removeTestDialog).apply { diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/submission/testresult/negative/SubmissionTestResultNegativeViewModel.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/submission/testresult/negative/SubmissionTestResultNegativeViewModel.kt index 59ce8eb6ebe99856343346b881c84f45bed35437..f5bf911c7ad2feb93912cf8734bd2ea015c359a5 100644 --- a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/submission/testresult/negative/SubmissionTestResultNegativeViewModel.kt +++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/submission/testresult/negative/SubmissionTestResultNegativeViewModel.kt @@ -4,6 +4,7 @@ import androidx.lifecycle.LiveData import androidx.lifecycle.asLiveData import androidx.navigation.NavDirections import com.squareup.inject.assisted.AssistedInject +import de.rki.coronawarnapp.notification.TestResultAvailableNotificationService import de.rki.coronawarnapp.submission.SubmissionRepository import de.rki.coronawarnapp.ui.submission.testresult.TestResultUIState import de.rki.coronawarnapp.util.coroutine.DispatcherProvider @@ -15,7 +16,8 @@ import timber.log.Timber class SubmissionTestResultNegativeViewModel @AssistedInject constructor( dispatcherProvider: DispatcherProvider, - private val submissionRepository: SubmissionRepository + private val submissionRepository: SubmissionRepository, + private val testResultAvailableNotificationService: TestResultAvailableNotificationService ) : CWAViewModel(dispatcherProvider = dispatcherProvider) { val routeToScreen = SingleLiveEvent<NavDirections?>() @@ -38,6 +40,11 @@ class SubmissionTestResultNegativeViewModel @AssistedInject constructor( } } + fun onTestOpened() { + submissionRepository.setViewedTestResult() + testResultAvailableNotificationService.cancelTestResultAvailableNotification() + } + @AssistedInject.Factory interface Factory : SimpleCWAViewModelFactory<SubmissionTestResultNegativeViewModel> diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/submission/testresult/pending/SubmissionTestResultPendingViewModel.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/submission/testresult/pending/SubmissionTestResultPendingViewModel.kt index b77a82130c1a636d56fb819b735a7a8113b5f8df..c9ae92042ced5a132dca245e7531d36efee0e9ba 100644 --- a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/submission/testresult/pending/SubmissionTestResultPendingViewModel.kt +++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/submission/testresult/pending/SubmissionTestResultPendingViewModel.kt @@ -1,10 +1,11 @@ package de.rki.coronawarnapp.ui.submission.testresult.pending +import androidx.lifecycle.LiveData import androidx.lifecycle.asLiveData import androidx.navigation.NavDirections import com.squareup.inject.assisted.AssistedInject import de.rki.coronawarnapp.exception.http.CwaWebException -import de.rki.coronawarnapp.notification.TestResultNotificationService +import de.rki.coronawarnapp.notification.ShareTestResultNotificationService import de.rki.coronawarnapp.submission.SubmissionRepository import de.rki.coronawarnapp.ui.submission.testresult.TestResultUIState import de.rki.coronawarnapp.util.DeviceUIState @@ -26,7 +27,7 @@ import timber.log.Timber class SubmissionTestResultPendingViewModel @AssistedInject constructor( dispatcherProvider: DispatcherProvider, - private val testResultNotificationService: TestResultNotificationService, + private val shareTestResultNotificationService: ShareTestResultNotificationService, private val submissionRepository: SubmissionRepository ) : CWAViewModel(dispatcherProvider = dispatcherProvider) { @@ -59,8 +60,7 @@ class SubmissionTestResultPendingViewModel @AssistedInject constructor( testResultReceivedDate = resultDate ) } - - val testState = testResultFlow + val testState: LiveData<TestResultUIState> = testResultFlow .onEach { testResultUIState -> testResultUIState.deviceUiState.withSuccess { deviceState -> when (deviceState) { @@ -100,7 +100,7 @@ class SubmissionTestResultPendingViewModel @AssistedInject constructor( it == DeviceUIState.PAIRED_POSITIVE || it == DeviceUIState.PAIRED_POSITIVE_TELETAN } } - .also { testResultNotificationService.schedulePositiveTestResultReminder() } + .also { shareTestResultNotificationService.scheduleSharePositiveTestResultReminder() } } fun deregisterTestFromDevice() { diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/submission/testresult/positive/SubmissionTestResultConsentGivenViewModel.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/submission/testresult/positive/SubmissionTestResultConsentGivenViewModel.kt index 723f7a0cda2580de46f0aaecf29b0bef987bb1ca..91e793734790043565ec87e14f43992153e4506a 100644 --- a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/submission/testresult/positive/SubmissionTestResultConsentGivenViewModel.kt +++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/submission/testresult/positive/SubmissionTestResultConsentGivenViewModel.kt @@ -3,6 +3,7 @@ package de.rki.coronawarnapp.ui.submission.testresult.positive import androidx.lifecycle.LiveData import androidx.lifecycle.asLiveData import com.squareup.inject.assisted.AssistedInject +import de.rki.coronawarnapp.notification.TestResultAvailableNotificationService import de.rki.coronawarnapp.submission.SubmissionRepository import de.rki.coronawarnapp.submission.auto.AutoSubmission import de.rki.coronawarnapp.ui.submission.testresult.TestResultUIState @@ -18,6 +19,7 @@ import timber.log.Timber class SubmissionTestResultConsentGivenViewModel @AssistedInject constructor( private val submissionRepository: SubmissionRepository, private val autoSubmission: AutoSubmission, + private val testResultAvailableNotificationService: TestResultAvailableNotificationService, dispatcherProvider: DispatcherProvider ) : CWAViewModel(dispatcherProvider = dispatcherProvider) { @@ -40,6 +42,7 @@ class SubmissionTestResultConsentGivenViewModel @AssistedInject constructor( fun onTestOpened() { submissionRepository.setViewedTestResult() + testResultAvailableNotificationService.cancelTestResultAvailableNotification() } fun onContinuePressed() { diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/submission/testresult/positive/SubmissionTestResultNoConsentViewModel.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/submission/testresult/positive/SubmissionTestResultNoConsentViewModel.kt index 33b1aaa7f02df217740a9a7d64addfbb407bafbe..104c11d68c3105032c479762567073e41afc1ddd 100644 --- a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/submission/testresult/positive/SubmissionTestResultNoConsentViewModel.kt +++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/submission/testresult/positive/SubmissionTestResultNoConsentViewModel.kt @@ -3,6 +3,7 @@ package de.rki.coronawarnapp.ui.submission.testresult.positive import androidx.lifecycle.LiveData import androidx.lifecycle.asLiveData import com.squareup.inject.assisted.AssistedInject +import de.rki.coronawarnapp.notification.TestResultAvailableNotificationService import de.rki.coronawarnapp.submission.SubmissionRepository import de.rki.coronawarnapp.ui.submission.testresult.TestResultUIState import de.rki.coronawarnapp.util.flow.combine @@ -11,7 +12,8 @@ import de.rki.coronawarnapp.util.viewmodel.SimpleCWAViewModelFactory import kotlinx.coroutines.Dispatchers class SubmissionTestResultNoConsentViewModel @AssistedInject constructor( - val submissionRepository: SubmissionRepository + private val submissionRepository: SubmissionRepository, + private val testResultAvailableNotificationService: TestResultAvailableNotificationService ) : CWAViewModel() { val uiState: LiveData<TestResultUIState> = combine( @@ -27,6 +29,7 @@ class SubmissionTestResultNoConsentViewModel @AssistedInject constructor( fun onTestOpened() { submissionRepository.setViewedTestResult() + testResultAvailableNotificationService.cancelTestResultAvailableNotification() } @AssistedInject.Factory diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/worker/BackgroundWorkScheduler.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/worker/BackgroundWorkScheduler.kt index f751980fdb460b3df59bb3e6e0f4bb2781e0919a..8653f6147cca703d2b872487840e918a8804b4e0 100644 --- a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/worker/BackgroundWorkScheduler.kt +++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/worker/BackgroundWorkScheduler.kt @@ -84,7 +84,7 @@ object BackgroundWorkScheduler { notificationBody.append("[DIAGNOSIS_KEY_BACKGROUND_PERIODIC_WORK] ") } if (!isWorkActive(WorkTag.DIAGNOSIS_TEST_RESULT_RETRIEVAL_PERIODIC_WORKER.tag) && - LocalData.registrationToken() != null && !LocalData.isTestResultNotificationSent() + LocalData.registrationToken() != null && !LocalData.isTestResultAvailableNotificationSent() ) { WorkType.DIAGNOSIS_TEST_RESULT_PERIODIC_WORKER.start() LocalData.initialPollingForTestResultTimeStamp(System.currentTimeMillis()) diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/worker/DiagnosisTestResultRetrievalPeriodicWorker.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/worker/DiagnosisTestResultRetrievalPeriodicWorker.kt index 0ced5280b9f13817d07af6c164fab1d721f316cf..9dcba978e54483367305972cf1c10044beb69354 100644 --- a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/worker/DiagnosisTestResultRetrievalPeriodicWorker.kt +++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/worker/DiagnosisTestResultRetrievalPeriodicWorker.kt @@ -8,9 +8,10 @@ import com.squareup.inject.assisted.AssistedInject import de.rki.coronawarnapp.exception.NoRegistrationTokenSetException import de.rki.coronawarnapp.notification.NotificationConstants import de.rki.coronawarnapp.notification.NotificationHelper -import de.rki.coronawarnapp.notification.TestResultAvailableNotification +import de.rki.coronawarnapp.notification.TestResultAvailableNotificationService import de.rki.coronawarnapp.service.submission.SubmissionService import de.rki.coronawarnapp.storage.LocalData +import de.rki.coronawarnapp.submission.SubmissionSettings import de.rki.coronawarnapp.util.TimeAndDateExtensions import de.rki.coronawarnapp.util.formatter.TestResult import de.rki.coronawarnapp.util.worker.InjectedWorkerFactory @@ -25,16 +26,17 @@ import timber.log.Timber class DiagnosisTestResultRetrievalPeriodicWorker @AssistedInject constructor( @Assisted val context: Context, @Assisted workerParams: WorkerParameters, - private val submissionService: SubmissionService, - private val testResultAvailableNotification: TestResultAvailableNotification, - private val notificationHelper: NotificationHelper + private val testResultAvailableNotificationService: TestResultAvailableNotificationService, + private val notificationHelper: NotificationHelper, + private val submissionSettings: SubmissionSettings, + private val submissionService: SubmissionService ) : CoroutineWorker(context, workerParams) { /** * If background job is running for less than 21 days, testResult is checked. * If the job is running for more than 21 days, the job will be stopped * - * @see LocalData.isTestResultNotificationSent + * @see LocalData.isTestResultAvailableNotificationSent * @see LocalData.initialPollingForTestResultTimeStamp */ override suspend fun doWork(): Result { @@ -50,19 +52,27 @@ class DiagnosisTestResultRetrievalPeriodicWorker @AssistedInject constructor( } var result = Result.success() try { - if (TimeAndDateExtensions.calculateDays( - LocalData.initialPollingForTestResultTimeStamp(), - System.currentTimeMillis() - ) < BackgroundConstants.POLLING_VALIDITY_MAX_DAYS - ) { - Timber.tag(TAG).d(" $id maximum days not exceeded") + + if (abortConditionsMet()) { + Timber.tag(TAG).d(" $id Stopping worker.") + stopWorker() + } else { + Timber.tag(TAG).d(" $id Running worker.") + val registrationToken = LocalData.registrationToken() ?: throw NoRegistrationTokenSetException() val testResult = submissionService.asyncRequestTestResult(registrationToken) - initiateNotification(testResult) - Timber.tag(TAG).d(" $id Test Result Notification Initiated") - } else { - stopWorker() - Timber.tag(TAG).d(" $id worker stopped") + Timber.tag(TAG).d("$id: Test Result retrieved is $testResult") + + if (testResult == TestResult.NEGATIVE || + testResult == TestResult.POSITIVE || + testResult == TestResult.INVALID + ) { + sendTestResultAvailableNotification(testResult) + cancelRiskLevelScoreNotification() + Timber.tag(TAG) + .d("$id: Test Result available - notification sent & risk level notification canceled") + stopWorker() + } } } catch (e: Exception) { result = Result.retry() @@ -73,35 +83,38 @@ class DiagnosisTestResultRetrievalPeriodicWorker @AssistedInject constructor( return result } - /** - * Notification Initiation - * - * If the returned Test Result is Negative, Positive or Invalid - * The Background polling will be stopped - * and a notification is shown, but only if the App is not in foreground - * - * @see LocalData.isTestResultNotificationSent - * @see LocalData.initialPollingForTestResultTimeStamp - * @see TestResult - */ - private suspend fun initiateNotification(testResult: TestResult) { - if (LocalData.isTestResultNotificationSent() || LocalData.submissionWasSuccessful()) { - Timber.tag(TAG).d("$id: Notification already sent or there was a successful submission") - return + private fun abortConditionsMet(): Boolean { + if (LocalData.isTestResultAvailableNotificationSent()) { + Timber.tag(TAG).d("$id: Notification already sent.") + return true + } + if (submissionSettings.hasViewedTestResult.value) { + Timber.tag(TAG).d("$id: Test result has already been viewed.") + return true } - Timber.tag(TAG).d("$id: Test Result retried is $testResult") - if (testResult == TestResult.NEGATIVE || testResult == TestResult.POSITIVE || - testResult == TestResult.INVALID + + if (TimeAndDateExtensions.calculateDays( + LocalData.initialPollingForTestResultTimeStamp(), + System.currentTimeMillis() + ) >= BackgroundConstants.POLLING_VALIDITY_MAX_DAYS ) { - testResultAvailableNotification.showTestResultNotification(testResult) + Timber.tag(TAG) + .d(" $id Maximum of ${BackgroundConstants.POLLING_VALIDITY_MAX_DAYS} days for polling exceeded.") + return true + } - notificationHelper.cancelCurrentNotification( - NotificationConstants.NEW_MESSAGE_RISK_LEVEL_SCORE_NOTIFICATION_ID) + return false + } - Timber.tag(TAG).d("$id: Test Result available - notification issued & risk level notification canceled") - LocalData.isTestResultNotificationSent(true) - stopWorker() - } + private suspend fun sendTestResultAvailableNotification(testResult: TestResult) { + testResultAvailableNotificationService.showTestResultAvailableNotification(testResult) + LocalData.isTestResultAvailableNotificationSent(true) + } + + private fun cancelRiskLevelScoreNotification() { + notificationHelper.cancelCurrentNotification( + NotificationConstants.NEW_MESSAGE_RISK_LEVEL_SCORE_NOTIFICATION_ID + ) } /** diff --git a/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/main/home/HomeFragmentViewModelTest.kt b/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/main/home/HomeFragmentViewModelTest.kt index 6f8740a5e53a26c730e04e0a3a89b147fa7613b3..d13c1ba62cb6725cddbe45214408158d66cd9cab 100644 --- a/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/main/home/HomeFragmentViewModelTest.kt +++ b/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/main/home/HomeFragmentViewModelTest.kt @@ -3,7 +3,7 @@ package de.rki.coronawarnapp.main.home import android.content.Context import de.rki.coronawarnapp.appconfig.AppConfigProvider import de.rki.coronawarnapp.main.CWASettings -import de.rki.coronawarnapp.notification.TestResultNotificationService +import de.rki.coronawarnapp.notification.ShareTestResultNotificationService import de.rki.coronawarnapp.storage.TracingRepository import de.rki.coronawarnapp.submission.SubmissionRepository import de.rki.coronawarnapp.submission.ui.homecards.SubmissionDone @@ -51,7 +51,7 @@ class HomeFragmentViewModelTest : BaseTest() { @MockK lateinit var tracingStateProviderFactory: TracingStateProvider.Factory @MockK lateinit var submissionStateProvider: SubmissionStateProvider @MockK lateinit var tracingRepository: TracingRepository - @MockK lateinit var testResultNotificationService: TestResultNotificationService + @MockK lateinit var shareTestResultNotificationService: ShareTestResultNotificationService @MockK lateinit var submissionRepository: SubmissionRepository @MockK lateinit var cwaSettings: CWASettings @MockK lateinit var appConfigProvider: AppConfigProvider @@ -82,7 +82,7 @@ class HomeFragmentViewModelTest : BaseTest() { errorResetTool = errorResetTool, tracingStatus = generalTracingStatus, tracingRepository = tracingRepository, - testResultNotificationService = testResultNotificationService, + shareTestResultNotificationService = shareTestResultNotificationService, submissionRepository = submissionRepository, submissionStateProvider = submissionStateProvider, tracingStateProviderFactory = tracingStateProviderFactory, @@ -141,12 +141,12 @@ class HomeFragmentViewModelTest : BaseTest() { every { submissionRepository.deviceUIStateFlow } returns flowOf( NetworkRequestWrapper.RequestSuccessful(PAIRED_POSITIVE) ) - every { testResultNotificationService.schedulePositiveTestResultReminder() } returns Unit + every { shareTestResultNotificationService.scheduleSharePositiveTestResultReminder() } returns Unit runBlocking { createInstance().apply { observeTestResultToSchedulePositiveTestResultReminder() - verify { testResultNotificationService.schedulePositiveTestResultReminder() } + verify { shareTestResultNotificationService.scheduleSharePositiveTestResultReminder() } } } } @@ -156,12 +156,12 @@ class HomeFragmentViewModelTest : BaseTest() { every { submissionRepository.deviceUIStateFlow } returns flowOf( NetworkRequestWrapper.RequestSuccessful(PAIRED_POSITIVE_TELETAN) ) - every { testResultNotificationService.schedulePositiveTestResultReminder() } returns Unit + every { shareTestResultNotificationService.scheduleSharePositiveTestResultReminder() } returns Unit runBlocking { createInstance().apply { observeTestResultToSchedulePositiveTestResultReminder() - verify { testResultNotificationService.schedulePositiveTestResultReminder() } + verify { shareTestResultNotificationService.scheduleSharePositiveTestResultReminder() } } } } diff --git a/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/notification/TestResultAvailableNotificationTest.kt b/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/notification/TestResultAvailableNotificationServiceTest.kt similarity index 93% rename from Corona-Warn-App/src/test/java/de/rki/coronawarnapp/notification/TestResultAvailableNotificationTest.kt rename to Corona-Warn-App/src/test/java/de/rki/coronawarnapp/notification/TestResultAvailableNotificationServiceTest.kt index a1fe6836345fbfec8d19c463ec02bf0945ab47c4..a114b12d3e1c6440d3b0d8dc90c08d1dceb4cc67 100644 --- a/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/notification/TestResultAvailableNotificationTest.kt +++ b/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/notification/TestResultAvailableNotificationServiceTest.kt @@ -26,7 +26,7 @@ import org.junit.jupiter.api.BeforeEach import org.junit.jupiter.api.Test import javax.inject.Provider -class TestResultAvailableNotificationTest { +class TestResultAvailableNotificationServiceTest { @MockK(relaxed = true) lateinit var context: Context @MockK lateinit var foregroundState: ForegroundState @@ -53,7 +53,7 @@ class TestResultAvailableNotificationTest { clearAllMocks() } - fun createInstance() = TestResultAvailableNotification( + fun createInstance() = TestResultAvailableNotificationService( context = context, foregroundState = foregroundState, navDeepLinkBuilderProvider = navDeepLinkBuilderProvider, @@ -76,7 +76,7 @@ class TestResultAvailableNotificationTest { fun `test notification in foreground`() = runBlockingTest { coEvery { foregroundState.isInForeground } returns flow { emit(true) } - createInstance().showTestResultNotification(TestResult.POSITIVE) + createInstance().showTestResultAvailableNotification(TestResult.POSITIVE) verify(exactly = 0) { navDeepLinkBuilderProvider.get() } } @@ -95,7 +95,7 @@ class TestResultAvailableNotificationTest { val instance = createInstance() - instance.showTestResultNotification(TestResult.POSITIVE) + instance.showTestResultAvailableNotification(TestResult.POSITIVE) verifyOrder { navDeepLinkBuilderProvider.get() diff --git a/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/storage/SubmissionRepositoryTest.kt b/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/storage/SubmissionRepositoryTest.kt index e8094f0becd1b7150a6d8807e3d85f864206924f..22fe1e1f8b75d3ad14166597f280c8a7aa1bb870 100644 --- a/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/storage/SubmissionRepositoryTest.kt +++ b/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/storage/SubmissionRepositoryTest.kt @@ -99,7 +99,7 @@ class SubmissionRepositoryTest { every { LocalData.initialPollingForTestResultTimeStamp(any()) } just Runs every { LocalData.initialTestResultReceivedTimestamp(any()) } just Runs every { LocalData.isAllowedToSubmitDiagnosisKeys(any()) } just Runs - every { LocalData.isTestResultNotificationSent(any()) } just Runs + every { LocalData.isTestResultAvailableNotificationSent(any()) } just Runs submissionRepository.removeTestFromDevice() @@ -109,7 +109,7 @@ class SubmissionRepositoryTest { LocalData.initialPollingForTestResultTimeStamp(0L) LocalData.initialTestResultReceivedTimestamp(0L) LocalData.isAllowedToSubmitDiagnosisKeys(false) - LocalData.isTestResultNotificationSent(false) + LocalData.isTestResultAvailableNotificationSent(false) } } diff --git a/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/submission/task/SubmissionTaskTest.kt b/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/submission/task/SubmissionTaskTest.kt index 596fb9a2450527fc7af19e2fab7b3bb2d1c093c7..f52239464b9dbc1d92c261885012f0ff5a3d3b7c 100644 --- a/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/submission/task/SubmissionTaskTest.kt +++ b/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/submission/task/SubmissionTaskTest.kt @@ -4,8 +4,8 @@ import com.google.android.gms.nearby.exposurenotification.TemporaryExposureKey import de.rki.coronawarnapp.appconfig.AppConfigProvider import de.rki.coronawarnapp.appconfig.ConfigData import de.rki.coronawarnapp.exception.NoRegistrationTokenSetException -import de.rki.coronawarnapp.notification.TestResultAvailableNotification -import de.rki.coronawarnapp.notification.TestResultNotificationService +import de.rki.coronawarnapp.notification.ShareTestResultNotificationService +import de.rki.coronawarnapp.notification.TestResultAvailableNotificationService import de.rki.coronawarnapp.playbook.Playbook import de.rki.coronawarnapp.server.protocols.external.exposurenotification.TemporaryExposureKeyExportOuterClass import de.rki.coronawarnapp.storage.LocalData @@ -48,8 +48,8 @@ class SubmissionTaskTest : BaseTest() { @MockK lateinit var tekHistoryCalculations: ExposureKeyHistoryCalculations @MockK lateinit var tekHistoryStorage: TEKHistoryStorage @MockK lateinit var submissionSettings: SubmissionSettings - @MockK lateinit var testResultNotificationService: TestResultNotificationService - @MockK lateinit var testResultAvailableNotification: TestResultAvailableNotification + @MockK lateinit var shareTestResultNotificationService: ShareTestResultNotificationService + @MockK lateinit var testResultAvailableNotificationService: TestResultAvailableNotificationService @MockK lateinit var autoSubmission: AutoSubmission @MockK lateinit var tekBatch: TEKHistoryStorage.TEKBatch @@ -100,8 +100,8 @@ class SubmissionTaskTest : BaseTest() { coEvery { playbook.submit(any()) } just Runs - every { testResultNotificationService.cancelPositiveTestResultNotification() } just Runs - every { testResultAvailableNotification.cancelTestResultNotification() } just Runs + every { shareTestResultNotificationService.cancelSharePositiveTestResultNotification() } just Runs + every { testResultAvailableNotificationService.cancelTestResultAvailableNotification() } just Runs every { autoSubmission.updateMode(any()) } just Runs @@ -114,10 +114,10 @@ class SubmissionTaskTest : BaseTest() { tekHistoryCalculations = tekHistoryCalculations, tekHistoryStorage = tekHistoryStorage, submissionSettings = submissionSettings, - testResultNotificationService = testResultNotificationService, + shareTestResultNotificationService = shareTestResultNotificationService, timeStamper = timeStamper, autoSubmission = autoSubmission, - testResultAvailableNotification = testResultAvailableNotification + testResultAvailableNotificationService = testResultAvailableNotificationService ) @Test @@ -155,8 +155,8 @@ class SubmissionTaskTest : BaseTest() { BackgroundWorkScheduler.stopWorkScheduler() LocalData.numberOfSuccessfulSubmissions(1) - testResultNotificationService.cancelPositiveTestResultNotification() - testResultAvailableNotification.cancelTestResultNotification() + shareTestResultNotificationService.cancelSharePositiveTestResultNotification() + testResultAvailableNotificationService.cancelTestResultAvailableNotification() } } @@ -205,7 +205,7 @@ class SubmissionTaskTest : BaseTest() { coVerify(exactly = 0) { tekHistoryStorage.clear() settingSymptomsPreference.update(any()) - testResultNotificationService.cancelPositiveTestResultNotification() + shareTestResultNotificationService.cancelSharePositiveTestResultNotification() autoSubmission.updateMode(any()) } submissionSettings.symptoms.value shouldBe userSymptoms diff --git a/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/ui/submission/testresult/SubmissionTestResultConsentGivenViewModelTest.kt b/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/ui/submission/testresult/SubmissionTestResultConsentGivenViewModelTest.kt index 6e90e1fd624ef6ebf2ad30589269e5c49c4f7058..9cf860c68b74bc78a2b50c7d5b7f9f98d1a7df76 100644 --- a/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/ui/submission/testresult/SubmissionTestResultConsentGivenViewModelTest.kt +++ b/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/ui/submission/testresult/SubmissionTestResultConsentGivenViewModelTest.kt @@ -1,5 +1,6 @@ package de.rki.coronawarnapp.ui.submission.testresult +import de.rki.coronawarnapp.notification.TestResultAvailableNotificationService import de.rki.coronawarnapp.submission.SubmissionRepository import de.rki.coronawarnapp.submission.auto.AutoSubmission import de.rki.coronawarnapp.ui.submission.testresult.positive.SubmissionTestResultConsentGivenViewModel @@ -18,6 +19,7 @@ import testhelpers.extensions.InstantExecutorExtension class SubmissionTestResultConsentGivenViewModelTest : BaseTest() { @MockK lateinit var submissionRepository: SubmissionRepository @MockK lateinit var autoSubmission: AutoSubmission + @MockK lateinit var testResultAvailableNotificationService: TestResultAvailableNotificationService lateinit var viewModel: SubmissionTestResultConsentGivenViewModel @BeforeEach @@ -28,7 +30,8 @@ class SubmissionTestResultConsentGivenViewModelTest : BaseTest() { private fun createViewModel() = SubmissionTestResultConsentGivenViewModel( submissionRepository = submissionRepository, dispatcherProvider = TestDispatcherProvider, - autoSubmission = autoSubmission + autoSubmission = autoSubmission, + testResultAvailableNotificationService = testResultAvailableNotificationService ) @Test diff --git a/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/util/worker/WorkerBinderTest.kt b/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/util/worker/WorkerBinderTest.kt index 3dfbb16c00e55ac8d8c200c3a0d11c8848f1e515..7d8d75d1183497bb55efc76b55d4742d72046b8b 100644 --- a/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/util/worker/WorkerBinderTest.kt +++ b/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/util/worker/WorkerBinderTest.kt @@ -1,6 +1,8 @@ package de.rki.coronawarnapp.util.worker +import android.content.Context import androidx.work.ListenableWorker +import com.google.gson.Gson import dagger.Component import dagger.Module import dagger.Provides @@ -8,11 +10,13 @@ import de.rki.coronawarnapp.deadman.DeadmanNotificationScheduler import de.rki.coronawarnapp.deadman.DeadmanNotificationSender import de.rki.coronawarnapp.nearby.ENFClient import de.rki.coronawarnapp.notification.NotificationHelper -import de.rki.coronawarnapp.notification.TestResultAvailableNotification +import de.rki.coronawarnapp.notification.TestResultAvailableNotificationService import de.rki.coronawarnapp.playbook.Playbook import de.rki.coronawarnapp.risk.storage.RiskLevelStorage import de.rki.coronawarnapp.task.TaskController +import de.rki.coronawarnapp.util.di.AppContext import de.rki.coronawarnapp.util.di.AssistedInjectModule +import de.rki.coronawarnapp.util.serialization.BaseGson import io.github.classgraph.ClassGraph import io.kotest.matchers.collections.shouldContainAll import io.mockk.mockk @@ -100,8 +104,16 @@ class MockProvider { fun exposureSummaryRepository(): RiskLevelStorage = mockk() @Provides - fun testResultAvailableNotification(): TestResultAvailableNotification = mockk() + fun testResultAvailableNotification(): TestResultAvailableNotificationService = mockk() @Provides fun notificationHelper(): NotificationHelper = mockk() + + @Provides + @AppContext + fun context(): Context = mockk() + + @Provides + @BaseGson + fun baseGson(): Gson = mockk() }