From c166e4cb5d17337ea09739f760467f147e4cad32 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jakob=20M=C3=B6ller?= <jakob.moeller@sap.com> Date: Fri, 5 Jun 2020 18:16:59 +0200 Subject: [PATCH] Background Job Rework (#193) * Background work improved * Allow background data usage checks --- .../de/rki/coronawarnapp/storage/LocalData.kt | 9 -- .../storage/SettingsRepository.kt | 38 +---- .../rki/coronawarnapp/ui/main/MainActivity.kt | 10 +- .../rki/coronawarnapp/ui/main/MainFragment.kt | 1 - .../ui/riskdetails/RiskDetailsFragment.kt | 1 - .../ui/settings/SettingsFragment.kt | 2 - .../ui/settings/SettingsTracingFragment.kt | 3 +- .../ui/viewmodel/SettingsViewModel.kt | 27 +--- .../coronawarnapp/util/ConnectivityHelper.kt | 18 +++ .../util/formatter/FormatterRiskHelper.kt | 7 +- .../worker/BackgroundConstants.kt | 7 +- .../worker/BackgroundWorkScheduler.kt | 140 +++++++++--------- .../DiagnosisKeyRetrievalOneTimeWorker.kt | 15 +- .../DiagnosisKeyRetrievalPeriodicWorker.kt | 17 ++- .../src/main/res/layout/include_risk_card.xml | 4 +- .../src/main/res/values/strings.xml | 2 +- 16 files changed, 133 insertions(+), 168 deletions(-) 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 7735bc4ce..c6c6bba9d 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 @@ -585,13 +585,4 @@ object LocalData { ****************************************************/ fun getSharedPreferenceInstance(): SharedPreferences = globalEncryptedSharedPreferencesInstance - - fun getBackgroundWorkRelatedPreferences() = listOf( - CoronaWarnApplication.getAppContext().getString(R.string.preference_background_job_allowed), - CoronaWarnApplication.getAppContext().getString(R.string.preference_mobile_data_allowed) - ) - - fun getLastFetchDatePreference() = - CoronaWarnApplication.getAppContext() - .getString(R.string.preference_timestamp_diagnosis_keys_fetch) } diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/storage/SettingsRepository.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/storage/SettingsRepository.kt index 918f0ad3a..308385ca1 100644 --- a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/storage/SettingsRepository.kt +++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/storage/SettingsRepository.kt @@ -24,7 +24,6 @@ object SettingsRepository { val isManualKeyRetrievalEnabled = MutableLiveData(true) val isConnectionEnabled = MutableLiveData(true) val isBluetoothEnabled = MutableLiveData(true) - val isMobileDataEnabled = MutableLiveData(true) val isBackgroundJobEnabled = MutableLiveData(true) // TODO should go to a formatter @@ -97,40 +96,11 @@ object SettingsRepository { } /** - * Toggle mobile data in shared preferences and refresh it afterwards. - * - * @see LocalData - */ - fun toggleMobileDataEnabled() { - LocalData.toggleMobileDataEnabled() - refreshMobileDataEnabled() - } - - /** - * Refresh mobile data with the current shared preferences state. - * - * @see LocalData - */ - fun refreshMobileDataEnabled() { - isMobileDataEnabled.value = LocalData.isMobileDataEnabled() - } - - /** - * Toggle background job in shared preferences and refresh it afterwards. - * - * @see LocalData - */ - fun toggleBackgroundJobEnabled() { - LocalData.toggleBackgroundJobEnabled() - refreshBackgroundJobEnabled() - } - - /** - * Refresh background job with the current shared preferences state. + * Refresh global bluetooth state to point out that tracing isn't working * - * @see LocalData + * @see ConnectivityHelper */ - fun refreshBackgroundJobEnabled() { - isBackgroundJobEnabled.value = LocalData.isBackgroundJobEnabled() + fun updateBackgroundJobEnabled(value: Boolean) { + isBackgroundJobEnabled.postValue(value) } } diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/main/MainActivity.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/main/MainActivity.kt index 091353254..1d03c732a 100644 --- a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/main/MainActivity.kt +++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/main/MainActivity.kt @@ -2,6 +2,7 @@ package de.rki.coronawarnapp.ui.main import android.content.Intent import android.os.Bundle +import android.util.Log import androidx.appcompat.app.AppCompatActivity import androidx.fragment.app.Fragment import androidx.fragment.app.FragmentManager @@ -55,10 +56,6 @@ class MainActivity : AppCompatActivity() { } } - init { - scheduleWork() - } - override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_main) @@ -66,12 +63,15 @@ class MainActivity : AppCompatActivity() { } /** - * Register network and bluetooth callback. + * Register network, bluetooth and data saver callback. */ override fun onResume() { super.onResume() ConnectivityHelper.registerNetworkStatusCallback(this, callbackNetwork) ConnectivityHelper.registerBluetoothStatusCallback(this, callbackBluetooth) + Log.d(TAG, "Background work is available: ${!ConnectivityHelper.isDataSaverEnabled(this)}") + settingsViewModel.updateBackgroundJobEnabled(!ConnectivityHelper.isDataSaverEnabled(this)) + scheduleWork() showDialogWithStacktraceIfPreviouslyCrashed() } diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/main/MainFragment.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/main/MainFragment.kt index 53404e0f9..3634469be 100644 --- a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/main/MainFragment.kt +++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/main/MainFragment.kt @@ -72,7 +72,6 @@ class MainFragment : BaseFragment() { tracingViewModel.refreshLastTimeDiagnosisKeysFetchedDate() tracingViewModel.refreshIsTracingEnabled() tracingViewModel.refreshActiveTracingDaysInRetentionPeriod() - settingsViewModel.refreshBackgroundJobEnabled() TimerHelper.checkManualKeyRetrievalTimer() submissionViewModel.refreshDeviceUIState() } diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/riskdetails/RiskDetailsFragment.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/riskdetails/RiskDetailsFragment.kt index 13e9e6564..893a95287 100644 --- a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/riskdetails/RiskDetailsFragment.kt +++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/riskdetails/RiskDetailsFragment.kt @@ -57,7 +57,6 @@ class RiskDetailsFragment : BaseFragment() { tracingViewModel.refreshRiskLevel() tracingViewModel.refreshExposureSummary() tracingViewModel.refreshLastTimeDiagnosisKeysFetchedDate() - settingsViewModel.refreshBackgroundJobEnabled() TimerHelper.checkManualKeyRetrievalTimer() } diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/settings/SettingsFragment.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/settings/SettingsFragment.kt index 55f10e046..f7aab9c19 100644 --- a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/settings/SettingsFragment.kt +++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/settings/SettingsFragment.kt @@ -57,8 +57,6 @@ class SettingsFragment : BaseFragment() { settingsViewModel.refreshNotificationsEnabled(requireContext()) settingsViewModel.refreshNotificationsRiskEnabled() settingsViewModel.refreshNotificationsTestEnabled() - settingsViewModel.refreshMobileDataEnabled() - settingsViewModel.refreshBackgroundJobEnabled() } private fun setButtonOnClickListener() { diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/settings/SettingsTracingFragment.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/settings/SettingsTracingFragment.kt index 7a4f6cbc0..382d34f05 100644 --- a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/settings/SettingsTracingFragment.kt +++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/settings/SettingsTracingFragment.kt @@ -81,8 +81,7 @@ class SettingsTracingFragment : BaseFragment(), override fun onStartPermissionGranted() { tracingViewModel.refreshIsTracingEnabled() - // TODO - BackgroundWorkScheduler.checkStart() + BackgroundWorkScheduler.startWorkScheduler() Toast.makeText(requireContext(), "Tracing started successfully", Toast.LENGTH_SHORT).show() } diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/viewmodel/SettingsViewModel.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/viewmodel/SettingsViewModel.kt index ada13e703..05809e74c 100644 --- a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/viewmodel/SettingsViewModel.kt +++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/viewmodel/SettingsViewModel.kt @@ -22,10 +22,6 @@ class SettingsViewModel : ViewModel() { val isBluetoothEnabled: LiveData<Boolean> = SettingsRepository.isBluetoothEnabled - // Todo bind to os settings, change to general network availability, cannot be set within the app - // Will impact UI if no network connection is found, persistent storing is not necessary - val isMobileDataEnabled: LiveData<Boolean> = SettingsRepository.isMobileDataEnabled - // Todo bind to os settings, care API 23 / API 24 onwards // Will impact UI if background activity is not permitted, persistent storing is not necessary val isBackgroundJobEnabled: LiveData<Boolean> = SettingsRepository.isBackgroundJobEnabled @@ -102,24 +98,11 @@ class SettingsViewModel : ViewModel() { } /** - * Refresh & toggle mobile data enabled - */ - fun refreshMobileDataEnabled() { - SettingsRepository.refreshMobileDataEnabled() - } - - fun toggleMobileDataEnabled() { - SettingsRepository.toggleMobileDataEnabled() - } - - /** - * Refresh & toggle background job enabled + * Update background job enabled + * + * @param value */ - fun refreshBackgroundJobEnabled() { - SettingsRepository.refreshBackgroundJobEnabled() - } - - fun toggleBackgroundJobEnabled() { - SettingsRepository.toggleBackgroundJobEnabled() + fun updateBackgroundJobEnabled(value: Boolean) { + SettingsRepository.updateBackgroundJobEnabled(value) } } diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/util/ConnectivityHelper.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/util/ConnectivityHelper.kt index 6118ea661..457de57a6 100644 --- a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/util/ConnectivityHelper.kt +++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/util/ConnectivityHelper.kt @@ -9,6 +9,7 @@ import android.net.ConnectivityManager import android.net.Network import android.net.NetworkCapabilities import android.net.NetworkRequest +import android.os.Build import android.util.Log import de.rki.coronawarnapp.exception.ExceptionCategory import de.rki.coronawarnapp.exception.report @@ -120,6 +121,23 @@ object ConnectivityHelper { } } + /** + * For API level 24+ check if data saver is enabled + * Else always return false + * + * @param context the context + * + * @return Boolean + * + * @see ConnectivityManager.RESTRICT_BACKGROUND_STATUS_DISABLED + */ + fun isDataSaverEnabled(context: Context): Boolean { + return if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) { + val connectivityManager = context.getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager + connectivityManager.restrictBackgroundStatus != ConnectivityManager.RESTRICT_BACKGROUND_STATUS_DISABLED + } else false + } + /** * Get bluetooth enabled status. * diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/util/formatter/FormatterRiskHelper.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/util/formatter/FormatterRiskHelper.kt index 29adcd8d9..2b26669bf 100644 --- a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/util/formatter/FormatterRiskHelper.kt +++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/util/formatter/FormatterRiskHelper.kt @@ -255,8 +255,7 @@ fun formatTimeFetched( */ fun formatNextUpdate( riskLevelScore: Int?, - isBackgroundJobEnabled: Boolean?, - nextUpdate: Date + isBackgroundJobEnabled: Boolean? ): String { val appContext = CoronaWarnApplication.getAppContext() return if (isBackgroundJobEnabled != true) { @@ -266,9 +265,7 @@ fun formatNextUpdate( RiskLevelConstants.UNKNOWN_RISK_INITIAL, RiskLevelConstants.LOW_LEVEL_RISK, RiskLevelConstants.INCREASED_RISK -> appContext.getString( - R.string.risk_card_body_next_update, - DateFormat.getDateTimeInstance(DateFormat.SHORT, DateFormat.MEDIUM) - .format(nextUpdate) + R.string.risk_card_body_next_update ) else -> "" } diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/worker/BackgroundConstants.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/worker/BackgroundConstants.kt index 3c5c8eb80..a36174aea 100644 --- a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/worker/BackgroundConstants.kt +++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/worker/BackgroundConstants.kt @@ -38,7 +38,7 @@ object BackgroundConstants { * Total tries count for diagnosis key retrieval per day * Internal requirement */ - const val DIAGNOSIS_KEY_RETRIEVAL_TRIES_PER_DAY = 12 + const val DIAGNOSIS_KEY_RETRIEVAL_TRIES_PER_DAY = 1 /** * Maximum tries count for diagnosis key retrieval per day @@ -84,4 +84,9 @@ object BackgroundConstants { * @see TimeUnit.MINUTES */ const val TIME_RANGE_MAX = 1439 + + /** + * Retries before work would set as FAILED + */ + const val WORKER_RETRY_COUNT_THRESHOLD = 3 } 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 88f2db0be..a40cef82d 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 @@ -1,7 +1,7 @@ package de.rki.coronawarnapp.worker -import android.content.SharedPreferences.OnSharedPreferenceChangeListener import android.util.Log +import androidx.work.BackoffPolicy import androidx.work.Constraints import androidx.work.ExistingPeriodicWorkPolicy import androidx.work.ExistingWorkPolicy @@ -9,14 +9,14 @@ import androidx.work.NetworkType import androidx.work.OneTimeWorkRequestBuilder import androidx.work.Operation import androidx.work.PeriodicWorkRequestBuilder +import androidx.work.WorkInfo import androidx.work.WorkManager import de.rki.coronawarnapp.BuildConfig import de.rki.coronawarnapp.CoronaWarnApplication -import de.rki.coronawarnapp.storage.LocalData -import de.rki.coronawarnapp.storage.TracingRepository import org.joda.time.DateTime import org.joda.time.DateTimeZone import org.joda.time.Instant +import java.util.concurrent.ExecutionException import java.util.concurrent.TimeUnit /** @@ -78,11 +78,6 @@ object BackgroundWorkScheduler { BackgroundConstants.DIAGNOSIS_KEY_RETRIEVAL_TRIES_PER_DAY .coerceAtMost(BackgroundConstants.GOOGLE_API_MAX_CALLS_PER_DAY) - /** - * Shared preferences listener - */ - private var sharedPrefListener: OnSharedPreferenceChangeListener? = null - /** * Work manager instance */ @@ -90,27 +85,44 @@ object BackgroundWorkScheduler { /** * Start work scheduler - * Subscribe shared preferences listener for changes. If any changes regarding background work - * occurred, then reschedule periodic work or stop it (depends on changes occurred). - * Two keys are monitored: - * - preference_background_jonboarding_allowed - * - preference_mobile_data_allowed - * @see LocalData.getBackgroundWorkRelatedPreferences() + * Checks if periodic worker was already scheduled. If not - reschedule it again. + * + * @see isWorkActive */ fun startWorkScheduler() { - sharedPrefListener = OnSharedPreferenceChangeListener { _, key -> - if (LocalData.getBackgroundWorkRelatedPreferences().contains(key)) { - logSharedPreferencesChange(key) - checkStart() - } else if (key == LocalData.getLastFetchDatePreference()) { - TracingRepository.refreshLastTimeDiagnosisKeysFetchedDate() + val isPeriodicWorkActive = isWorkActive(WorkTag.DIAGNOSIS_KEY_RETRIEVAL_PERIODIC_WORKER.tag) + logWorkActiveStatus(WorkTag.DIAGNOSIS_KEY_RETRIEVAL_PERIODIC_WORKER.tag, isPeriodicWorkActive) + if (!isPeriodicWorkActive) WorkType.DIAGNOSIS_KEY_BACKGROUND_PERIODIC_WORK.start() + } + + /** + * Checks if defined work is active + * Non-active means worker was Cancelled, Failed or have not been enqueued at all + * + * @param tag String tag of the worker + * + * @return Boolean + * + * @see WorkInfo.State.CANCELLED + * @see WorkInfo.State.FAILED + */ + private fun isWorkActive(tag: String): Boolean { + val workStatus = workManager.getWorkInfosByTag(tag) + var result = true + try { + val workInfoList = workStatus.get() + if (workInfoList.size == 0) result = false + for (info in workInfoList) { + if (info.state == WorkInfo.State.CANCELLED || info.state == WorkInfo.State.FAILED) { + result = false + } } + } catch (e: ExecutionException) { + result = false + } catch (e: InterruptedException) { + result = false } - LocalData.getSharedPreferenceInstance().registerOnSharedPreferenceChangeListener( - sharedPrefListener - ) - // TODO: Reimplement after clarifications - WorkType.DIAGNOSIS_KEY_BACKGROUND_PERIODIC_WORK.start() + return result } /** @@ -125,31 +137,21 @@ object BackgroundWorkScheduler { } /** - * Check start periodic work - * If background work is enabled, than reschedule it. else - stop it. + * Schedule diagnosis key one time work * - * @see LocalData.isBackgroundJobEnabled() - * @see WorkType.DIAGNOSIS_KEY_BACKGROUND_PERIODIC_WORK + * @see WorkType.DIAGNOSIS_KEY_BACKGROUND_ONE_TIME_WORK */ - fun checkStart() { - if (LocalData.isBackgroundJobEnabled()) { - WorkType.DIAGNOSIS_KEY_BACKGROUND_ONE_TIME_WORK.stop() - WorkType.DIAGNOSIS_KEY_BACKGROUND_PERIODIC_WORK.start() - } else { - stopWorkScheduler() - } + fun scheduleDiagnosisKeyPeriodicWork() { + WorkType.DIAGNOSIS_KEY_BACKGROUND_PERIODIC_WORK.start() } /** * Schedule diagnosis key one time work * - * @see LocalData.isBackgroundJobEnabled() * @see WorkType.DIAGNOSIS_KEY_BACKGROUND_ONE_TIME_WORK */ fun scheduleDiagnosisKeyOneTimeWork() { - if (LocalData.isBackgroundJobEnabled()) { - WorkType.DIAGNOSIS_KEY_BACKGROUND_ONE_TIME_WORK.start() - } + WorkType.DIAGNOSIS_KEY_BACKGROUND_ONE_TIME_WORK.start() } /** @@ -164,15 +166,6 @@ object BackgroundWorkScheduler { WorkType.DIAGNOSIS_KEY_BACKGROUND_ONE_TIME_WORK -> enqueueDiagnosisKeyBackgroundOneTimeWork() } - /** - * Stop work by unique name - * - * @return Operation - * - * @see WorkType - */ - private fun WorkType.stop(): Operation = workManager.cancelUniqueWork(this.uniqueName) - /** * Enqueue diagnosis key periodic work and log it * Replace with new if older work exists. @@ -204,11 +197,13 @@ object BackgroundWorkScheduler { /** * Build diagnosis key periodic work request * Set "kind delay" for accessibility reason. + * Backoff criteria set to Linear type. * * @return PeriodicWorkRequest * * @see WorkTag.DIAGNOSIS_KEY_RETRIEVAL_PERIODIC_WORKER * @see BackgroundConstants.DIAGNOSIS_KEY_PERIODIC_KIND_DELAY + * @see BackoffPolicy.LINEAR */ private fun buildDiagnosisKeyRetrievalPeriodicWork() = PeriodicWorkRequestBuilder<DiagnosisKeyRetrievalPeriodicWorker>( @@ -220,16 +215,24 @@ object BackgroundWorkScheduler { BackgroundConstants.DIAGNOSIS_KEY_PERIODIC_KIND_DELAY, TimeUnit.MINUTES ) + .setBackoffCriteria( + BackoffPolicy.LINEAR, + BackgroundConstants.DIAGNOSIS_KEY_PERIODIC_KIND_DELAY, + TimeUnit.MINUTES + ) .build() /** * Build diagnosis key one time work request * Set random initial delay for security reason. + * Backoff criteria set to Linear type. * * @return OneTimeWorkRequest * * @see WorkTag.DIAGNOSIS_KEY_RETRIEVAL_ONE_TIME_WORKER * @see buildDiagnosisKeyRetrievalOneTimeWork + * @see BackgroundConstants.DIAGNOSIS_KEY_PERIODIC_KIND_DELAY + * @see BackoffPolicy.LINEAR */ private fun buildDiagnosisKeyRetrievalOneTimeWork() = OneTimeWorkRequestBuilder<DiagnosisKeyRetrievalOneTimeWorker>() @@ -243,6 +246,11 @@ object BackgroundWorkScheduler { ) ), TimeUnit.MINUTES ) + .setBackoffCriteria( + BackoffPolicy.LINEAR, + BackgroundConstants.DIAGNOSIS_KEY_PERIODIC_KIND_DELAY, + TimeUnit.MINUTES + ) .build() /** @@ -256,29 +264,19 @@ object BackgroundWorkScheduler { /** * Constraints for diagnosis key one time work - * Depends on current application settings. + * Requires battery not low and any network connection + * Mobile data usage is handled on OS level in application settings * * @return Constraints * - * @see LocalData.isMobileDataEnabled() + * @see NetworkType.CONNECTED */ - private fun getConstraintsForDiagnosisKeyOneTimeBackgroundWork(): Constraints { - val builder = Constraints.Builder() - if (LocalData.isMobileDataEnabled()) { - if (BuildConfig.DEBUG) Log.d( - TAG, "${WorkType.DIAGNOSIS_KEY_BACKGROUND_ONE_TIME_WORK}:" + - "$BackgroundConstants.NETWORK_ROAMING_ALLOWED" - ) - builder.setRequiredNetworkType(NetworkType.CONNECTED) - } else { - if (BuildConfig.DEBUG) Log.d( - TAG, "${WorkType.DIAGNOSIS_KEY_BACKGROUND_ONE_TIME_WORK}:" + - "$BackgroundConstants.NETWORK_ROAMING_FORBIDDEN" - ) - builder.setRequiredNetworkType(NetworkType.NOT_ROAMING) - } - return builder.build() - } + private fun getConstraintsForDiagnosisKeyOneTimeBackgroundWork() = + Constraints + .Builder() + .setRequiresBatteryNotLow(true) + .setRequiredNetworkType(NetworkType.CONNECTED) + .build() /** * Log operation schedule @@ -296,9 +294,9 @@ object BackgroundWorkScheduler { .also { if (BuildConfig.DEBUG) Log.d(TAG, "Canceling all work with tag ${workTag.tag}") } /** - * Log shared preferences change + * Log work active status */ - private fun logSharedPreferencesChange(key: String) { - if (BuildConfig.DEBUG) Log.d(TAG, "Shared preferences was changed in key: $key") + private fun logWorkActiveStatus(tag: String, active: Boolean) { + if (BuildConfig.DEBUG) Log.d(TAG, "Work type $tag is active: $active") } } diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/worker/DiagnosisKeyRetrievalOneTimeWorker.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/worker/DiagnosisKeyRetrievalOneTimeWorker.kt index 777edc0c3..5f31a256b 100644 --- a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/worker/DiagnosisKeyRetrievalOneTimeWorker.kt +++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/worker/DiagnosisKeyRetrievalOneTimeWorker.kt @@ -5,8 +5,6 @@ import android.util.Log import androidx.work.CoroutineWorker import androidx.work.WorkerParameters import de.rki.coronawarnapp.BuildConfig -import de.rki.coronawarnapp.exception.ExceptionCategory -import de.rki.coronawarnapp.exception.report import de.rki.coronawarnapp.transaction.RetrieveDiagnosisKeysTransaction /** @@ -30,13 +28,18 @@ class DiagnosisKeyRetrievalOneTimeWorker(val context: Context, workerParams: Wor * @see RetrieveDiagnosisKeysTransaction */ override suspend fun doWork(): Result { - if (BuildConfig.DEBUG) Log.d(TAG, "Background job started...") + if (BuildConfig.DEBUG) Log.d(TAG, "Background job started. Run attempt: $runAttemptCount") + + if (runAttemptCount > BackgroundConstants.WORKER_RETRY_COUNT_THRESHOLD) { + if (BuildConfig.DEBUG) Log.d(TAG, "Background job failed after $runAttemptCount attempts. Rescheduling") + return Result.failure() + } + var result = Result.success() try { RetrieveDiagnosisKeysTransaction.start() } catch (e: Exception) { - e.report(ExceptionCategory.JOB) - return Result.failure() + result = Result.retry() } - return Result.success() + return result } } diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/worker/DiagnosisKeyRetrievalPeriodicWorker.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/worker/DiagnosisKeyRetrievalPeriodicWorker.kt index 1caccef0b..f7d7eee4f 100644 --- a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/worker/DiagnosisKeyRetrievalPeriodicWorker.kt +++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/worker/DiagnosisKeyRetrievalPeriodicWorker.kt @@ -5,8 +5,6 @@ import android.util.Log import androidx.work.CoroutineWorker import androidx.work.WorkerParameters import de.rki.coronawarnapp.BuildConfig -import de.rki.coronawarnapp.exception.ExceptionCategory -import de.rki.coronawarnapp.exception.report /** * Periodic diagnosis key retrieval work @@ -27,16 +25,23 @@ class DiagnosisKeyRetrievalPeriodicWorker(val context: Context, workerParams: Wo * * @return Result * + * @see BackgroundWorkScheduler.scheduleDiagnosisKeyPeriodicWork() * @see BackgroundWorkScheduler.scheduleDiagnosisKeyOneTimeWork() */ override suspend fun doWork(): Result { - if (BuildConfig.DEBUG) Log.d(TAG, "Background job started...") + if (BuildConfig.DEBUG) Log.d(TAG, "Background job started. Run attempt: $runAttemptCount") + + if (runAttemptCount > BackgroundConstants.WORKER_RETRY_COUNT_THRESHOLD) { + if (BuildConfig.DEBUG) Log.d(TAG, "Background job failed after $runAttemptCount attempts. Rescheduling") + BackgroundWorkScheduler.scheduleDiagnosisKeyPeriodicWork() + return Result.failure() + } + var result = Result.success() try { BackgroundWorkScheduler.scheduleDiagnosisKeyOneTimeWork() } catch (e: Exception) { - e.report(ExceptionCategory.JOB) - return Result.failure() + result = Result.retry() } - return Result.success() + return result } } diff --git a/Corona-Warn-App/src/main/res/layout/include_risk_card.xml b/Corona-Warn-App/src/main/res/layout/include_risk_card.xml index 31f9e683f..6c7e4acf0 100644 --- a/Corona-Warn-App/src/main/res/layout/include_risk_card.xml +++ b/Corona-Warn-App/src/main/res/layout/include_risk_card.xml @@ -209,7 +209,7 @@ android:layout_width="0dp" android:layout_height="wrap_content" android:layout_marginTop="@dimen/spacing_normal" - android:visibility="@{FormatterHelper.formatVisibilityText(FormatterRiskHelper.formatNextUpdate(tracingViewModel.riskLevel, settingsViewModel.isBackgroundJobEnabled(), tracingViewModel.nextUpdate))}" + android:visibility="@{FormatterHelper.formatVisibilityText(FormatterRiskHelper.formatNextUpdate(tracingViewModel.riskLevel, settingsViewModel.isBackgroundJobEnabled()))}" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toBottomOf="@+id/risk_card_row_time_fetched"> @@ -227,7 +227,7 @@ android:layout_width="0dp" android:layout_height="wrap_content" android:layout_marginTop="@dimen/spacing_small" - android:text="@{FormatterRiskHelper.formatNextUpdate(tracingViewModel.riskLevel, settingsViewModel.isBackgroundJobEnabled(), tracingViewModel.nextUpdate)}" + android:text="@{FormatterRiskHelper.formatNextUpdate(tracingViewModel.riskLevel, settingsViewModel.isBackgroundJobEnabled())}" android:textColor="@{FormatterRiskHelper.formatStableTextColor(tracingViewModel.riskLevel)}" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintStart_toStartOf="parent" diff --git a/Corona-Warn-App/src/main/res/values/strings.xml b/Corona-Warn-App/src/main/res/values/strings.xml index 6f3c230cc..15c559b77 100644 --- a/Corona-Warn-App/src/main/res/values/strings.xml +++ b/Corona-Warn-App/src/main/res/values/strings.xml @@ -164,7 +164,7 @@ <string name="risk_card_body_saved_days">%1$s von 14 Tagen aktiv</string> <string name="risk_card_body_not_yet_fetched">Kontakte wurden noch nicht überprüft.</string> <string name="risk_card_body_time_fetched">Aktualisiert: %1$s</string> - <string name="risk_card_body_next_update">Nächste Aktualisierung in: %1$s</string> + <string name="risk_card_body_next_update">Tägliche Aktualisierung</string> <!-- XBUT: risk card - update risk --> <string name="risk_card_button_update">Aktualisieren</string> <string name="risk_card_button_cooldown">Aktualisierung in %1$s</string> -- GitLab