Skip to content
Snippets Groups Projects
Commit 43ca7912 authored by chris-cwa's avatar chris-cwa
Browse files

Merge remote-tracking branch 'origin/release/1.8.x' into feature/3456-enfv2-main-branch

parents fdfe57c1 6736566f
No related branches found
No related tags found
No related merge requests found
Showing
with 53 additions and 35 deletions
...@@ -91,7 +91,7 @@ android { ...@@ -91,7 +91,7 @@ android {
signingProps.load(new FileInputStream(signingPropFile)) signingProps.load(new FileInputStream(signingPropFile))
signingConfigs { signingConfigs {
deviceRelease { deviceRelease {
if(signingProps['deviceRelease.storePath'] != null) { if (signingProps['deviceRelease.storePath'] != null) {
storeFile file(signingProps['deviceRelease.storePath']) storeFile file(signingProps['deviceRelease.storePath'])
keyAlias signingProps['deviceRelease.keyAlias'] keyAlias signingProps['deviceRelease.keyAlias']
storePassword signingProps['deviceRelease.storePassword'] storePassword signingProps['deviceRelease.storePassword']
...@@ -99,7 +99,7 @@ android { ...@@ -99,7 +99,7 @@ android {
} }
} }
deviceForTestersRelease { deviceForTestersRelease {
if(signingProps['deviceForTestersRelease.storePath'] != null) { if (signingProps['deviceForTestersRelease.storePath'] != null) {
storeFile file(signingProps['deviceForTestersRelease.storePath']) storeFile file(signingProps['deviceForTestersRelease.storePath'])
keyAlias signingProps['deviceForTestersRelease.keyAlias'] keyAlias signingProps['deviceForTestersRelease.keyAlias']
storePassword signingProps['deviceForTestersRelease.storePassword'] storePassword signingProps['deviceForTestersRelease.storePassword']
...@@ -163,6 +163,12 @@ android { ...@@ -163,6 +163,12 @@ android {
} }
println("deviceForTesters adjusted versionName: $adjustedVersionName") println("deviceForTesters adjusted versionName: $adjustedVersionName")
} }
variant.outputs.each { output ->
def apkName = "Corona-Warn-App-${output.versionNameOverride}-${flavor.name}-${variant.buildType.name}.apk"
println("APK Name: $apkName")
output.outputFileName = apkName
}
} }
buildFeatures { buildFeatures {
......
...@@ -3,11 +3,13 @@ package de.rki.coronawarnapp.test.api.ui ...@@ -3,11 +3,13 @@ package de.rki.coronawarnapp.test.api.ui
import de.rki.coronawarnapp.util.CWADebug import de.rki.coronawarnapp.util.CWADebug
data class LoggerState( data class LoggerState(
val isLogging: Boolean val isLogging: Boolean,
val logsize: Long
) { ) {
companion object { companion object {
internal fun CWADebug.toLoggerState() = LoggerState( internal fun CWADebug.toLoggerState() = LoggerState(
isLogging = fileLogger?.isLogging ?: false isLogging = fileLogger?.isLogging ?: false,
logsize = fileLogger?.logFile?.length() ?: 0L
) )
} }
} }
...@@ -2,6 +2,7 @@ package de.rki.coronawarnapp.test.debugoptions.ui ...@@ -2,6 +2,7 @@ package de.rki.coronawarnapp.test.debugoptions.ui
import android.annotation.SuppressLint import android.annotation.SuppressLint
import android.os.Bundle import android.os.Bundle
import android.text.format.Formatter
import android.view.View import android.view.View
import android.widget.RadioButton import android.widget.RadioButton
import android.widget.RadioGroup import android.widget.RadioGroup
...@@ -49,6 +50,8 @@ class DebugOptionsFragment : Fragment(R.layout.fragment_test_debugoptions), Auto ...@@ -49,6 +50,8 @@ class DebugOptionsFragment : Fragment(R.layout.fragment_test_debugoptions), Auto
vm.loggerState.observe2(this) { state -> vm.loggerState.observe2(this) { state ->
binding.apply { binding.apply {
testLogfileToggle.isChecked = state.isLogging testLogfileToggle.isChecked = state.isLogging
val logSize = Formatter.formatShortFileSize(requireContext(), state.logsize)
testLogfileToggle.text = "Logfile enabled ($logSize)"
testLogfileShare.setGone(!state.isLogging) testLogfileShare.setGone(!state.isLogging)
} }
} }
......
...@@ -5,11 +5,7 @@ import androidx.lifecycle.viewModelScope ...@@ -5,11 +5,7 @@ import androidx.lifecycle.viewModelScope
import com.squareup.inject.assisted.AssistedInject import com.squareup.inject.assisted.AssistedInject
import de.rki.coronawarnapp.environment.EnvironmentSetup import de.rki.coronawarnapp.environment.EnvironmentSetup
import de.rki.coronawarnapp.environment.EnvironmentSetup.Type.Companion.toEnvironmentType import de.rki.coronawarnapp.environment.EnvironmentSetup.Type.Companion.toEnvironmentType
import de.rki.coronawarnapp.risk.RiskLevelTask
import de.rki.coronawarnapp.storage.LocalData import de.rki.coronawarnapp.storage.LocalData
import de.rki.coronawarnapp.storage.TestSettings
import de.rki.coronawarnapp.task.TaskController
import de.rki.coronawarnapp.task.common.DefaultTaskRequest
import de.rki.coronawarnapp.test.api.ui.EnvironmentState.Companion.toEnvironmentState import de.rki.coronawarnapp.test.api.ui.EnvironmentState.Companion.toEnvironmentState
import de.rki.coronawarnapp.test.api.ui.LoggerState.Companion.toLoggerState import de.rki.coronawarnapp.test.api.ui.LoggerState.Companion.toLoggerState
import de.rki.coronawarnapp.util.CWADebug import de.rki.coronawarnapp.util.CWADebug
...@@ -26,8 +22,6 @@ import java.io.File ...@@ -26,8 +22,6 @@ import java.io.File
class DebugOptionsFragmentViewModel @AssistedInject constructor( class DebugOptionsFragmentViewModel @AssistedInject constructor(
@AppContext private val context: Context, @AppContext private val context: Context,
private val envSetup: EnvironmentSetup, private val envSetup: EnvironmentSetup,
private val testSettings: TestSettings,
private val taskController: TaskController,
dispatcherProvider: DispatcherProvider dispatcherProvider: DispatcherProvider
) : CWAViewModel(dispatcherProvider = dispatcherProvider) { ) : CWAViewModel(dispatcherProvider = dispatcherProvider) {
...@@ -71,10 +65,6 @@ class DebugOptionsFragmentViewModel @AssistedInject constructor( ...@@ -71,10 +65,6 @@ class DebugOptionsFragmentViewModel @AssistedInject constructor(
loggerState.update { CWADebug.toLoggerState() } loggerState.update { CWADebug.toLoggerState() }
} }
fun calculateRiskLevelClicked() {
taskController.submit(DefaultTaskRequest(RiskLevelTask::class))
}
val logShareEvent = SingleLiveEvent<File?>() val logShareEvent = SingleLiveEvent<File?>()
fun shareLogFile() { fun shareLogFile() {
......
...@@ -47,7 +47,7 @@ class ErrorReportReceiver(private val activity: Activity) : BroadcastReceiver() ...@@ -47,7 +47,7 @@ class ErrorReportReceiver(private val activity: Activity) : BroadcastReceiver()
message += "#$apiStatusCode" message += "#$apiStatusCode"
} }
val dialogTitle = if (intent.hasExtra(ReportingConstants.ERROR_REPORT_TITLE_EXTRA)) { val dialogTitle = if (intent.getStringExtra(ReportingConstants.ERROR_REPORT_TITLE_EXTRA) != null) {
intent.getStringExtra(ReportingConstants.ERROR_REPORT_TITLE_EXTRA) intent.getStringExtra(ReportingConstants.ERROR_REPORT_TITLE_EXTRA)
} else { } else {
val errorTitle = context.resources.getString(R.string.errors_generic_details_headline) val errorTitle = context.resources.getString(R.string.errors_generic_details_headline)
......
...@@ -10,10 +10,12 @@ import de.rki.coronawarnapp.exception.ExceptionCategory ...@@ -10,10 +10,12 @@ 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_API_FAIL
import de.rki.coronawarnapp.exception.reporting.ReportingConstants.STATUS_CODE_GOOGLE_UPDATE_NEEDED 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.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.CWADebug
import de.rki.coronawarnapp.util.HasHumanReadableError
import de.rki.coronawarnapp.util.tryHumanReadableError
import java.io.PrintWriter import java.io.PrintWriter
import java.io.StringWriter import java.io.StringWriter
import java.util.concurrent.CancellationException
fun Throwable.report(exceptionCategory: ExceptionCategory) = fun Throwable.report(exceptionCategory: ExceptionCategory) =
this.report(exceptionCategory, null, null) this.report(exceptionCategory, null, null)
...@@ -25,17 +27,27 @@ fun Throwable.report( ...@@ -25,17 +27,27 @@ fun Throwable.report(
) { ) {
if (CWADebug.isAUnitTest) return if (CWADebug.isAUnitTest) return
// CancellationException is a part of normal operation. It is used to cancel a running
// asynchronous operation. It is not a failure and should not be reported as such.
if (this is CancellationException) return
reportProblem(tag = prefix, info = suffix) reportProblem(tag = prefix, info = suffix)
val context = CoronaWarnApplication.getAppContext() val context = CoronaWarnApplication.getAppContext()
val formattedError = this.tryHumanReadableError(context)
val intent = Intent(ReportingConstants.ERROR_REPORT_LOCAL_BROADCAST_CHANNEL) val intent = Intent(ReportingConstants.ERROR_REPORT_LOCAL_BROADCAST_CHANNEL)
intent.putExtra(ReportingConstants.ERROR_REPORT_CATEGORY_EXTRA, exceptionCategory.name) intent.putExtra(ReportingConstants.ERROR_REPORT_CATEGORY_EXTRA, exceptionCategory.name)
intent.putExtra(ReportingConstants.ERROR_REPORT_PREFIX_EXTRA, prefix) intent.putExtra(ReportingConstants.ERROR_REPORT_PREFIX_EXTRA, prefix)
intent.putExtra(ReportingConstants.ERROR_REPORT_SUFFIX_EXTRA, suffix) intent.putExtra(ReportingConstants.ERROR_REPORT_SUFFIX_EXTRA, suffix)
intent.putExtra(ReportingConstants.ERROR_REPORT_TITLE_EXTRA, formattedError.title)
intent.putExtra(ReportingConstants.ERROR_REPORT_MESSAGE_EXTRA, formattedError.description) if (this is HasHumanReadableError) {
val humanReadable = this.tryHumanReadableError(context)
humanReadable.title?.let {
intent.putExtra(ReportingConstants.ERROR_REPORT_TITLE_EXTRA, it)
}
intent.putExtra(ReportingConstants.ERROR_REPORT_MESSAGE_EXTRA, humanReadable.description)
} else {
intent.putExtra(ReportingConstants.ERROR_REPORT_MESSAGE_EXTRA, this.message)
}
if (this is ReportedExceptionInterface) { if (this is ReportedExceptionInterface) {
intent.putExtra(ReportingConstants.ERROR_REPORT_CODE_EXTRA, this.code) intent.putExtra(ReportingConstants.ERROR_REPORT_CODE_EXTRA, this.code)
......
...@@ -14,7 +14,7 @@ object CWADebug { ...@@ -14,7 +14,7 @@ object CWADebug {
if (BuildConfig.DEBUG) { if (BuildConfig.DEBUG) {
Timber.plant(Timber.DebugTree()) Timber.plant(Timber.DebugTree())
} }
if ((buildFlavor == BuildFlavor.DEVICE_FOR_TESTERS || BuildConfig.DEBUG)) { if (isDeviceForTestersBuild) {
fileLogger = FileLogger(application) fileLogger = FileLogger(application)
} }
} }
......
package de.rki.coronawarnapp.util.debug package de.rki.coronawarnapp.util.debug
import android.content.Context import android.content.Context
import de.rki.coronawarnapp.util.CWADebug
import timber.log.Timber import timber.log.Timber
import java.io.File import java.io.File
class FileLogger constructor(private val context: Context) { class FileLogger constructor(context: Context) {
val logFile = File(context.cacheDir, "FileLoggerTree.log") val logFile = File(context.cacheDir, "FileLoggerTree.log")
val triggerFile = File(context.filesDir, "FileLoggerTree.trigger")
private val blockerFile = File(context.filesDir, "FileLoggerTree.blocker")
private var loggerTree: FileLoggerTree? = null private var loggerTree: FileLoggerTree? = null
val isLogging: Boolean val isLogging: Boolean
get() = loggerTree != null get() = loggerTree != null
init { init {
if (triggerFile.exists()) { if (!blockerFile.exists()) {
start() start()
} }
} }
fun start() { fun start() {
if (!CWADebug.isDeviceForTestersBuild) return
if (loggerTree != null) return if (loggerTree != null) return
loggerTree = FileLoggerTree(logFile).also { loggerTree = FileLoggerTree(logFile).also {
Timber.plant(it) Timber.plant(it)
it.start() it.start()
triggerFile.createNewFile() blockerFile.delete()
} }
} }
fun stop() { fun stop() {
if (!CWADebug.isDeviceForTestersBuild) return
loggerTree?.let { loggerTree?.let {
it.stop() it.stop()
logFile.delete() logFile.delete()
triggerFile.delete() blockerFile.createNewFile()
loggerTree = null loggerTree = null
} }
} }
......
...@@ -71,7 +71,7 @@ class BaseKeyPackageSyncToolTest : BaseIOTest() { ...@@ -71,7 +71,7 @@ class BaseKeyPackageSyncToolTest : BaseIOTest() {
) )
@Test @Test
fun `key invalidation based on ETags`() = runBlockingTest { fun `revoke keys based on ETags and return true if something happened`() = runBlockingTest {
val invalidatedDay = mockk<KeyDownloadConfig.RevokedKeyPackage>().apply { val invalidatedDay = mockk<KeyDownloadConfig.RevokedKeyPackage>().apply {
every { etag } returns "etag-badday" every { etag } returns "etag-badday"
} }
...@@ -106,7 +106,12 @@ class BaseKeyPackageSyncToolTest : BaseIOTest() { ...@@ -106,7 +106,12 @@ class BaseKeyPackageSyncToolTest : BaseIOTest() {
coEvery { keyCache.getAllCachedKeys() } returns listOf(badDay, goodDay, badHour, goodHour) coEvery { keyCache.getAllCachedKeys() } returns listOf(badDay, goodDay, badHour, goodHour)
val instance = createInstance() val instance = createInstance()
instance.revokeCachedKeys(listOf(invalidatedDay, invalidatedHour)) instance.revokeCachedKeys(listOf(invalidatedDay, invalidatedHour)) shouldBe true
coEvery { keyCache.getAllCachedKeys() } returns emptyList()
instance.revokeCachedKeys(listOf(invalidatedDay, invalidatedHour)) shouldBe false
instance.revokeCachedKeys(emptyList()) shouldBe false
coVerify { keyCache.delete(listOf(badDayInfo, badHourInfo)) } coVerify { keyCache.delete(listOf(badDayInfo, badHourInfo)) }
} }
......
...@@ -3,8 +3,6 @@ package de.rki.coronawarnapp.test.debugoptions.ui ...@@ -3,8 +3,6 @@ package de.rki.coronawarnapp.test.debugoptions.ui
import android.content.Context import android.content.Context
import androidx.lifecycle.Observer import androidx.lifecycle.Observer
import de.rki.coronawarnapp.environment.EnvironmentSetup import de.rki.coronawarnapp.environment.EnvironmentSetup
import de.rki.coronawarnapp.storage.TestSettings
import de.rki.coronawarnapp.task.TaskController
import de.rki.coronawarnapp.test.api.ui.EnvironmentState import de.rki.coronawarnapp.test.api.ui.EnvironmentState
import io.kotest.matchers.shouldBe import io.kotest.matchers.shouldBe
import io.mockk.MockKAnnotations import io.mockk.MockKAnnotations
...@@ -30,8 +28,6 @@ class DebugOptionsFragmentViewModelTest : BaseTest() { ...@@ -30,8 +28,6 @@ class DebugOptionsFragmentViewModelTest : BaseTest() {
@MockK private lateinit var environmentSetup: EnvironmentSetup @MockK private lateinit var environmentSetup: EnvironmentSetup
@MockK private lateinit var context: Context @MockK private lateinit var context: Context
@MockK private lateinit var testSettings: TestSettings
@MockK lateinit var taskController: TaskController
private var currentEnvironment = EnvironmentSetup.Type.DEV private var currentEnvironment = EnvironmentSetup.Type.DEV
...@@ -61,9 +57,7 @@ class DebugOptionsFragmentViewModelTest : BaseTest() { ...@@ -61,9 +57,7 @@ class DebugOptionsFragmentViewModelTest : BaseTest() {
private fun createViewModel(): DebugOptionsFragmentViewModel = DebugOptionsFragmentViewModel( private fun createViewModel(): DebugOptionsFragmentViewModel = DebugOptionsFragmentViewModel(
context = context, context = context,
taskController = taskController,
envSetup = environmentSetup, envSetup = environmentSetup,
testSettings = testSettings,
dispatcherProvider = TestDispatcherProvider dispatcherProvider = TestDispatcherProvider
) )
......
...@@ -20,4 +20,4 @@ org.gradle.dependency.verification.console=verbose ...@@ -20,4 +20,4 @@ org.gradle.dependency.verification.console=verbose
VERSION_MAJOR=1 VERSION_MAJOR=1
VERSION_MINOR=8 VERSION_MINOR=8
VERSION_PATCH=0 VERSION_PATCH=0
VERSION_BUILD=1 VERSION_BUILD=2
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment