diff --git a/play-services-core/src/main/kotlin/org/microg/gms/ui/ExposureNotificationsAppPreferencesFragment.kt b/play-services-core/src/main/kotlin/org/microg/gms/ui/ExposureNotificationsAppPreferencesFragment.kt index bfdfbe1a..bc54805c 100644 --- a/play-services-core/src/main/kotlin/org/microg/gms/ui/ExposureNotificationsAppPreferencesFragment.kt +++ b/play-services-core/src/main/kotlin/org/microg/gms/ui/ExposureNotificationsAppPreferencesFragment.kt @@ -8,10 +8,13 @@ package org.microg.gms.ui import android.content.Intent import android.os.Bundle import android.text.format.DateUtils +import android.util.JsonReader import androidx.preference.Preference import androidx.preference.PreferenceFragmentCompat import com.google.android.gms.R +import org.json.JSONObject import org.microg.gms.nearby.exposurenotification.ExposureDatabase +import java.util.concurrent.TimeUnit class ExposureNotificationsAppPreferencesFragment : PreferenceFragmentCompat() { private lateinit var open: Preference @@ -53,6 +56,19 @@ class ExposureNotificationsAppPreferencesFragment : PreferenceFragmentCompat() { if (lastCheckTime != null && lastCheckTime != 0L) { str += "\n" + getString(R.string.pref_exposure_app_last_check_summary, DateUtils.getRelativeDateTimeString(context, lastCheckTime, DateUtils.MINUTE_IN_MILLIS, DateUtils.WEEK_IN_MILLIS, DateUtils.FORMAT_SHOW_TIME)) } + val lastExposureSummaryTime = database.lastMethodCall(packageName, "getExposureSummary") + val lastExposureSummary = database.lastMethodCallArgs(packageName, "getExposureSummary") + if (lastExposureSummaryTime != null && lastExposureSummary != null && System.currentTimeMillis() - lastExposureSummaryTime <= TimeUnit.DAYS.toMillis(1)) { + try { + val json = JSONObject(lastExposureSummary) + val matchedKeys = json.optInt("response_matched_keys") + val daysSince = json.optInt("response_days_since", -1) + if (matchedKeys > 0 && daysSince >= 0) { + str += "\n" + resources.getQuantityString(R.plurals.pref_exposure_app_last_report_summary, matchedKeys, matchedKeys, daysSince) + } + } catch (ignored: Exception) { + } + } checks.summary = str } } diff --git a/play-services-core/src/main/res/values/plurals.xml b/play-services-core/src/main/res/values/plurals.xml index e12bc924..c5b8ef5a 100644 --- a/play-services-core/src/main/res/values/plurals.xml +++ b/play-services-core/src/main/res/values/plurals.xml @@ -32,4 +32,8 @@ Request missing permission Request missing permissions - \ No newline at end of file + + Last report: %1$d match, %2$d days ago + Last report: %1$d matches, latest %2$d days ago + + diff --git a/play-services-core/src/main/res/xml/preferences_exposure_notifications_app.xml b/play-services-core/src/main/res/xml/preferences_exposure_notifications_app.xml index c5aa4767..26caa9d8 100644 --- a/play-services-core/src/main/res/xml/preferences_exposure_notifications_app.xml +++ b/play-services-core/src/main/res/xml/preferences_exposure_notifications_app.xml @@ -16,6 +16,6 @@ + tools:summary="7 checks in past 14 days\nLast check: 3 hours ago\nLast report: 2 matches, latest 3 days ago" /> diff --git a/play-services-nearby-core/src/main/kotlin/org/microg/gms/nearby/exposurenotification/ExposureDatabase.kt b/play-services-nearby-core/src/main/kotlin/org/microg/gms/nearby/exposurenotification/ExposureDatabase.kt index b8b89527..04515f29 100644 --- a/play-services-nearby-core/src/main/kotlin/org/microg/gms/nearby/exposurenotification/ExposureDatabase.kt +++ b/play-services-nearby-core/src/main/kotlin/org/microg/gms/nearby/exposurenotification/ExposureDatabase.kt @@ -444,6 +444,16 @@ class ExposureDatabase private constructor(private val context: Context) : SQLit } } + fun lastMethodCallArgs(packageName: String, method: String): String? = readableDatabase.run { + query(TABLE_APP_LOG, arrayOf("args"), "package = ? AND method = ?", arrayOf(packageName, method), null, null, "timestamp DESC", "1").use { cursor -> + if (cursor.moveToNext()) { + cursor.getString(0) + } else { + null + } + } + } + private val currentTemporaryExposureKey: TemporaryExposureKey get() = findOwnKeyAt(currentRollingStartNumber.toInt()) ?: storeOwnKey(generateCurrentTemporaryExposureKey()) diff --git a/play-services-nearby-core/src/main/kotlin/org/microg/gms/nearby/exposurenotification/ExposureNotificationServiceImpl.kt b/play-services-nearby-core/src/main/kotlin/org/microg/gms/nearby/exposurenotification/ExposureNotificationServiceImpl.kt index 28aac77b..8d573bb1 100644 --- a/play-services-nearby-core/src/main/kotlin/org/microg/gms/nearby/exposurenotification/ExposureNotificationServiceImpl.kt +++ b/play-services-nearby-core/src/main/kotlin/org/microg/gms/nearby/exposurenotification/ExposureNotificationServiceImpl.kt @@ -72,24 +72,14 @@ class ExposureNotificationServiceImpl(private val context: Context, private val } override fun stop(params: StopParams) { - if (!ExposurePreferences(context).enabled) { - params.callback.onResult(Status.SUCCESS) - return + ExposurePreferences(context).enabled = false + ExposureDatabase.with(context) { database -> + database.noteAppAction(packageName, "stop") } - confirm(CONFIRM_ACTION_STOP) { resultCode, _ -> - if (resultCode == SUCCESS) { - ExposurePreferences(context).enabled = false - } - ExposureDatabase.with(context) { database -> - database.noteAppAction(packageName, "stop", JSONObject().apply { - put("result", resultCode) - }.toString()) - } - try { - params.callback.onResult(Status.SUCCESS) - } catch (e: Exception) { - Log.w(TAG, "Callback failed", e) - } + try { + params.callback.onResult(Status.SUCCESS) + } catch (e: Exception) { + Log.w(TAG, "Callback failed", e) } } diff --git a/play-services-nearby-core/src/main/kotlin/org/microg/gms/nearby/exposurenotification/MeasuredExposure.kt b/play-services-nearby-core/src/main/kotlin/org/microg/gms/nearby/exposurenotification/MeasuredExposure.kt index 415baecf..18113f1f 100644 --- a/play-services-nearby-core/src/main/kotlin/org/microg/gms/nearby/exposurenotification/MeasuredExposure.kt +++ b/play-services-nearby-core/src/main/kotlin/org/microg/gms/nearby/exposurenotification/MeasuredExposure.kt @@ -55,7 +55,7 @@ data class MergedExposure internal constructor(val key: TemporaryExposureKey, va get() = TimeUnit.MILLISECONDS.toDays(System.currentTimeMillis() - timestamp) val attenuation - get() = subs.map { it.attenuation }.min()!! + get() = (subs.map { it.attenuation * it.duration }.sum().toDouble() / subs.map { it.duration }.sum().toDouble()).toInt() fun getAttenuationRiskScore(configuration: ExposureConfiguration): Int { return when {