From c6014d2315d9f23f5c981050c0f9adc67a3a6ae3 Mon Sep 17 00:00:00 2001 From: Matthias Urhahn <darken@darken.eu> Date: Thu, 17 Sep 2020 14:46:46 +0200 Subject: [PATCH] 1.3.1 into 1.4.0 (#1177) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * New Scan Confirmation Texts Change (EXPOSUREAPP-2427) (#1097) Co-authored-by: harambasicluka <64483219+harambasicluka@users.noreply.github.com> Co-authored-by: Jakob Möller <jakob.moeller@sap.com> * New Strings for Risikobegegnung mit niedrigem Risiko (EXPOSUREAPP-2462) (#1106) * + new strings * let the app not crash on other languages than DE * values for lint and tests * made bad test a comment * removed unnecessary strings * more string fixes Co-authored-by: Jakob Möller <jakob.moeller@sap.com> Co-authored-by: Luka Harambasic <luka.harambasic@sap.com> * Remove Cache Clearing to reduce CDN load on failing devices (EXPOSUREAPP-2405) (#1108) * Remove Cache Clearing to reduce CDN load on failing devices. This ideally needs to be accompanied by a way to clear the cache manually and a way to identify more root causes of Transaction Failures. Signed-off-by: d067928 <jakob.moeller@sap.com> * Remove Files that failed for Key Retrieval Only Remove Files from Cache that failed to download, instead of every file. This is accompanied ideally by no rollback in the Key Retrieval. We only delete the cache ref, the file will not be deleted as it is considered not present Signed-off-by: d067928 <jakob.moeller@sap.com> * Introduce dedicated QuotaCalculator for Unit Testing Signed-off-by: d067928 <jakob.moeller@sap.com> * Refactor QuotaCalculator for LocalData Property Access and Write Tests Signed-off-by: d067928 <jakob.moeller@sap.com> * Use Instant on the Device Read since this is not timezone specific Signed-off-by: d067928 <jakob.moeller@sap.com> * Add specific state for the quota calculation and dedicated rollback Signed-off-by: d067928 <jakob.moeller@sap.com> * PR Comments Signed-off-by: d067928 <jakob.moeller@sap.com> * Feature: Update low risk string (EXPOSUREAPP-1971) (#1125) * Improve Explanation for "Risikobegegnung mit niedrigem Risiko" (EXPOSUREAPP-1971) (#1112) * Adapt QuotaCalculatorTest to old JUnit4 API Signed-off-by: d067928 <jakob.moeller@sap.com> * [INTERNAL] Translation delivery: commit by LX Lab (#1132) Change-Id: Ib76a9ea2b03163a05dd8b6acf2179262f9bcf5bf * Removed ar & ru and updated defaults (#1133) * Throw Exception in case we have a failed entry to ensure Abortion of the Transaction (EXPOSUREAPP-2405) (#1134) * Throw Exception in case we have a failed entry to ensure Abortion of the Transaction. Signed-off-by: d067928 <jakob.moeller@sap.com> * Adjust test to not expect call to clear cache files Signed-off-by: d067928 <jakob.moeller@sap.com> * version bump to 1.3.1 * Reverted replaced wording (EXPOSUREAPP-2638) (#1153) * Fix: No exposure with low risk so far * Fixed klint issues (#1144) * restored reverted replaced wording for lint * https://github.com/corona-warn-app/cwa-app-android/pull/1153#discussion_r487801724 * fixed term * Align TestFragment Crash behavior with background transaction crash behavior. * Add logging mechanism to debug hotfix issue. * Lint Resolvement, Nav Graph Issue clean, Enable Log for deviceForTesters, Correct Quota Tests due to now lacking exception Signed-off-by: d067928 <jakob.moeller@sap.com> Co-authored-by: Philipp Woessner <64482866+pwoessner@users.noreply.github.com> Co-authored-by: Jakob Möller <jakob.moeller@sap.com> Co-authored-by: Rituraj Sambherao <54317407+ritsam@users.noreply.github.com> Co-authored-by: harambasicluka <64483219+harambasicluka@users.noreply.github.com> Co-authored-by: chris-cwa <69595386+chris-cwa@users.noreply.github.com> Co-authored-by: Luka Harambasic <luka.harambasic@sap.com> Co-authored-by: SAP LX Lab Service Account <tmsatsls+github.com_service-tip-git@sap.com> Co-authored-by: Matthias Urhahn <matthias.urhahn@sap.com> --- .../coronawarnapp/test/TestForAPIFragment.kt | 47 ++++++++++ .../test/TestRiskLevelCalculationFragment.kt | 2 +- .../res/layout/fragment_test_for_a_p_i.xml | 26 +++++- .../coronawarnapp/CoronaWarnApplication.kt | 49 ++++++----- .../util/GoogleQuotaCalculator.kt | 41 +++++++-- .../coronawarnapp/util/debug/FileLogger.kt | 40 +++++++++ .../util/debug/FileLoggerTree.kt | 86 +++++++++++++++++++ .../src/main/res/navigation/nav_graph.xml | 5 ++ .../src/main/res/values-en/strings.xml | 2 +- .../src/main/res/values-ro/strings.xml | 18 ++-- .../src/main/res/values/strings.xml | 2 +- .../util/GoogleQuotaCalculatorTest.kt | 8 +- 12 files changed, 279 insertions(+), 47 deletions(-) create mode 100644 Corona-Warn-App/src/main/java/de/rki/coronawarnapp/util/debug/FileLogger.kt create mode 100644 Corona-Warn-App/src/main/java/de/rki/coronawarnapp/util/debug/FileLoggerTree.kt diff --git a/Corona-Warn-App/src/deviceForTesters/java/de/rki/coronawarnapp/test/TestForAPIFragment.kt b/Corona-Warn-App/src/deviceForTesters/java/de/rki/coronawarnapp/test/TestForAPIFragment.kt index 748a74ba2..5c20d3a46 100644 --- a/Corona-Warn-App/src/deviceForTesters/java/de/rki/coronawarnapp/test/TestForAPIFragment.kt +++ b/Corona-Warn-App/src/deviceForTesters/java/de/rki/coronawarnapp/test/TestForAPIFragment.kt @@ -30,6 +30,7 @@ import com.google.zxing.BarcodeFormat import com.google.zxing.integration.android.IntentIntegrator import com.google.zxing.integration.android.IntentResult import com.google.zxing.qrcode.QRCodeWriter +import de.rki.coronawarnapp.CoronaWarnApplication import de.rki.coronawarnapp.R import de.rki.coronawarnapp.databinding.FragmentTestForAPIBinding import de.rki.coronawarnapp.exception.ExceptionCategory @@ -53,6 +54,7 @@ import de.rki.coronawarnapp.ui.viewmodel.TracingViewModel import de.rki.coronawarnapp.util.KeyFileHelper import kotlinx.android.synthetic.deviceForTesters.fragment_test_for_a_p_i.* import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.async import kotlinx.coroutines.launch import kotlinx.coroutines.withContext import org.joda.time.DateTime @@ -246,6 +248,51 @@ class TestForAPIFragment : Fragment(), InternalExposureNotificationPermissionHel showToast(TimeVariables.getActiveTracingDaysInRetentionPeriod().toString()) } } + + binding.testLogfileToggle.isChecked = CoronaWarnApplication.fileLogger?.isLogging ?: false + binding.testLogfileToggle.setOnClickListener { buttonView -> + CoronaWarnApplication.fileLogger?.let { + if (binding.testLogfileToggle.isChecked) { + it.start() + } else { + it.stop() + } + } + } + + binding.testLogfileShare.setOnClickListener { + CoronaWarnApplication.fileLogger?.let { + lifecycleScope.launch { + val targetPath = withContext(Dispatchers.IO) { + async { + if (!it.logFile.exists()) return@async null + + val externalPath = File( + requireContext().getExternalFilesDir(null), + "LogFile-${System.currentTimeMillis()}.log" + ) + + it.logFile.copyTo(externalPath) + + return@async externalPath + } + }.await() + if (targetPath != null) { + Toast.makeText( + requireActivity(), + "Logfile copied to $targetPath", + Toast.LENGTH_SHORT + ).show() + } else { + Toast.makeText( + requireActivity(), + "No log file available", + Toast.LENGTH_SHORT + ).show() + } + } + } + } } override fun onResume() { diff --git a/Corona-Warn-App/src/deviceForTesters/java/de/rki/coronawarnapp/test/TestRiskLevelCalculationFragment.kt b/Corona-Warn-App/src/deviceForTesters/java/de/rki/coronawarnapp/test/TestRiskLevelCalculationFragment.kt index d5de4bcac..6172b4f2f 100644 --- a/Corona-Warn-App/src/deviceForTesters/java/de/rki/coronawarnapp/test/TestRiskLevelCalculationFragment.kt +++ b/Corona-Warn-App/src/deviceForTesters/java/de/rki/coronawarnapp/test/TestRiskLevelCalculationFragment.kt @@ -155,7 +155,7 @@ class TestRiskLevelCalculationFragment : Fragment() { try { RetrieveDiagnosisKeysTransaction.start() calculateRiskLevel() - } catch (e: TransactionException) { + } catch (e: Exception) { e.report(ExceptionCategory.INTERNAL) } } diff --git a/Corona-Warn-App/src/deviceForTesters/res/layout/fragment_test_for_a_p_i.xml b/Corona-Warn-App/src/deviceForTesters/res/layout/fragment_test_for_a_p_i.xml index a90a271a9..f8b9d4a5d 100644 --- a/Corona-Warn-App/src/deviceForTesters/res/layout/fragment_test_for_a_p_i.xml +++ b/Corona-Warn-App/src/deviceForTesters/res/layout/fragment_test_for_a_p_i.xml @@ -1,5 +1,7 @@ <?xml version="1.0" encoding="utf-8"?> -<layout xmlns:android="http://schemas.android.com/apk/res/android"> +<layout xmlns:tools="http://schemas.android.com/tools" + tools:ignore="HardcodedText" + xmlns:android="http://schemas.android.com/apk/res/android"> <data> @@ -30,6 +32,7 @@ android:layout_width="match_parent" android:layout_height="wrap_content" /> + <Switch android:id="@+id/test_api_switch_last_three_hours_from_server" style="@style/body1" @@ -46,6 +49,27 @@ android:text="@string/test_api_switch_background_notifications" android:theme="@style/switchBase" /> + <LinearLayout + android:layout_width="match_parent" + android:orientation="horizontal" + android:layout_height="wrap_content"> + + <Switch + android:id="@+id/test_logfile_toggle" + style="@style/body1" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:text="Logfile enabled" + android:theme="@style/switchBase" /> + + <Button + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:id="@+id/test_logfile_share" + android:text="Share log" /> + + </LinearLayout> + <TextView android:id="@+id/label_exposure_summary" style="@style/headline6" diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/CoronaWarnApplication.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/CoronaWarnApplication.kt index 9369e2914..7e3f60900 100644 --- a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/CoronaWarnApplication.kt +++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/CoronaWarnApplication.kt @@ -27,6 +27,7 @@ import de.rki.coronawarnapp.storage.LocalData import de.rki.coronawarnapp.transaction.RetrieveDiagnosisKeysTransaction import de.rki.coronawarnapp.util.CWADebug import de.rki.coronawarnapp.util.ConnectivityHelper +import de.rki.coronawarnapp.util.debug.FileLogger import de.rki.coronawarnapp.util.di.AppInjector import de.rki.coronawarnapp.util.di.ApplicationComponent import de.rki.coronawarnapp.worker.BackgroundWorkHelper @@ -56,6 +57,7 @@ class CoronaWarnApplication : Application(), LifecycleObserver, instance.applicationContext const val TEN_MINUTE_TIMEOUT_IN_MS = 10 * 60 * 1000L + var fileLogger: FileLogger? = null } private lateinit var errorReceiver: ErrorReportReceiver @@ -88,6 +90,9 @@ class CoronaWarnApplication : Application(), LifecycleObserver, if (BuildConfig.DEBUG) { Timber.plant(Timber.DebugTree()) } + if ((BuildConfig.FLAVOR == "deviceForTesters" || BuildConfig.DEBUG)) { + fileLogger = FileLogger(this) + } // notification to test the WakeUpService from Google when the app // was force stopped @@ -99,27 +104,9 @@ class CoronaWarnApplication : Application(), LifecycleObserver, ProcessLifecycleOwner.get().lifecycleScope.launch { // we want a wakelock as the OS does not handle this for us like in the background // job execution - val wakeLock: PowerManager.WakeLock = - (getSystemService(Context.POWER_SERVICE) as PowerManager).run { - newWakeLock( - PowerManager.PARTIAL_WAKE_LOCK, - TAG + "-WAKE-" + UUID.randomUUID().toString() - ).apply { - acquire(TEN_MINUTE_TIMEOUT_IN_MS) - } - } - + val wakeLock = createWakeLock() // we keep a wifi lock to wake up the wifi connection in case the device is dozing - val wifiLock: WifiManager.WifiLock = - (getSystemService(Context.WIFI_SERVICE) as WifiManager).run { - createWifiLock( - WifiManager.WIFI_MODE_FULL_HIGH_PERF, - TAG + "-WIFI-" + UUID.randomUUID().toString() - ).apply { - acquire() - } - } - + val wifiLock = createWifiLock() try { BackgroundWorkHelper.sendDebugNotification( "Automatic mode is on", "Check if we have downloaded keys already today" @@ -146,6 +133,28 @@ class CoronaWarnApplication : Application(), LifecycleObserver, } } + private fun createWakeLock(): PowerManager.WakeLock = + (getSystemService(Context.POWER_SERVICE) as PowerManager) + .run { + newWakeLock( + PowerManager.PARTIAL_WAKE_LOCK, + TAG + "-WAKE-" + UUID.randomUUID().toString() + ).apply { + acquire(TEN_MINUTE_TIMEOUT_IN_MS) + } + } + + private fun createWifiLock(): WifiManager.WifiLock = + (getSystemService(Context.WIFI_SERVICE) as WifiManager) + .run { + createWifiLock( + WifiManager.WIFI_MODE_FULL_HIGH_PERF, + TAG + "-WIFI-" + UUID.randomUUID().toString() + ).apply { + acquire() + } + } + /** * Callback when the app is open but backgrounded */ diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/util/GoogleQuotaCalculator.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/util/GoogleQuotaCalculator.kt index e7aace190..e686eec75 100644 --- a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/util/GoogleQuotaCalculator.kt +++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/util/GoogleQuotaCalculator.kt @@ -6,6 +6,7 @@ import org.joda.time.DateTime import org.joda.time.DateTimeZone import org.joda.time.Duration import org.joda.time.Instant +import timber.log.Timber /** * This Calculator class takes multiple parameters to check if the Google API @@ -28,34 +29,58 @@ class GoogleQuotaCalculator( override var hasExceededQuota: Boolean = false override fun calculateQuota(): Boolean { - if (Instant.now().isAfter(LocalData.nextTimeRateLimitingUnlocks)) { + val oldQuota = LocalData.googleAPIProvideDiagnosisKeysCallCount + var currentQuota = oldQuota + + val now = Instant.now() + val nextUnlock = LocalData.nextTimeRateLimitingUnlocks + + Timber.v( + "calculateQuota() start! (currentQuota=%s, timeNow=%s, timeReset=%s)", + oldQuota, now, nextUnlock + ) + if (now.isAfter(nextUnlock)) { LocalData.nextTimeRateLimitingUnlocks = DateTime .now(quotaTimeZone) .withChronology(quotaChronology) .plus(quotaResetPeriod) .withTimeAtStartOfDay() .toInstant() - LocalData.googleAPIProvideDiagnosisKeysCallCount = 0 + Timber.d("calculateQuota() quota reset to 0.") + currentQuota = 0 + } else { + Timber.v("calculateQuota() can't be reset yet.") } - if (LocalData.googleAPIProvideDiagnosisKeysCallCount <= quotaLimit) { - LocalData.googleAPIProvideDiagnosisKeysCallCount += incrementByAmount + if (currentQuota <= quotaLimit) { + currentQuota += incrementByAmount } - hasExceededQuota = LocalData.googleAPIProvideDiagnosisKeysCallCount > quotaLimit + if (currentQuota != oldQuota) { + LocalData.googleAPIProvideDiagnosisKeysCallCount = currentQuota + } - return hasExceededQuota + return (currentQuota > quotaLimit).also { + hasExceededQuota = it + Timber.v( + "calculateQuota() done! -> oldQuota=%d, currentQuotaHm=%d, quotaLimit=%d, EXCEEDED=%b", + oldQuota, currentQuota, quotaLimit, it + ) + } } override fun resetProgressTowardsQuota(newProgress: Int) { if (newProgress > quotaLimit) { - throw IllegalArgumentException("cannot reset progress to a value higher than the quota limit") + Timber.w("cannot reset progress to a value higher than the quota limit") + return } if (newProgress % incrementByAmount != 0) { - throw IllegalArgumentException("supplied progress is no multiple of $incrementByAmount") + Timber.e("supplied progress is no multiple of $incrementByAmount") + return } LocalData.googleAPIProvideDiagnosisKeysCallCount = newProgress hasExceededQuota = false + Timber.d("resetProgressTowardsQuota(newProgress=%d) done", newProgress) } override fun getProgressTowardsQuota(): Int = LocalData.googleAPIProvideDiagnosisKeysCallCount diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/util/debug/FileLogger.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/util/debug/FileLogger.kt new file mode 100644 index 000000000..eb3b29093 --- /dev/null +++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/util/debug/FileLogger.kt @@ -0,0 +1,40 @@ +package de.rki.coronawarnapp.util.debug + +import android.content.Context +import timber.log.Timber +import java.io.File + +class FileLogger constructor(private val context: Context) { + + val logFile = File(context.cacheDir, "FileLoggerTree.log") + val triggerFile = File(context.filesDir, "FileLoggerTree.trigger") + private var loggerTree: FileLoggerTree? = null + + val isLogging: Boolean + get() = loggerTree != null + + init { + if (triggerFile.exists()) { + start() + } + } + + fun start() { + if (loggerTree != null) return + + loggerTree = FileLoggerTree(logFile).also { + Timber.plant(it) + it.start() + triggerFile.createNewFile() + } + } + + fun stop() { + loggerTree?.let { + it.stop() + logFile.delete() + triggerFile.delete() + loggerTree = null + } + } +} diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/util/debug/FileLoggerTree.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/util/debug/FileLoggerTree.kt new file mode 100644 index 000000000..84bd21ad6 --- /dev/null +++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/util/debug/FileLoggerTree.kt @@ -0,0 +1,86 @@ +package de.rki.coronawarnapp.util.debug + +import android.annotation.SuppressLint +import android.util.Log +import timber.log.Timber +import java.io.File +import java.io.FileOutputStream +import java.io.IOException +import java.io.OutputStreamWriter + +@SuppressLint("LogNotTimber") +class FileLoggerTree(private val logFile: File) : Timber.DebugTree() { + private var logWriter: OutputStreamWriter? = null + + @SuppressLint("SetWorldReadable") + @Synchronized + fun start() { + if (logWriter != null) return + + logFile.parentFile.mkdirs() + if (logFile.createNewFile()) { + Log.i(TAG, "File logger writing to " + logFile.path) + } + if (logFile.setReadable(true, false)) { + Log.i(TAG, "Debug run log read permission set") + } + + try { + logWriter = OutputStreamWriter(FileOutputStream(logFile, true)) + logWriter!!.write("=== BEGIN ===\n") + logWriter!!.write("Logfile: $logFile\n") + logWriter!!.flush() + Log.i(TAG, "File logger started.") + } catch (e: IOException) { + e.printStackTrace() + + logFile.delete() + if (logWriter != null) logWriter!!.close() + } + } + + @Synchronized + fun stop() { + logWriter?.let { + logWriter = null + try { + it.write("=== END ===\n") + it.close() + } catch (ignore: IOException) { + } + Log.i(TAG, "File logger stopped.") + } + } + + override fun log(priority: Int, tag: String?, message: String, t: Throwable?) { + logWriter?.let { + try { + it.write("${System.currentTimeMillis()} ${priorityToString(priority)}/$tag: $message\n") + it.flush() + } catch (e: IOException) { + Timber.tag(TAG).e(e) + try { + it.close() + } catch (ignore: Exception) { + } + logWriter = null + } + } + } + + override fun toString(): String { + return "FileLoggerTree(file=$logFile)" + } + + companion object { + private const val TAG = "FileLoggerTree" + private fun priorityToString(priority: Int): String = when (priority) { + Log.ERROR -> "E" + Log.WARN -> "W" + Log.INFO -> "I" + Log.DEBUG -> "D" + Log.VERBOSE -> "V" + else -> priority.toString() + } + } +} diff --git a/Corona-Warn-App/src/main/res/navigation/nav_graph.xml b/Corona-Warn-App/src/main/res/navigation/nav_graph.xml index 3b45032bb..a79c1468e 100644 --- a/Corona-Warn-App/src/main/res/navigation/nav_graph.xml +++ b/Corona-Warn-App/src/main/res/navigation/nav_graph.xml @@ -236,6 +236,11 @@ android:name="de.rki.coronawarnapp.ui.submission.SubmissionTanFragment" android:label="fragment_submission_tan" tools:layout="@layout/fragment_submission_tan"> + <action + android:id="@+id/action_submissionTanFragment_to_submissionDispatcherFragment" + app:destination="@id/submissionDispatcherFragment" + app:popUpTo="@id/submissionDispatcherFragment" + app:popUpToInclusive="true" /> <action android:id="@+id/action_submissionTanFragment_to_submissionResultFragment" app:destination="@id/submissionResultFragment" diff --git a/Corona-Warn-App/src/main/res/values-en/strings.xml b/Corona-Warn-App/src/main/res/values-en/strings.xml index 1cea318c8..7b72be394 100644 --- a/Corona-Warn-App/src/main/res/values-en/strings.xml +++ b/Corona-Warn-App/src/main/res/values-en/strings.xml @@ -276,7 +276,7 @@ <!-- XHED: App overview subtitle for glossary contact --> <string name="main_overview_subtitle_glossary_contact">"Exposures"</string> <!-- YTXT: App overview body for glossary contact --> - <string name="main_overview_body_glossary_contact">"Encounters over an extended period and in close proximity to a person diagnosed with COVID-19."</string> + <string name="main_overview_body_glossary_contact">"Encounters over a longer duration and close proximity to people diagnosed with COVID-19."</string> <!-- XHED: App overview subtitle for glossary notifications --> <string name="main_overview_subtitle_glossary_notification">"Exposure Notification"</string> <!-- YTXT: App overview body for glossary notifications --> diff --git a/Corona-Warn-App/src/main/res/values-ro/strings.xml b/Corona-Warn-App/src/main/res/values-ro/strings.xml index a38d1fc6e..e36080142 100644 --- a/Corona-Warn-App/src/main/res/values-ro/strings.xml +++ b/Corona-Warn-App/src/main/res/values-ro/strings.xml @@ -276,7 +276,7 @@ <!-- XHED: App overview subtitle for glossary contact --> <string name="main_overview_subtitle_glossary_contact">"Expuneri"</string> <!-- YTXT: App overview body for glossary contact --> - <string name="main_overview_body_glossary_contact">"Întâlniri de o durată lungă și în strânsă proximitate cu o persoană diagnosticată cu COVID-19."</string> + <string name="main_overview_body_glossary_contact">"Întâlniri de o durată mai lungă și în strânsă proximitate cu persoane diagnosticate cu COVID-19."</string> <!-- XHED: App overview subtitle for glossary notifications --> <string name="main_overview_subtitle_glossary_notification">"Notificarea de expunere"</string> <!-- YTXT: App overview body for glossary notifications --> @@ -441,7 +441,7 @@ <!-- YMSI: onboarding(tracing) - dialog about background jobs --> <string name="onboarding_background_fetch_dialog_body">"Ați dezactivat actualizările în fundal pentru aplicația Corona-Warn. Activați actualizările în fundal pentru a utiliza înregistrarea automată în jurnal a expunerilor. Dacă nu activați actualizările în fundal, puteți porni doar manual din aplicație înregistrarea în jurnal a expunerilor. Puteți activa actualizările în fundal pentru aplicație din setările dispozitivului dvs."</string> <!-- XBUT: onboarding(tracing) - dialog about background jobs, open device settings --> - <string name="onboarding_background_fetch_dialog_button_positive">"Deschideți setările dispozitivului"</string> + <string name="onboarding_background_fetch_dialog_button_positive">"Deschideți Setările dispozitivului"</string> <!-- XBUT: onboarding(tracing) - dialog about background jobs, continue in app --> <string name="onboarding_background_fetch_dialog_button_negative">"Porniți manual înregistrarea în jurnal a expunerilor"</string> <!-- XACT: onboarding(tracing) - dialog about energy optimized header text --> @@ -465,7 +465,7 @@ <!-- XTXT: onboarding(tracing) - location explanation for bluetooth body text --> <string name="onboarding_tracing_location_body">"Locația dvs. nu poate fi accesată. Google și/sau Android necesită acces la locația dispozitivului dvs. pentru a utiliza Bluetooth-ul."</string> <!-- XBUT: onboarding(tracing) - button enable tracing --> - <string name="onboarding_tracing_location_button">"Deschideți setările dispozitivului"</string> + <string name="onboarding_tracing_location_button">"Deschideți Setările dispozitivului"</string> <!-- XACT: Onboarding (test) page title --> <string name="onboarding_test_accessibility_title">"Pagina de înregistrare 4 din 5: Dacă sunteți diagnosticat cu COVID-19…"</string> <!-- XHED: onboarding(test) - about positive tests --> @@ -535,21 +535,21 @@ <!--XHED : settings(tracing) - headline on card about the current status and what to do --> <string name="settings_tracing_status_bluetooth_headline">"Activați Bluetooth-ul"</string> <!-- XTXT: settings(tracing) - explains user what to do on card if bluetooth is disabled --> - <string name="settings_tracing_status_bluetooth_body">"Bluetooth-ul trebuie să fie activat pentru ca înregistrarea în jurnal a expunerilor să funcționeze. Activați Bluetooth-ul în setările dispozitivului."</string> + <string name="settings_tracing_status_bluetooth_body">"Bluetooth-ul trebuie să fie pornit pentru ca înregistrarea în jurnal a expunerilor să funcționeze. Porniți Bluetooth-ul în setările dispozitivului."</string> <!-- XBUT: settings(tracing) - go to operating system settings button on card --> - <string name="settings_tracing_status_bluetooth_button">"Deschideți setările dispozitivului"</string> + <string name="settings_tracing_status_bluetooth_button">"Deschideți Setările dispozitivului"</string> <!--XHED : settings(tracing) - headline on card about the current status and what to do --> <string name="settings_tracing_status_location_headline">"Permiteți accesul la locație"</string> <!-- XTXT: settings(tracing) - explains user what to do on card if location is disabled --> <string name="settings_tracing_status_location_body">"Locația dvs. nu poate fi accesată. Google și/sau Android necesită acces la locația dispozitivului dvs. pentru a utiliza Bluetooth-ul."</string> <!-- XBUT: settings(tracing) - go to operating system settings button on card - location --> - <string name="settings_tracing_status_location_button">"Deschideți setările dispozitivului"</string> + <string name="settings_tracing_status_location_button">"Deschideți Setările dispozitivului"</string> <!--XHED : settings(tracing) - headline on card about the current status and what to do --> <string name="settings_tracing_status_connection_headline">"Deschideți conexiunea la internet"</string> <!-- XTXT: settings(tracing) - explains user what to do on card if connection is disabled --> <string name="settings_tracing_status_connection_body">"Înregistrarea în jurnal a expunerilor necesită conexiunea la internet pentru a calcula expunerile. Porniți rețeaua Wi-Fi sau datele mobile din setările dispozitivului dvs."</string> <!-- XBUT: settings(tracing) - go to operating system settings button on card --> - <string name="settings_tracing_status_connection_button">"Deschideți setările dispozitivului"</string> + <string name="settings_tracing_status_connection_button">"Deschideți Setările dispozitivului"</string> <!-- XTXT: settings(tracing) - explains the circle progress indicator to the right with the current value --> <plurals name="settings_tracing_status_body_active"> <item quantity="one">"Înregistrarea în jurnal a expunerilor a fost activă o zi.\nO verificare a expunerii poate fi de încredere doar dacă înregistrarea în jurnal a expunerilor este activată permanent."</item> @@ -591,7 +591,7 @@ <!-- XTXT: settings(notification) - next to a switch --> <string name="settings_notifications_subtitle_update_test">"Starea testului COVID-19"</string> <!-- XBUT: settings(notification) - go to operating settings --> - <string name="settings_notifications_button_open_settings">"Deschideți setările dispozitivului"</string> + <string name="settings_notifications_button_open_settings">"Deschideți Setările dispozitivului"</string> <!-- XACT: main (overview) - illustraction description, explanation image, displays notificatin status, active --> <string name="settings_notifications_illustration_description_active">"O femeie primește o notificare de la Corona-Warn-App."</string> <!-- XACT: main (overview) - illustraction description, explanation image, displays notificatin status, inactive --> @@ -635,7 +635,7 @@ <!-- XTXT: settings(background priority) - explains user what to do on card if background priority is enabled --> <string name="settings_background_priority_card_body">"Dacă doriți să dezactivați activitatea în fundal cu prioritate, vă rugăm să faceți acest lucru din setările dispozitivului."</string> <!-- XBUT: settings(background priority) - go to operating system settings button on card --> - <string name="settings_background_priority_card_button">"Deschideți setările dispozitivului"</string> + <string name="settings_background_priority_card_button">"Deschideți Setările dispozitivului"</string> <!-- XHED : settings(background priority) - headline on card about the current status and what to do --> <string name="settings_background_priority_card_headline">"Dezactivați activitatea în fundal cu prioritate"</string> diff --git a/Corona-Warn-App/src/main/res/values/strings.xml b/Corona-Warn-App/src/main/res/values/strings.xml index b168dfbe7..cbbf23556 100644 --- a/Corona-Warn-App/src/main/res/values/strings.xml +++ b/Corona-Warn-App/src/main/res/values/strings.xml @@ -278,7 +278,7 @@ <!-- XHED: App overview subtitle for glossary contact --> <string name="main_overview_subtitle_glossary_contact">"Exposures"</string> <!-- YTXT: App overview body for glossary contact --> - <string name="main_overview_body_glossary_contact">"Encounters over an extended period and in close proximity to a person diagnosed with COVID-19."</string> + <string name="main_overview_body_glossary_contact">"Encounters over a longer duration and close proximity to people diagnosed with COVID-19."</string> <!-- XHED: App overview subtitle for glossary notifications --> <string name="main_overview_subtitle_glossary_notification">"Exposure Notification"</string> <!-- YTXT: App overview body for glossary notifications --> diff --git a/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/util/GoogleQuotaCalculatorTest.kt b/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/util/GoogleQuotaCalculatorTest.kt index 995ed6751..693e31871 100644 --- a/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/util/GoogleQuotaCalculatorTest.kt +++ b/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/util/GoogleQuotaCalculatorTest.kt @@ -148,9 +148,7 @@ internal class GoogleQuotaCalculatorTest : BaseTest() { } } - assertThrows<IllegalArgumentException> { - classUnderTest.resetProgressTowardsQuota(defaultIncrementByAmountInTest + 1) - } + classUnderTest.resetProgressTowardsQuota(defaultIncrementByAmountInTest + 1) } @Test @@ -207,9 +205,7 @@ internal class GoogleQuotaCalculatorTest : BaseTest() { } val newProgressAfterReset = defaultQuotaLimitInTest + 1 - assertThrows<IllegalArgumentException> { - classUnderTest.resetProgressTowardsQuota(newProgressAfterReset) - } + classUnderTest.resetProgressTowardsQuota(newProgressAfterReset) assertEquals(true, classUnderTest.hasExceededQuota) assertEquals( (progressBeforeReset -- GitLab