Skip to content
This repository has been archived by the owner on Jun 20, 2023. It is now read-only.

Commit

Permalink
Merge pull request #5322 from corona-warn-app/fix/13461-tan-submission
Browse files Browse the repository at this point in the history
No TEK caching from test menu (EXPOSUREAPP-13461)
  • Loading branch information
schauersbergern authored Jul 6, 2022
2 parents 81b1f45 + 7bd236d commit f76fbfb
Show file tree
Hide file tree
Showing 11 changed files with 187 additions and 140 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import android.view.View
import androidx.fragment.app.Fragment
import androidx.recyclerview.widget.LinearLayoutManager
import de.rki.coronawarnapp.R
import de.rki.coronawarnapp.bugreporting.ui.toErrorDialogBuilder
import de.rki.coronawarnapp.databinding.FragmentTestSubmissionBinding
import de.rki.coronawarnapp.test.menu.ui.TestMenuItem
import de.rki.coronawarnapp.tracing.ui.TracingConsentDialog
Expand Down Expand Up @@ -50,10 +51,13 @@ class SubmissionTestFragment : Fragment(R.layout.fragment_test_submission), Auto
startActivity(share)
}

vm.errorEvents.observe2(this) {
it.toErrorDialogBuilder(requireContext()).show()
}

binding.apply {
tekStorageUpdate.setOnClickListener { vm.updateStorage() }
tekStorageClear.setOnClickListener { vm.clearStorage() }
tekStorageEmail.setOnClickListener { vm.emailTEKs() }
tekRetrieval.setOnClickListener { vm.updateStorage() }
tekEmail.setOnClickListener { vm.emailTEKs() }
}
vm.permissionRequestEvent.observe2(this) { permissionRequest ->
permissionRequest.invoke(requireActivity())
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,27 +2,24 @@ package de.rki.coronawarnapp.test.submission.ui

import android.app.Activity
import android.content.Intent
import androidx.lifecycle.LiveData
import androidx.lifecycle.asLiveData
import androidx.lifecycle.MutableLiveData
import com.google.android.gms.nearby.exposurenotification.TemporaryExposureKey
import com.google.gson.Gson
import dagger.assisted.AssistedFactory
import dagger.assisted.AssistedInject
import de.rki.coronawarnapp.submission.data.tekhistory.TEKHistoryStorage
import de.rki.coronawarnapp.submission.data.tekhistory.TEKHistoryUpdater
import de.rki.coronawarnapp.util.TimeStamper
import de.rki.coronawarnapp.util.coroutine.DispatcherProvider
import de.rki.coronawarnapp.util.serialization.BaseGson
import de.rki.coronawarnapp.util.ui.SingleLiveEvent
import de.rki.coronawarnapp.util.viewmodel.CWAViewModel
import de.rki.coronawarnapp.util.viewmodel.SimpleCWAViewModelFactory
import kotlinx.coroutines.flow.first
import kotlinx.coroutines.flow.map
import timber.log.Timber

class SubmissionTestFragmentViewModel @AssistedInject constructor(
dispatcherProvider: DispatcherProvider,
private val tekHistoryStorage: TEKHistoryStorage,
tekHistoryUpdaterFactory: TEKHistoryUpdater.Factory,
timeStamper: TimeStamper,
@BaseGson baseGson: Gson
) : CWAViewModel(dispatcherProvider = dispatcherProvider) {

Expand All @@ -34,6 +31,14 @@ class SubmissionTestFragmentViewModel @AssistedInject constructor(
object : TEKHistoryUpdater.Callback {
override fun onTEKAvailable(teks: List<TemporaryExposureKey>) {
Timber.d("TEKs are available: %s", teks)
val now = timeStamper.nowJavaUTC
val tekList = teks.map { key ->
TEKHistoryItem(
obtainedAt = now,
key = key
)
}.sortedBy { it.obtainedAt }
tekHistory.postValue(tekList)
}

override fun onTEKPermissionDeclined() {
Expand Down Expand Up @@ -61,40 +66,20 @@ class SubmissionTestFragmentViewModel @AssistedInject constructor(
val permissionRequestEvent = SingleLiveEvent<(Activity) -> Unit>()
val showTracingConsentDialog = SingleLiveEvent<(Boolean) -> Unit>()

val tekHistory: LiveData<List<TEKHistoryItem>> = tekHistoryStorage.tekData
.map { items ->
items.flatMap { batch ->
batch.keys
.map { key ->
TEKHistoryItem(
obtainedAt = batch.obtainedAt,
batchId = batch.batchId,
key = key
)
}
}
}
.map { historyItems -> historyItems.sortedBy { it.obtainedAt } }
.asLiveData(context = dispatcherProvider.Default)
val tekHistory = MutableLiveData<List<TEKHistoryItem>>()

fun updateStorage() {
tekHistoryUpdater.updateTEKHistoryOrRequestPermission()
}

fun clearStorage() {
launch {
tekHistoryStorage.reset()
}
tekHistoryUpdater.getTeksForTesting()
}

fun emailTEKs() {
launch {
val exportedKeys = tekHistoryStorage.tekData.first().toExportedKeys()

val tekExport = TEKExport(
exportText = exportJson.toJson(exportedKeys)
)
shareTEKsEvent.postValue(tekExport)
tekHistory.value?.toExportedKeys()?.let {
launch {
val tekExport = TEKExport(
exportText = exportJson.toJson(it)
)
shareTEKsEvent.postValue(tekExport)
}
}
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,18 +1,16 @@
package de.rki.coronawarnapp.test.submission.ui

import com.google.android.gms.nearby.exposurenotification.TemporaryExposureKey
import de.rki.coronawarnapp.submission.data.tekhistory.TEKHistoryStorage
import java.time.Instant

data class TEKExport(
val exportText: String
)

fun List<TEKHistoryStorage.TEKBatch>.toExportedKeys() = this
fun List<TEKHistoryItem>.toExportedKeys() = this
.sortedBy { it.obtainedAt }
.flatMap { batch ->
batch.keys.map { keyInbatch ->
keyInbatch.toExportedTEK(batch)
}
.map { item ->
item.key.toExportedTEK(item.obtainedAt)
}

data class ExportedTEK(
Expand All @@ -25,8 +23,8 @@ data class ExportedTEK(
val daysSinceOnsetOfSymptoms: Int
)

fun TemporaryExposureKey.toExportedTEK(tekBatch: TEKHistoryStorage.TEKBatch) = ExportedTEK(
obtainedAt = tekBatch.obtainedAt.toString(),
fun TemporaryExposureKey.toExportedTEK(obtainedAt: Instant) = ExportedTEK(
obtainedAt = obtainedAt.toString(),
keyData = this.keyData,
rollingStartIntervalNumber = this.rollingStartIntervalNumber,
transmissionRiskLevel = this.transmissionRiskLevel,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,10 @@ package de.rki.coronawarnapp.test.submission.ui

import com.google.android.gms.nearby.exposurenotification.TemporaryExposureKey
import de.rki.coronawarnapp.util.lists.HasStableId
import org.joda.time.Instant
import java.time.Instant

data class TEKHistoryItem(
val obtainedAt: Instant,
val batchId: String,
val key: TemporaryExposureKey
) : HasStableId {

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@
style="@style/body1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Stored TEK History"
android:text="Current TEKs in cache/ENF"
app:layout_constraintTop_toTopOf="parent" />

<TextView
Expand All @@ -35,57 +35,45 @@
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="8dp"
android:text="When the user grants permissions to access the TEKs, they are automatically cached for later submission. The currently cached keys are shown below."
android:text="The currently available keys from cache or ENF are shown below. If the cache has entries from the last submission, these are used. If not, the current TEKs from ENF are used. Does NOT update cache.\n Tracing must be activated in advance."
app:layout_constraintTop_toBottomOf="@id/tek_history_title" />

<Button
android:id="@+id/tek_storage_update"
android:id="@+id/tek_retrieval"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="@dimen/spacing_tiny"
android:text="Get TEKS"
app:layout_constraintEnd_toStartOf="@+id/tek_storage_clear"
android:text="Get TEKs"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/tek_history_description" />

<Button
android:id="@+id/tek_storage_clear"
android:id="@+id/tek_email"
android:layout_width="0dp"
android:layout_height="match_parent"
android:text="Clear storage"
app:layout_constraintBottom_toBottomOf="@+id/tek_storage_update"
android:layout_height="wrap_content"
android:text="Email TEKs"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toEndOf="@+id/tek_storage_update"
app:layout_constraintTop_toTopOf="@+id/tek_storage_update" />

<Button
android:id="@+id/tek_storage_email"
android:layout_width="0dp"
android:layout_height="match_parent"
android:text="Email TEKS"
app:layout_constraintEnd_toStartOf="@+id/tek_storage_clear"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/tek_storage_update" />
app:layout_constraintTop_toBottomOf="@id/tek_retrieval" />

<TextView
android:id="@+id/tek_storage_count"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_marginStart="@dimen/spacing_small"
android:layout_marginEnd="@dimen/spacing_small"
app:layout_constraintBottom_toBottomOf="@id/tek_storage_email"
app:layout_constraintEnd_toEndOf="@+id/tek_storage_clear"
app:layout_constraintStart_toEndOf="@id/tek_storage_email"
app:layout_constraintTop_toBottomOf="@id/tek_storage_update"
android:layout_height="wrap_content"
android:layout_marginTop="@dimen/spacing_normal"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/tek_email"
tools:text="99 TEKs" />

<androidx.recyclerview.widget.RecyclerView
android:id="@+id/tek_history_list"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="@dimen/spacing_tiny"
android:layout_marginTop="@dimen/spacing_small"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintTop_toBottomOf="@id/tek_storage_email" />
app:layout_constraintTop_toBottomOf="@id/tek_storage_count" />
</androidx.constraintlayout.widget.ConstraintLayout>

</LinearLayout>
Expand Down
Loading

0 comments on commit f76fbfb

Please sign in to comment.