From 4a2b240fb161f789cd44f9096b0d8b8539d3b934 Mon Sep 17 00:00:00 2001 From: Matthias Urhahn Date: Thu, 15 Apr 2021 09:23:14 +0200 Subject: [PATCH 01/66] Version bump (2.2.0.0) --- gradle.properties | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gradle.properties b/gradle.properties index 85d77440895..6e200a00b61 100644 --- a/gradle.properties +++ b/gradle.properties @@ -18,6 +18,6 @@ org.gradle.parallel=true org.gradle.dependency.verification.console=verbose # Versioning, this is used by the app & pipelines to calculate the current versionCode & versionName VERSION_MAJOR=2 -VERSION_MINOR=1 +VERSION_MINOR=2 VERSION_PATCH=0 VERSION_BUILD=0 From aa9b1e0ab811fbf1e0be19f3d012c93b9c0919ee Mon Sep 17 00:00:00 2001 From: Juraj Kusnier Date: Mon, 19 Apr 2021 09:02:32 +0200 Subject: [PATCH 02/66] Enable logging for prod (#2842) --- .../upload/server/auth/LogUploadAuthorizer.kt | 6 ------ .../ui/information/InformationFragment.kt | 5 ----- .../java/de/rki/coronawarnapp/util/CWADebug.kt | 8 ++------ .../server/auth/LogUploadAuthorizerTest.kt | 18 ------------------ .../de/rki/coronawarnapp/util/CWADebugTest.kt | 15 +-------------- 5 files changed, 3 insertions(+), 49 deletions(-) diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/bugreporting/debuglog/upload/server/auth/LogUploadAuthorizer.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/bugreporting/debuglog/upload/server/auth/LogUploadAuthorizer.kt index 121f7f19ff5..3fc77b8a435 100644 --- a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/bugreporting/debuglog/upload/server/auth/LogUploadAuthorizer.kt +++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/bugreporting/debuglog/upload/server/auth/LogUploadAuthorizer.kt @@ -7,7 +7,6 @@ import de.rki.coronawarnapp.appconfig.ConfigData import de.rki.coronawarnapp.datadonation.safetynet.DeviceAttestation import de.rki.coronawarnapp.server.protocols.internal.ppdd.ElsOtp import de.rki.coronawarnapp.server.protocols.internal.ppdd.ElsOtpRequestAndroid -import de.rki.coronawarnapp.util.CWADebug import kotlinx.coroutines.flow.first import org.joda.time.Instant import timber.log.Timber @@ -27,11 +26,6 @@ class LogUploadAuthorizer @Inject constructor( suspend fun getAuthorizedOTP(otp: UUID = UUID.randomUUID()): LogUploadOtp { Timber.tag(TAG).d("getAuthorizedOTP() trying to authorize %s", otp) - // TODO ¯\_(ツ)_/¯ - if (!CWADebug.isDeviceForTestersBuild) { - throw UnsupportedOperationException() - } - val elsOtp = ElsOtp.ELSOneTimePassword.newBuilder().apply { setOtp(otp.toString()) }.build() diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/information/InformationFragment.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/information/InformationFragment.kt index 3e891ee68f6..c18bdc0f694 100644 --- a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/information/InformationFragment.kt +++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/information/InformationFragment.kt @@ -5,13 +5,11 @@ import android.os.Bundle import android.view.View import android.view.accessibility.AccessibilityEvent import android.view.accessibility.AccessibilityNodeInfo -import androidx.core.view.isGone import androidx.fragment.app.Fragment import com.google.android.gms.nearby.exposurenotification.ExposureNotificationClient import de.rki.coronawarnapp.R import de.rki.coronawarnapp.databinding.FragmentInformationBinding import de.rki.coronawarnapp.ui.main.MainActivity -import de.rki.coronawarnapp.util.CWADebug import de.rki.coronawarnapp.util.ExternalActionHelper import de.rki.coronawarnapp.util.di.AutoInject import de.rki.coronawarnapp.util.ui.doNavigate @@ -56,9 +54,6 @@ class InformationFragment : Fragment(R.layout.fragment_information), AutoInject setButtonOnClickListener() setAccessibilityDelegate() - - // TODO ¯\_(ツ)_/¯ - binding.informationDebuglog.rootLayout.isGone = !CWADebug.isDeviceForTestersBuild } override fun onResume() { diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/util/CWADebug.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/util/CWADebug.kt index a0085169567..7725af441c6 100644 --- a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/util/CWADebug.kt +++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/util/CWADebug.kt @@ -28,8 +28,7 @@ object CWADebug { setupExceptionHandler() debugLogger = debugLoggerFactory(application).also { - // TODO Disabled until all parties are satisfied, search for ¯\_(ツ)_/¯ - if (isDeviceForTestersBuild) it.init() + it.init() } logDeviceInfos() @@ -37,10 +36,7 @@ object CWADebug { fun initAfterInjection(component: ApplicationComponent) { Timber.v("initAfterInjection(%s)", component) - // TODO ¯\_(ツ)_/¯ - if (isDeviceForTestersBuild) { - debugLogger.setInjectionIsReady(component) - } + debugLogger.setInjectionIsReady(component) } val isLogging: Boolean diff --git a/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/bugreporting/debuglog/upload/server/auth/LogUploadAuthorizerTest.kt b/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/bugreporting/debuglog/upload/server/auth/LogUploadAuthorizerTest.kt index d04943c8dd2..b2a8b3c9fa3 100644 --- a/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/bugreporting/debuglog/upload/server/auth/LogUploadAuthorizerTest.kt +++ b/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/bugreporting/debuglog/upload/server/auth/LogUploadAuthorizerTest.kt @@ -6,8 +6,6 @@ import de.rki.coronawarnapp.appconfig.LogUploadConfig import de.rki.coronawarnapp.appconfig.SafetyNetRequirements import de.rki.coronawarnapp.datadonation.safetynet.DeviceAttestation import de.rki.coronawarnapp.server.protocols.internal.ppdd.PpacAndroid -import de.rki.coronawarnapp.util.CWADebug -import io.kotest.assertions.throwables.shouldThrow import io.kotest.matchers.shouldBe import io.mockk.MockKAnnotations import io.mockk.Runs @@ -15,7 +13,6 @@ import io.mockk.coEvery import io.mockk.every import io.mockk.impl.annotations.MockK import io.mockk.just -import io.mockk.mockkObject import io.mockk.slot import kotlinx.coroutines.flow.flowOf import kotlinx.coroutines.test.runBlockingTest @@ -49,9 +46,6 @@ class LogUploadAuthorizerTest : BaseIOTest() { fun setup() { MockKAnnotations.init(this) - mockkObject(CWADebug) - every { CWADebug.isDeviceForTestersBuild } returns true - every { configData.logUpload } returns logUploadConfig every { logUploadConfig.safetyNetRequirements } returns safetyNetRequirements @@ -88,16 +82,4 @@ class LogUploadAuthorizerTest : BaseIOTest() { attestationRequestSlot.captured.configData shouldBe configData attestationRequestSlot.captured.checkDeviceTime shouldBe false } - - @Test - fun `upload is not possible on prod builds`() = runBlockingTest { - every { CWADebug.isDeviceForTestersBuild } returns false - - val expectedOtp = UUID.fromString("15cff19f-af26-41bc-94f2-c1a65075e894") - val instance = createInstance() - - shouldThrow { - instance.getAuthorizedOTP(otp = expectedOtp) - } - } } diff --git a/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/util/CWADebugTest.kt b/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/util/CWADebugTest.kt index c29454f47f6..236128957ab 100644 --- a/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/util/CWADebugTest.kt +++ b/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/util/CWADebugTest.kt @@ -5,7 +5,6 @@ import de.rki.coronawarnapp.bugreporting.debuglog.DebugLogger import de.rki.coronawarnapp.environment.BuildConfigWrap import de.rki.coronawarnapp.util.di.ApplicationComponent import io.kotest.matchers.shouldBe -import io.mockk.Called import io.mockk.MockKAnnotations import io.mockk.Runs import io.mockk.every @@ -13,7 +12,6 @@ import io.mockk.impl.annotations.MockK import io.mockk.just import io.mockk.mockk import io.mockk.mockkObject -import io.mockk.verify import io.mockk.verifySequence import org.junit.jupiter.api.BeforeEach import org.junit.jupiter.api.Test @@ -49,18 +47,7 @@ class CWADebugTest : BaseTest() { } @Test - fun `logging is only initialized on tester builds`() { - val debugLogger: DebugLogger = mockk() - CWADebug.debugLoggerFactory = { debugLogger } - CWADebug.init(application) - CWADebug.initAfterInjection(appComponent) - verify { debugLogger wasNot Called } - } - - @Test - fun `logging is initialized on deviceForTester builds`() { - every { BuildConfigWrap.FLAVOR } returns "deviceForTesters" - + fun `logging is initialized`() { val debugLogger = mockk().apply { every { init() } just Runs every { setInjectionIsReady(appComponent) } just Runs From 54fbdadfc9a99b4c373e7d90df02d70545fc4376 Mon Sep 17 00:00:00 2001 From: Lukas Lechner Date: Tue, 20 Apr 2021 10:25:14 +0200 Subject: [PATCH 03/66] Technical support function - Add share dialog (EXPOSUREAPP-6057) (#2847) * Share error log instead of storing it locally * Remove remaining "store-locally" logic * Refactor DebugLogFragment.kt * Fix string descriptions * Fix DebugLogFragmentTest.kt * Update strings.xml Co-authored-by: harambasicluka <64483219+harambasicluka@users.noreply.github.com> --- .../bugreporting/DebugLogFragmentTest.kt | 8 +-- .../debuglog/export/SAFLogExport.kt | 62 ---------------- .../debuglog/ui/DebugLogFragment.kt | 60 ++++------------ .../debuglog/ui/DebugLogViewModel.kt | 43 ++--------- .../coronawarnapp/util/files/FileSharing.kt | 31 +------- .../layout/bugreporting_debuglog_fragment.xml | 6 +- .../src/main/res/values-bg/strings.xml | 12 +--- .../src/main/res/values-de/strings.xml | 13 ++-- .../src/main/res/values-en/strings.xml | 12 +--- .../src/main/res/values-pl/strings.xml | 12 +--- .../src/main/res/values-ro/strings.xml | 12 +--- .../src/main/res/values-tr/strings.xml | 12 +--- .../src/main/res/values/strings.xml | 12 +--- .../src/main/res/xml/provider_paths.xml | 2 +- .../debuglog/export/SAFLogExportTest.kt | 72 ------------------- 15 files changed, 49 insertions(+), 320 deletions(-) delete mode 100644 Corona-Warn-App/src/main/java/de/rki/coronawarnapp/bugreporting/debuglog/export/SAFLogExport.kt delete mode 100644 Corona-Warn-App/src/test/java/de/rki/coronawarnapp/bugreporting/debuglog/export/SAFLogExportTest.kt diff --git a/Corona-Warn-App/src/androidTest/java/de/rki/coronawarnapp/bugreporting/DebugLogFragmentTest.kt b/Corona-Warn-App/src/androidTest/java/de/rki/coronawarnapp/bugreporting/DebugLogFragmentTest.kt index c97a39b0d84..c18496b74f1 100644 --- a/Corona-Warn-App/src/androidTest/java/de/rki/coronawarnapp/bugreporting/DebugLogFragmentTest.kt +++ b/Corona-Warn-App/src/androidTest/java/de/rki/coronawarnapp/bugreporting/DebugLogFragmentTest.kt @@ -1,12 +1,10 @@ package de.rki.coronawarnapp.bugreporting -import android.content.ContentResolver import androidx.lifecycle.MutableLiveData import androidx.test.ext.junit.runners.AndroidJUnit4 import dagger.Module import dagger.android.ContributesAndroidInjector import de.rki.coronawarnapp.bugreporting.debuglog.DebugLogger -import de.rki.coronawarnapp.bugreporting.debuglog.export.SAFLogExport import de.rki.coronawarnapp.bugreporting.debuglog.internal.LogSnapshotter import de.rki.coronawarnapp.bugreporting.debuglog.ui.DebugLogFragment import de.rki.coronawarnapp.bugreporting.debuglog.ui.DebugLogViewModel @@ -36,8 +34,6 @@ class DebugLogFragmentTest : BaseUITest() { @MockK lateinit var enfClient: ENFClient @MockK lateinit var bugReportingSettings: BugReportingSettings @MockK lateinit var logSnapshotter: LogSnapshotter - @MockK lateinit var safLogExport: SAFLogExport - @MockK lateinit var contentResolver: ContentResolver private lateinit var inactiveViewModel: DebugLogViewModel private lateinit var activeViewModel: DebugLogViewModel @@ -103,9 +99,7 @@ class DebugLogFragmentTest : BaseUITest() { TestDispatcherProvider(), enfClient, bugReportingSettings, - logSnapshotter, - safLogExport, - contentResolver + logSnapshotter ) ) with(vm) { diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/bugreporting/debuglog/export/SAFLogExport.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/bugreporting/debuglog/export/SAFLogExport.kt deleted file mode 100644 index 12d91f7ef91..00000000000 --- a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/bugreporting/debuglog/export/SAFLogExport.kt +++ /dev/null @@ -1,62 +0,0 @@ -package de.rki.coronawarnapp.bugreporting.debuglog.export - -import android.content.ContentResolver -import android.content.Intent -import android.net.Uri -import de.rki.coronawarnapp.bugreporting.debuglog.internal.LogSnapshotter -import de.rki.coronawarnapp.util.files.determineMimeType -import okio.buffer -import okio.sink -import okio.source -import timber.log.Timber -import javax.inject.Inject -import javax.inject.Singleton - -@Singleton -class SAFLogExport @Inject constructor() { - private var lastId = 1 - private val requestMap = mutableMapOf() - - fun createSAFRequest(snapshot: LogSnapshotter.Snapshot): Request { - val request = Request( - id = ++lastId, - snapshot = snapshot - ) - requestMap[request.id] = request - return request - } - - fun getRequest(id: Int): Request? = requestMap[id] - - data class Request( - val id: Int, - val snapshot: LogSnapshotter.Snapshot, - ) { - fun createIntent() = Intent(Intent.ACTION_CREATE_DOCUMENT).apply { - addCategory(Intent.CATEGORY_OPENABLE) - type = snapshot.path.determineMimeType() - putExtra(Intent.EXTRA_TITLE, snapshot.path.name) - } - - fun storeSnapshot(resolver: ContentResolver, uri: Uri): Result { - Timber.tag(TAG).d("Writing to %s", uri) - resolver.openOutputStream(uri)!!.sink().buffer().use { dest -> - snapshot.path.source().buffer().use { source -> - dest.writeAll(source) - } - } - Timber.tag(TAG).i("%s was written to %s", snapshot, uri) - - snapshot.delete().also { - Timber.tag(TAG).d("Snapshot deleted: %s", snapshot) - } - return Result(uri) - } - - data class Result(val storageUri: Uri) - } - - companion object { - private const val TAG = "SAFLogSharing" - } -} diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/bugreporting/debuglog/ui/DebugLogFragment.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/bugreporting/debuglog/ui/DebugLogFragment.kt index 0adf631f150..7c2913791e8 100644 --- a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/bugreporting/debuglog/ui/DebugLogFragment.kt +++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/bugreporting/debuglog/ui/DebugLogFragment.kt @@ -1,6 +1,5 @@ package de.rki.coronawarnapp.bugreporting.debuglog.ui -import android.app.Activity import android.content.Intent import android.os.Bundle import android.provider.Settings @@ -12,11 +11,12 @@ import androidx.core.widget.NestedScrollView import androidx.fragment.app.Fragment import com.google.android.material.dialog.MaterialAlertDialogBuilder import de.rki.coronawarnapp.R +import de.rki.coronawarnapp.bugreporting.debuglog.internal.LogSnapshotter import de.rki.coronawarnapp.databinding.BugreportingDebuglogFragmentBinding import de.rki.coronawarnapp.util.ContextExtensions.getDrawableCompat import de.rki.coronawarnapp.util.di.AutoInject +import de.rki.coronawarnapp.util.files.FileSharing import de.rki.coronawarnapp.util.setUrl -import de.rki.coronawarnapp.util.tryHumanReadableError import de.rki.coronawarnapp.util.ui.doNavigate import de.rki.coronawarnapp.util.ui.observe2 import de.rki.coronawarnapp.util.ui.popBackStack @@ -26,12 +26,13 @@ import de.rki.coronawarnapp.util.viewmodel.CWAViewModelFactoryProvider import de.rki.coronawarnapp.util.viewmodel.cwaViewModels import org.joda.time.Duration import org.joda.time.Instant -import timber.log.Timber import javax.inject.Inject class DebugLogFragment : Fragment(R.layout.bugreporting_debuglog_fragment), AutoInject { @Inject lateinit var viewModelFactory: CWAViewModelFactoryProvider.Factory + @Inject lateinit var fileSharing: FileSharing + private val vm: DebugLogViewModel by cwaViewModels { viewModelFactory } private val binding: BugreportingDebuglogFragmentBinding by viewBindingLazy() @@ -91,13 +92,13 @@ class DebugLogFragment : Fragment(R.layout.bugreporting_debuglog_fragment), Auto toggleSendErrorLog.apply { isGone = !it.isRecording isEnabled = it.currentSize > 0L && !it.isActionInProgress - setOnClickListener { vm.onShareButtonPress() } + setOnClickListener { vm.onSendErrorLogPress() } } - toggleStoreLog.apply { + toggleExportLog.apply { isGone = !it.isRecording isEnabled = it.currentSize > 0L && !it.isActionInProgress - setOnClickListener { vm.onStoreLog() } + setOnClickListener { vm.onExportLogPress() } } } } @@ -128,14 +129,8 @@ class DebugLogFragment : Fragment(R.layout.bugreporting_debuglog_fragment), Auto DebugLogViewModel.Event.ShowLowStorageDialog -> { showLowStorageError() } - is DebugLogViewModel.Event.LocalExport -> { - startActivityForResult(it.request.createIntent(), it.request.id) - } - is DebugLogViewModel.Event.ExportResult -> { - showExportResult() - } - is DebugLogViewModel.Event.ShowLocalExportError -> { - showLocalExportError(it.error) + is DebugLogViewModel.Event.Export -> { + exportLog(it.snapshot) } } } @@ -164,14 +159,6 @@ class DebugLogFragment : Fragment(R.layout.bugreporting_debuglog_fragment), Auto binding.debugLogHistoryContainer.setOnClickListener { vm.onIdHistoryPress() } } - override fun onActivityResult(requestCode: Int, resultCode: Int, resultData: Intent?) { - Timber.d("onActivityResult(requestCode=$requestCode, resultCode=$resultCode, resultData=$resultData") - vm.processSAFResult( - requestCode, - if (resultCode == Activity.RESULT_OK) resultData?.data else null - ) - } - private fun showLogDeletionRequest() { MaterialAlertDialogBuilder(requireContext()).apply { setTitle(R.string.debugging_debuglog_stop_confirmation_title) @@ -198,29 +185,10 @@ class DebugLogFragment : Fragment(R.layout.bugreporting_debuglog_fragment), Auto }.show() } - private fun showExportResult() { - MaterialAlertDialogBuilder(requireContext()).apply { - setTitle(R.string.debugging_debuglog_localexport_title) - setMessage(R.string.debugging_debuglog_localexport_message) - setPositiveButton(android.R.string.yes) { _, _ -> /* dismiss */ } - }.show() - } - - private fun showLocalExportError(cause: Throwable) { - MaterialAlertDialogBuilder(requireContext()).apply { - setTitle(R.string.errors_generic_headline_short) - setMessage( - getString(R.string.debugging_debuglog_localexport_error_message) + "\n(" + - cause.tryHumanReadableError(requireContext()).description + ")" - ) - setPositiveButton(android.R.string.yes) { _, _ -> /* dismiss */ } - setNeutralButton(R.string.menu_settings) { _, _ -> - try { - startActivity(Intent(Settings.ACTION_INTERNAL_STORAGE_SETTINGS)) - } catch (e: Exception) { - Toast.makeText(requireContext(), e.toString(), Toast.LENGTH_LONG).show() - } - } - }.show() + private fun exportLog(snapshot: LogSnapshotter.Snapshot) { + val intent = fileSharing + .getFileIntentProvider(snapshot.path, snapshot.path.name, createChooserIntent = true) + .intent(requireActivity()) + startActivity(intent) } } diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/bugreporting/debuglog/ui/DebugLogViewModel.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/bugreporting/debuglog/ui/DebugLogViewModel.kt index d9793e597bc..8e83edfe1e1 100644 --- a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/bugreporting/debuglog/ui/DebugLogViewModel.kt +++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/bugreporting/debuglog/ui/DebugLogViewModel.kt @@ -1,14 +1,11 @@ package de.rki.coronawarnapp.bugreporting.debuglog.ui -import android.content.ContentResolver -import android.net.Uri import androidx.lifecycle.LiveData import androidx.lifecycle.asLiveData import dagger.assisted.AssistedFactory import dagger.assisted.AssistedInject import de.rki.coronawarnapp.bugreporting.BugReportingSettings import de.rki.coronawarnapp.bugreporting.debuglog.DebugLogger -import de.rki.coronawarnapp.bugreporting.debuglog.export.SAFLogExport import de.rki.coronawarnapp.bugreporting.debuglog.internal.LogSnapshotter import de.rki.coronawarnapp.nearby.ENFClient import de.rki.coronawarnapp.util.CWADebug @@ -20,16 +17,13 @@ import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.flow.combine import timber.log.Timber -import java.io.IOException class DebugLogViewModel @AssistedInject constructor( private val debugLogger: DebugLogger, dispatcherProvider: DispatcherProvider, private val enfClient: ENFClient, bugReportingSettings: BugReportingSettings, - private val logSnapshotter: LogSnapshotter, - private val safLogExport: SAFLogExport, - private val contentResolver: ContentResolver, + private val logSnapshotter: LogSnapshotter ) : CWAViewModel(dispatcherProvider = dispatcherProvider) { private val isActionInProgress = MutableStateFlow(false) @@ -55,7 +49,7 @@ class DebugLogViewModel @AssistedInject constructor( events.postValue(Event.NavigateToPrivacyFragment) } - fun onShareButtonPress() { + fun onSendErrorLogPress() { events.postValue(Event.NavigateToUploadFragment) } @@ -93,33 +87,10 @@ class DebugLogViewModel @AssistedInject constructor( } } - fun onStoreLog() = launchWithProgress(finishProgressAction = false) { - Timber.d("storeLog()") + fun onExportLogPress() = launchWithProgress(finishProgressAction = true) { + Timber.d("onExportLogPress()") val snapshot = logSnapshotter.snapshot() - val shareRequest = safLogExport.createSAFRequest(snapshot) - events.postValue(Event.LocalExport(shareRequest)) - } - - fun processSAFResult(requestCode: Int, safPath: Uri?) = launchWithProgress { - if (safPath == null) { - Timber.i("No SAF path available.") - return@launchWithProgress - } - - val request = safLogExport.getRequest(requestCode) - if (request == null) { - Timber.w("Unknown request with code $requestCode") - return@launchWithProgress - } - - try { - val storageResult = request.storeSnapshot(contentResolver, safPath) - Timber.i("Log stored %s", storageResult) - events.postValue(Event.ExportResult(storageResult)) - } catch (e: IOException) { - Timber.e(e, "Failed to store log file.") - events.postValue(Event.ShowLocalExportError(e)) - } + events.postValue(Event.Export(snapshot)) } private fun launchWithProgress( @@ -156,10 +127,8 @@ class DebugLogViewModel @AssistedInject constructor( object NavigateToUploadHistory : Event() object ShowLogDeletionRequest : Event() object ShowLowStorageDialog : Event() - data class ShowLocalExportError(val error: Throwable) : Event() data class Error(val error: Throwable) : Event() - data class LocalExport(val request: SAFLogExport.Request) : Event() - data class ExportResult(val result: SAFLogExport.Request.Result) : Event() + data class Export(val snapshot: LogSnapshotter.Snapshot) : Event() } @AssistedFactory diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/util/files/FileSharing.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/util/files/FileSharing.kt index 488c8a12f3a..632ee2a10ee 100644 --- a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/util/files/FileSharing.kt +++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/util/files/FileSharing.kt @@ -4,7 +4,6 @@ import android.app.Activity import android.content.Context import android.content.Intent import android.net.Uri -import androidx.annotation.StringRes import androidx.core.app.ShareCompat import androidx.core.content.FileProvider import dagger.Reusable @@ -25,45 +24,19 @@ class FileSharing @Inject constructor( path ) - fun getIntentProvider( - path: File, - title: String, - @StringRes chooserTitle: Int? = null - ): ShareIntentProvider = object : ShareIntentProvider { - override fun get(activity: Activity): Intent { - val builder = ShareCompat.IntentBuilder.from(activity).apply { - setType(path.determineMimeType()) - setStream(getFileUri(path)) - setSubject(title) - chooserTitle?.let { setChooserTitle(it) } - } - - val intent = if (chooserTitle != null) { - builder.createChooserIntent() - } else { - builder.intent - } - return intent.apply { - addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION) - Timber.tag(TAG).d("Intent created %s", this) - } - } - } - fun getFileIntentProvider( path: File, title: String, - @StringRes chooserTitle: Int? = null + createChooserIntent: Boolean = false ): FileIntentProvider = object : FileIntentProvider { override fun intent(activity: Activity): Intent { val builder = ShareCompat.IntentBuilder.from(activity).apply { setType(path.determineMimeType()) setStream(getFileUri(path)) setSubject(title) - chooserTitle?.let { setChooserTitle(it) } } - val intent = if (chooserTitle != null) { + val intent = if (createChooserIntent) { builder.createChooserIntent() } else { builder.intent diff --git a/Corona-Warn-App/src/main/res/layout/bugreporting_debuglog_fragment.xml b/Corona-Warn-App/src/main/res/layout/bugreporting_debuglog_fragment.xml index 2277fe672d8..1a236c4b811 100644 --- a/Corona-Warn-App/src/main/res/layout/bugreporting_debuglog_fragment.xml +++ b/Corona-Warn-App/src/main/res/layout/bugreporting_debuglog_fragment.xml @@ -174,13 +174,13 @@ tools:text="@string/debugging_debuglog_action_share_log" />