From 0753c49cc1286ea25f788878b15aa65831d8e495 Mon Sep 17 00:00:00 2001 From: Matthias Urhahn <matthias.urhahn@sap.com> Date: Wed, 11 Nov 2020 14:58:21 +0100 Subject: [PATCH] New quota error (EXPOSUREAPP-3511) (#1569) * Show more specific error message when quota limit is reached and remove "Update ever 24h text". * Show custom title in error dialog and make stack trace selectable. * LINTs * Add a log statement so that in all cases the the base error reporting is made visible. Co-authored-by: harambasicluka <64483219+harambasicluka@users.noreply.github.com> --- .../processor/DefaultBugProcessor.kt | 7 +- .../coronawarnapp/bugreporting/BugReporter.kt | 3 + .../reporting/ErrorReportReceiver.kt | 72 ++++++++++-------- .../exception/reporting/ExceptionReporter.kt | 21 ++--- .../exception/reporting/ReportingConstants.kt | 1 + .../DefaultDiagnosisKeyProvider.kt | 12 ++- .../QuotaExceededException.kt | 16 ++++ .../storage/InsufficientStorageException.kt | 12 ++- .../ui/tracing/card/TracingCardState.kt | 17 ----- .../de/rki/coronawarnapp/util/DialogHelper.kt | 42 +++++----- .../rki/coronawarnapp/util/FormattedError.kt | 12 --- .../util/HasHumanReadableError.kt | 21 +++++ .../res/layout/include_risk_card_content.xml | 29 +------ .../src/main/res/values-de/strings.xml | 7 +- .../src/main/res/values/strings.xml | 4 + .../ui/tracing/card/TracingCardStateTest.kt | 76 ------------------- 16 files changed, 143 insertions(+), 209 deletions(-) create mode 100644 Corona-Warn-App/src/main/java/de/rki/coronawarnapp/nearby/modules/diagnosiskeyprovider/QuotaExceededException.kt delete mode 100644 Corona-Warn-App/src/main/java/de/rki/coronawarnapp/util/FormattedError.kt create mode 100644 Corona-Warn-App/src/main/java/de/rki/coronawarnapp/util/HasHumanReadableError.kt diff --git a/Corona-Warn-App/src/deviceForTesters/java/de/rki/coronawarnapp/bugreporting/processor/DefaultBugProcessor.kt b/Corona-Warn-App/src/deviceForTesters/java/de/rki/coronawarnapp/bugreporting/processor/DefaultBugProcessor.kt index 12c569990..0c19f0fae 100644 --- a/Corona-Warn-App/src/deviceForTesters/java/de/rki/coronawarnapp/bugreporting/processor/DefaultBugProcessor.kt +++ b/Corona-Warn-App/src/deviceForTesters/java/de/rki/coronawarnapp/bugreporting/processor/DefaultBugProcessor.kt @@ -9,7 +9,7 @@ import de.rki.coronawarnapp.bugreporting.event.DefaultBugEvent import de.rki.coronawarnapp.bugreporting.loghistory.RollingLogHistory import de.rki.coronawarnapp.util.TimeStamper import de.rki.coronawarnapp.util.di.AppContext -import de.rki.coronawarnapp.util.tryFormattedError +import de.rki.coronawarnapp.util.tryHumanReadableError import javax.inject.Inject import javax.inject.Singleton @@ -21,8 +21,9 @@ class DefaultBugProcessor @Inject constructor( ) : BugProcessor { override suspend fun processor(throwable: Throwable, tag: String?, info: String?): BugEvent { + val formattedError = throwable.tryHumanReadableError(context) + val crashedAt = timeStamper.nowUTC - val exceptionMessage = throwable.tryFormattedError(context) val exceptionClass = throwable::class.java.simpleName val stacktrace = Log.getStackTraceString(throwable) val deviceInfo = "${Build.MANUFACTURER} ${Build.MODEL} (${Build.DEVICE})" @@ -38,7 +39,7 @@ class DefaultBugProcessor @Inject constructor( tag = tag, info = info, exceptionClass = exceptionClass, - exceptionMessage = exceptionMessage, + exceptionMessage = formattedError.description, stackTrace = stacktrace, deviceInfo = deviceInfo, appVersionName = appVersionName, diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/bugreporting/BugReporter.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/bugreporting/BugReporter.kt index d67d523d9..31913f27d 100644 --- a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/bugreporting/BugReporter.kt +++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/bugreporting/BugReporter.kt @@ -2,12 +2,15 @@ package de.rki.coronawarnapp.bugreporting import de.rki.coronawarnapp.util.CWADebug import de.rki.coronawarnapp.util.di.AppInjector +import timber.log.Timber interface BugReporter { fun report(throwable: Throwable, tag: String? = null, info: String? = null) } fun Throwable.reportProblem(tag: String? = null, info: String? = null) { + Timber.tag("BugReporter").v(this, "report(tag=$tag, info=$info)") + if (CWADebug.isAUnitTest) return val reporter = AppInjector.component.bugReporter reporter.report(this, tag, info) diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/exception/reporting/ErrorReportReceiver.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/exception/reporting/ErrorReportReceiver.kt index 8aafc6246..ac820f405 100644 --- a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/exception/reporting/ErrorReportReceiver.kt +++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/exception/reporting/ErrorReportReceiver.kt @@ -12,17 +12,12 @@ import timber.log.Timber import java.util.Locale class ErrorReportReceiver(private val activity: Activity) : BroadcastReceiver() { - companion object { - private val TAG: String = ErrorReportReceiver::class.java.simpleName - } + @Suppress("LongMethod") override fun onReceive(context: Context, intent: Intent) { val category = ExceptionCategory .valueOf(intent.getStringExtra(ReportingConstants.ERROR_REPORT_CATEGORY_EXTRA) ?: "") - val errorCode = intent.getIntExtra( - ReportingConstants.ERROR_REPORT_CODE_EXTRA, - ReportingConstants.ERROR_REPORT_UNKNOWN_ERROR - ) + val prefix = intent.getStringExtra(ReportingConstants.ERROR_REPORT_PREFIX_EXTRA) val suffix = intent.getStringExtra(ReportingConstants.ERROR_REPORT_SUFFIX_EXTRA) @@ -41,7 +36,7 @@ class ErrorReportReceiver(private val activity: Activity) : BroadcastReceiver() val confirm = context.resources.getString(R.string.errors_generic_button_positive) val details = context.resources.getString(R.string.errors_generic_button_negative) - var detailsTitle = context.resources.getString(R.string.errors_generic_details_headline) + val detailsTitle = context.resources.getString(R.string.errors_generic_details_headline) if (intent.hasExtra(ReportingConstants.ERROR_REPORT_API_EXCEPTION_CODE)) { val apiStatusCode = intent.getIntExtra( @@ -52,31 +47,44 @@ class ErrorReportReceiver(private val activity: Activity) : BroadcastReceiver() message += "#$apiStatusCode" } - val errorTitle = context.resources.getString(R.string.errors_generic_details_headline) - .toUpperCase(Locale.ROOT) - - if (CoronaWarnApplication.isAppInForeground) { - DialogHelper.showDialog( - DialogHelper.DialogInstance( - activity, - "$errorTitle: $errorCode\n$title", - message, - confirm, - details, - null, - {}, - { - DialogHelper.showDialog( - DialogHelper.DialogInstance( - activity, - title, - "$detailsTitle:\n$stack", - confirm - ) - ).run {} - } - )) + val dialogTitle = if (intent.hasExtra(ReportingConstants.ERROR_REPORT_TITLE_EXTRA)) { + intent.getStringExtra(ReportingConstants.ERROR_REPORT_TITLE_EXTRA) + } else { + val errorTitle = context.resources.getString(R.string.errors_generic_details_headline) + .toUpperCase(Locale.ROOT) + val errorCode = intent.getIntExtra( + ReportingConstants.ERROR_REPORT_CODE_EXTRA, + ReportingConstants.ERROR_REPORT_UNKNOWN_ERROR + ) + "$errorTitle: $errorCode\n$title" } + Timber.e("[$category]${(prefix ?: "")} $message${(suffix ?: "")}") + + if (!CoronaWarnApplication.isAppInForeground) { + Timber.v("Not displaying error dialog, not in foreground.") + return + } + + val dialogInstance = DialogHelper.DialogInstance( + context = activity, + title = dialogTitle, + message = message, + positiveButton = confirm, + negativeButton = details, + cancelable = null, + positiveButtonFunction = {}, + negativeButtonFunction = { + val stackTraceDialog = DialogHelper.DialogInstance( + activity, + title, + "$detailsTitle:\n$stack", + confirm + ) + DialogHelper.showDialog(stackTraceDialog.copy(isTextSelectable = true)) + Unit + } + ) + DialogHelper.showDialog(dialogInstance) } } diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/exception/reporting/ExceptionReporter.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/exception/reporting/ExceptionReporter.kt index 06a6455a5..e8b2ec5da 100644 --- a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/exception/reporting/ExceptionReporter.kt +++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/exception/reporting/ExceptionReporter.kt @@ -10,8 +10,8 @@ import de.rki.coronawarnapp.exception.ExceptionCategory import de.rki.coronawarnapp.exception.reporting.ReportingConstants.STATUS_CODE_GOOGLE_API_FAIL import de.rki.coronawarnapp.exception.reporting.ReportingConstants.STATUS_CODE_GOOGLE_UPDATE_NEEDED import de.rki.coronawarnapp.exception.reporting.ReportingConstants.STATUS_CODE_REACHED_REQUEST_LIMIT +import de.rki.coronawarnapp.util.tryHumanReadableError import de.rki.coronawarnapp.util.CWADebug -import de.rki.coronawarnapp.util.tryFormattedError import java.io.PrintWriter import java.io.StringWriter @@ -28,11 +28,14 @@ fun Throwable.report( reportProblem(tag = prefix, info = suffix) val context = CoronaWarnApplication.getAppContext() + val formattedError = this.tryHumanReadableError(context) + val intent = Intent(ReportingConstants.ERROR_REPORT_LOCAL_BROADCAST_CHANNEL) intent.putExtra(ReportingConstants.ERROR_REPORT_CATEGORY_EXTRA, exceptionCategory.name) intent.putExtra(ReportingConstants.ERROR_REPORT_PREFIX_EXTRA, prefix) intent.putExtra(ReportingConstants.ERROR_REPORT_SUFFIX_EXTRA, suffix) - intent.putExtra(ReportingConstants.ERROR_REPORT_MESSAGE_EXTRA, this.tryFormattedError(context)) + intent.putExtra(ReportingConstants.ERROR_REPORT_TITLE_EXTRA, formattedError.title) + intent.putExtra(ReportingConstants.ERROR_REPORT_MESSAGE_EXTRA, formattedError.description) if (this is ReportedExceptionInterface) { intent.putExtra(ReportingConstants.ERROR_REPORT_CODE_EXTRA, this.code) @@ -54,10 +57,7 @@ fun Throwable.report( errorMessage = R.string.errors_google_api_error } - intent.putExtra( - ReportingConstants.ERROR_REPORT_RES_ID, - errorMessage - ) + intent.putExtra(ReportingConstants.ERROR_REPORT_RES_ID, errorMessage) intent.putExtra(ReportingConstants.ERROR_REPORT_CODE_EXTRA, ErrorCodes.API_EXCEPTION.code) intent.putExtra(ReportingConstants.ERROR_REPORT_API_EXCEPTION_CODE, this.statusCode) } @@ -72,12 +72,3 @@ fun Throwable.report( intent.putExtra(ReportingConstants.ERROR_REPORT_STACK_EXTRA, stackExtra) LocalBroadcastManager.getInstance(context).sendBroadcast(intent) } - -fun reportGeneric( - stackString: String -) { - val intent = Intent(ReportingConstants.ERROR_REPORT_LOCAL_BROADCAST_CHANNEL) - intent.putExtra("category", ExceptionCategory.INTERNAL.name) - intent.putExtra("stack", stackString) - LocalBroadcastManager.getInstance(CoronaWarnApplication.getAppContext()).sendBroadcast(intent) -} diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/exception/reporting/ReportingConstants.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/exception/reporting/ReportingConstants.kt index 16e021b5c..19475b1d6 100644 --- a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/exception/reporting/ReportingConstants.kt +++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/exception/reporting/ReportingConstants.kt @@ -5,6 +5,7 @@ object ReportingConstants { const val ERROR_REPORT_CATEGORY_EXTRA = "category" const val ERROR_REPORT_PREFIX_EXTRA = "prefix" const val ERROR_REPORT_SUFFIX_EXTRA = "suffix" + const val ERROR_REPORT_TITLE_EXTRA = "title" const val ERROR_REPORT_MESSAGE_EXTRA = "message" const val ERROR_REPORT_STACK_EXTRA = "stack" const val ERROR_REPORT_CODE_EXTRA = "code" diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/nearby/modules/diagnosiskeyprovider/DefaultDiagnosisKeyProvider.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/nearby/modules/diagnosiskeyprovider/DefaultDiagnosisKeyProvider.kt index bca8dfdd4..59114d58d 100644 --- a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/nearby/modules/diagnosiskeyprovider/DefaultDiagnosisKeyProvider.kt +++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/nearby/modules/diagnosiskeyprovider/DefaultDiagnosisKeyProvider.kt @@ -2,8 +2,10 @@ package de.rki.coronawarnapp.nearby.modules.diagnosiskeyprovider +import com.google.android.gms.common.api.ApiException import com.google.android.gms.nearby.exposurenotification.ExposureConfiguration import com.google.android.gms.nearby.exposurenotification.ExposureNotificationClient +import de.rki.coronawarnapp.exception.reporting.ReportingConstants import de.rki.coronawarnapp.util.GoogleAPIVersion import timber.log.Timber import java.io.File @@ -101,6 +103,14 @@ class DefaultDiagnosisKeyProvider @Inject constructor( enfClient .provideDiagnosisKeys(keyFiles.toList(), configuration, token) .addOnSuccessListener { cont.resume(it) } - .addOnFailureListener { cont.resumeWithException(it) } + .addOnFailureListener { + val wrappedException = when { + it is ApiException && it.statusCode == ReportingConstants.STATUS_CODE_REACHED_REQUEST_LIMIT -> { + QuotaExceededException(cause = it) + } + else -> it + } + cont.resumeWithException(wrappedException) + } } } diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/nearby/modules/diagnosiskeyprovider/QuotaExceededException.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/nearby/modules/diagnosiskeyprovider/QuotaExceededException.kt new file mode 100644 index 000000000..3a8f85a4a --- /dev/null +++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/nearby/modules/diagnosiskeyprovider/QuotaExceededException.kt @@ -0,0 +1,16 @@ +package de.rki.coronawarnapp.nearby.modules.diagnosiskeyprovider + +import android.content.Context +import de.rki.coronawarnapp.R +import de.rki.coronawarnapp.util.HasHumanReadableError +import de.rki.coronawarnapp.util.HumanReadableError + +class QuotaExceededException( + cause: Throwable +) : IllegalStateException("Quota limit exceeded.", cause), HasHumanReadableError { + + override fun toHumanReadableError(context: Context): HumanReadableError = HumanReadableError( + title = context.getString(R.string.errors_risk_detection_limit_reached_title), + description = context.getString(R.string.errors_risk_detection_limit_reached_description) + ) +} diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/storage/InsufficientStorageException.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/storage/InsufficientStorageException.kt index bb38a5844..b2203bc07 100644 --- a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/storage/InsufficientStorageException.kt +++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/storage/InsufficientStorageException.kt @@ -2,19 +2,23 @@ package de.rki.coronawarnapp.storage import android.content.Context import android.text.format.Formatter -import de.rki.coronawarnapp.util.FormattedError +import de.rki.coronawarnapp.util.HasHumanReadableError +import de.rki.coronawarnapp.util.HumanReadableError import java.io.IOException class InsufficientStorageException( val result: DeviceStorage.CheckResult ) : IOException( "Not enough free space: ${result.requiredBytes}B are required and only ${result.freeBytes}B are available." -), FormattedError { +), HasHumanReadableError { - override fun getFormattedError(context: Context): String { + override fun toHumanReadableError(context: Context): HumanReadableError { val formattedRequired = Formatter.formatShortFileSize(context, result.requiredBytes) val formattedFree = Formatter.formatShortFileSize(context, result.freeBytes) // TODO Replace with localized message when the exception is logged via new error tracking. - return "Not enough free space: $formattedRequired are required and only $formattedFree are available." + return HumanReadableError( + description = "Not enough free space: $formattedRequired are required " + + "and only $formattedFree are available." + ) } } diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/tracing/card/TracingCardState.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/tracing/card/TracingCardState.kt index 56a85ecc4..4a4fbf237 100644 --- a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/tracing/card/TracingCardState.kt +++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/tracing/card/TracingCardState.kt @@ -224,23 +224,6 @@ data class TracingCardState( } } - /** - * Formats the risk card text display of time when diagnosis keys will be updated - * from server again when applicable - */ - fun getNextUpdate(c: Context): String = if (!isBackgroundJobEnabled) { - "" - } else { - when (riskLevelScore) { - RiskLevelConstants.UNKNOWN_RISK_INITIAL, - RiskLevelConstants.LOW_LEVEL_RISK, - RiskLevelConstants.INCREASED_RISK -> c.getString( - R.string.risk_card_body_next_update - ) - else -> "" - } - } - /** * Formats the risk card divider color depending on risk level * This special handling is required due to light / dark mode differences and switches diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/util/DialogHelper.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/util/DialogHelper.kt index e7a295a16..48bb77b8d 100644 --- a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/util/DialogHelper.kt +++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/util/DialogHelper.kt @@ -18,6 +18,7 @@ object DialogHelper { val positiveButton: String, val negativeButton: String? = null, val cancelable: Boolean? = true, + val isTextSelectable: Boolean = false, val positiveButtonFunction: () -> Unit? = {}, val negativeButtonFunction: () -> Unit? = {} ) { @@ -31,14 +32,14 @@ object DialogHelper { positiveButtonFunction: () -> Unit? = {}, negativeButtonFunction: () -> Unit? = {} ) : this( - context, - context.resources.getString(title), - context.resources.getString(message), - context.resources.getString(positiveButton), - negativeButton?.let { context.resources.getString(it) }, - cancelable, - positiveButtonFunction, - negativeButtonFunction + context = context, + title = context.resources.getString(title), + message = context.resources.getString(message), + positiveButton = context.resources.getString(positiveButton), + negativeButton = negativeButton?.let { context.resources.getString(it) }, + cancelable = cancelable, + positiveButtonFunction = positiveButtonFunction, + negativeButtonFunction = negativeButtonFunction ) constructor( @@ -51,21 +52,25 @@ object DialogHelper { positiveButtonFunction: () -> Unit? = {}, negativeButtonFunction: () -> Unit? = {} ) : this( - context, - context.resources.getString(title), - message, - context.resources.getString(positiveButton), - negativeButton?.let { context.resources.getString(it) }, - cancelable, - positiveButtonFunction, - negativeButtonFunction + context = context, + title = context.resources.getString(title), + message = message, + positiveButton = context.resources.getString(positiveButton), + negativeButton = negativeButton?.let { context.resources.getString(it) }, + cancelable = cancelable, + positiveButtonFunction = positiveButtonFunction, + negativeButtonFunction = negativeButtonFunction ) } fun showDialog( dialogInstance: DialogInstance ): AlertDialog { - val message = getMessage(dialogInstance.context, dialogInstance.message) + val message = getMessage( + dialogInstance.context, + dialogInstance.message, + dialogInstance.isTextSelectable + ) val alertDialog: AlertDialog = dialogInstance.context.let { val builder = AlertDialog.Builder(it) builder.apply { @@ -91,7 +96,7 @@ object DialogHelper { return alertDialog } - private fun getMessage(context: Context, message: String?): TextView { + private fun getMessage(context: Context, message: String?, isTextSelectable: Boolean): TextView { // create spannable and add links, removed stack trace links into nowhere val spannable = SpannableString(message) val httpPattern: Pattern = Pattern.compile("[a-z]+://[^ \\n]*") @@ -107,6 +112,7 @@ object DialogHelper { textView.setPadding(paddingStartEnd, paddingLeftRight, paddingStartEnd, paddingLeftRight) textView.setTextAppearance(R.style.body1) textView.setLinkTextColor(context.getColorStateList(R.color.button_primary)) + if (isTextSelectable) textView.setTextIsSelectable(true) return textView } } diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/util/FormattedError.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/util/FormattedError.kt deleted file mode 100644 index 0639465ce..000000000 --- a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/util/FormattedError.kt +++ /dev/null @@ -1,12 +0,0 @@ -package de.rki.coronawarnapp.util - -import android.content.Context - -interface FormattedError { - fun getFormattedError(context: Context): String -} - -fun Throwable.tryFormattedError(context: Context): String = when (this) { - is FormattedError -> this.getFormattedError(context) - else -> (localizedMessage ?: this.message) ?: this.toString() -} diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/util/HasHumanReadableError.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/util/HasHumanReadableError.kt new file mode 100644 index 000000000..82f66fda5 --- /dev/null +++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/util/HasHumanReadableError.kt @@ -0,0 +1,21 @@ +package de.rki.coronawarnapp.util + +import android.content.Context + +interface HasHumanReadableError { + fun toHumanReadableError(context: Context): HumanReadableError +} + +data class HumanReadableError( + val title: String? = null, + val description: String +) + +fun Throwable.tryHumanReadableError(context: Context): HumanReadableError = when (this) { + is HasHumanReadableError -> this.toHumanReadableError(context) + else -> { + HumanReadableError( + description = (localizedMessage ?: this.message) ?: this.toString() + ) + } +} diff --git a/Corona-Warn-App/src/main/res/layout/include_risk_card_content.xml b/Corona-Warn-App/src/main/res/layout/include_risk_card_content.xml index bcbad4136..4d3f7ab83 100644 --- a/Corona-Warn-App/src/main/res/layout/include_risk_card_content.xml +++ b/Corona-Warn-App/src/main/res/layout/include_risk_card_content.xml @@ -229,33 +229,6 @@ app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toBottomOf="@+id/risk_card_row_saved_days" /> - <include - android:id="@+id/risk_card_next_update_divider" - gone="@{tracingCard.getNextUpdate(context).empty}" - layout="@layout/include_divider" - android:layout_width="@dimen/match_constraint" - android:layout_height="wrap_content" - android:layout_marginTop="@dimen/spacing_normal" - app:dividerColor="@{tracingCard.getStableDividerColor(context)}" - app:layout_constraintEnd_toEndOf="parent" - app:layout_constraintStart_toStartOf="parent" - app:layout_constraintTop_toBottomOf="@+id/risk_card_row_time_fetched" /> - - <TextView - android:id="@+id/risk_card_next_update_test" - style="@style/body2" - gone="@{tracingCard.getNextUpdate(context).empty}" - android:layout_width="@dimen/match_constraint" - android:layout_height="wrap_content" - android:layout_marginTop="@dimen/spacing_small" - android:text="@{tracingCard.getNextUpdate(context)}" - android:textColor="@{tracingCard.getStableTextColor(context)}" - app:layout_constraintEnd_toEndOf="parent" - app:layout_constraintStart_toStartOf="parent" - app:layout_constraintTop_toBottomOf="@+id/risk_card_next_update_divider" - tools:text="@string/risk_card_body_next_update" - tools:textColor="@color/colorStableLight" /> - <Button android:id="@+id/risk_card_button_enable_tracing" style="@style/buttonPrimary" @@ -266,7 +239,7 @@ android:text="@string/risk_details_button_enable_tracing" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintStart_toStartOf="parent" - app:layout_constraintTop_toBottomOf="@+id/risk_card_next_update_test" /> + app:layout_constraintTop_toBottomOf="@+id/risk_card_row_time_fetched" /> <Button android:id="@+id/risk_card_button_update" diff --git a/Corona-Warn-App/src/main/res/values-de/strings.xml b/Corona-Warn-App/src/main/res/values-de/strings.xml index 430476d88..8b872f6fd 100644 --- a/Corona-Warn-App/src/main/res/values-de/strings.xml +++ b/Corona-Warn-App/src/main/res/values-de/strings.xml @@ -158,8 +158,6 @@ <string name="risk_card_body_not_yet_fetched">"Begegnungen wurden noch nicht überprüft."</string> <!-- XTXT: risk card - last successful update --> <string name="risk_card_body_time_fetched">"Aktualisiert: %1$s"</string> - <!-- XTXT: risk card - next update --> - <string name="risk_card_body_next_update">"Tägliche Aktualisierung"</string> <!-- XTXT: risk card - hint to open the app daily --> <string name="risk_card_body_open_daily">"Hinweis: Bitte öffnen Sie die App täglich, um den Risikostatus zu aktualisieren."</string> <!-- XBUT: risk card - update risk --> @@ -1213,7 +1211,10 @@ <string name="errors_google_update_needed">"Ihre Corona-Warn-App ist korrekt installiert. Leider fehlt dem Betriebssystem Ihres Smartphones der Dienst „COVID-19-Benachrichtigungen“ und Sie können die Corona-Warn-App nicht nutzen. Weitere Informationen finden Sie in unseren FAQ: https://www.coronawarn.app/de/faq/"</string> <!-- XTXT: error dialog - either Google API Error (10) or reached request limit per day --> <string name="errors_google_api_error">"Ihre Corona-Warn-App läuft fehlerfrei. Leider können Sie Ihren Risikostatus im Moment nicht aktualisieren. Ihre Risiko-Ermittlung ist weiterhin aktiv und funktioniert. Weitere Informationen finden Sie in unseren FAQ: https://www.coronawarn.app/de/faq/"</string> - + <!-- XTXT: error dialog - Error title when the provideDiagnosisKeys quota limit was reached. --> + <string name="errors_risk_detection_limit_reached_title">"Limit bereits erreicht"</string> + <!-- XTXT: error dialog - Error description when the provideDiagnosisKeys quota limit was reached. --> + <string name="errors_risk_detection_limit_reached_description">"Heute sind keine weiteren Risiko-Überprüfungen möglich, weil das von Ihrem Betriebssystem festgelegte Limit von Risiko-Überprüfungen pro Tag bereits erreicht ist. Bitte überprüfen Sie Ihren Risikostatus morgen wieder."</string> <!-- #################################### Generic Error Messages ###################################### --> diff --git a/Corona-Warn-App/src/main/res/values/strings.xml b/Corona-Warn-App/src/main/res/values/strings.xml index d135fef16..266628ab2 100644 --- a/Corona-Warn-App/src/main/res/values/strings.xml +++ b/Corona-Warn-App/src/main/res/values/strings.xml @@ -1218,6 +1218,10 @@ <string name="errors_google_update_needed">"Your Corona-Warn-App is correctly installed, but the \"COVID-19 Exposure Notifications System\" is not available on your smartphone\'s operating system. This means that you cannot use the Corona-Warn-App. For further information, please see our FAQ page: https://www.coronawarn.app/en/faq/"</string> <!-- XTXT: error dialog - either Google API Error (10) or reached request limit per day --> <string name="errors_google_api_error">"The Corona-Warn-App is running correctly, but we cannot update your current risk status. Exposure logging remains active and is working correctly. For further information, please see our FAQ page: https://www.coronawarn.app/en/faq/"</string> + <!-- XTXT: error dialog - Error title when the provideDiagnosisKeys quota limit was reached. --> + <string name="errors_risk_detection_limit_reached_title" /> + <!-- XTXT: error dialog - Error description when the provideDiagnosisKeys quota limit was reached. --> + <string name="errors_risk_detection_limit_reached_description" /> <!-- #################################### Generic Error Messages diff --git a/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/ui/tracing/card/TracingCardStateTest.kt b/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/ui/tracing/card/TracingCardStateTest.kt index a6d955946..be649ea37 100644 --- a/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/ui/tracing/card/TracingCardStateTest.kt +++ b/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/ui/tracing/card/TracingCardStateTest.kt @@ -636,82 +636,6 @@ class TracingCardStateTest : BaseTest() { } } - @Test - fun `text for next update time`() { - createInstance( - riskLevel = INCREASED_RISK, - isBackgroundJobEnabled = false - ).apply { - getNextUpdate(context) shouldBe "" - } - - createInstance( - riskLevel = UNKNOWN_RISK_OUTDATED_RESULTS, - isBackgroundJobEnabled = false - ).apply { - getNextUpdate(context) shouldBe "" - } - - createInstance( - riskLevel = NO_CALCULATION_POSSIBLE_TRACING_OFF, - isBackgroundJobEnabled = false - ).apply { - getNextUpdate(context) shouldBe "" - } - - createInstance( - riskLevel = LOW_LEVEL_RISK, - isBackgroundJobEnabled = false - ).apply { - getNextUpdate(context) shouldBe "" - } - - createInstance( - riskLevel = UNKNOWN_RISK_INITIAL, - isBackgroundJobEnabled = false - ).apply { - getNextUpdate(context) shouldBe "" - } - - createInstance( - riskLevel = INCREASED_RISK, - isBackgroundJobEnabled = true - ).apply { - getNextUpdate(context) - verify { context.getString(R.string.risk_card_body_next_update) } - } - - createInstance( - riskLevel = UNKNOWN_RISK_OUTDATED_RESULTS, - isBackgroundJobEnabled = true - ).apply { - getNextUpdate(context) shouldBe "" - } - - createInstance( - riskLevel = NO_CALCULATION_POSSIBLE_TRACING_OFF, - isBackgroundJobEnabled = true - ).apply { - getNextUpdate(context) shouldBe "" - } - - createInstance( - riskLevel = LOW_LEVEL_RISK, - isBackgroundJobEnabled = true - ).apply { - getNextUpdate(context) - verify { context.getString(R.string.risk_card_body_next_update) } - } - - createInstance( - riskLevel = UNKNOWN_RISK_INITIAL, - isBackgroundJobEnabled = true - ).apply { - getNextUpdate(context) - verify { context.getString(R.string.risk_card_body_next_update) } - } - } - @Test fun `task divider is formatted according to riskLevel`() { createInstance(riskLevel = INCREASED_RISK).apply { -- GitLab