Add a "connectivity warning" bottom sheet.

This commit is contained in:
Greyson Parrelli
2024-07-19 16:17:04 -04:00
committed by Nicholas Tinsley
parent 44b2c62a0e
commit f1ba947a59
16 changed files with 312 additions and 51 deletions

View File

@@ -29,7 +29,7 @@ object DeviceSpecificNotificationConfig {
*/
data class Config(
@JsonProperty val model: String = "",
@JsonProperty val showConditionCode: String = "has-slow-notifications",
@JsonProperty val showConditionCode: String = ShowCondition.NONE.code,
@JsonProperty val link: String = GENERAL_SUPPORT_URL,
@JsonProperty val localePercent: String = "*",
@JsonProperty val version: Int = 0
@@ -43,10 +43,11 @@ object DeviceSpecificNotificationConfig {
enum class ShowCondition(val code: String) {
ALWAYS("always"),
HAS_BATTERY_OPTIMIZATION_ON("has-battery-optimization-on"),
HAS_SLOW_NOTIFICATIONS("has-slow-notifications");
HAS_SLOW_NOTIFICATIONS("has-slow-notifications"),
NONE("none");
companion object {
fun fromCode(code: String) = values().firstOrNull { it.code == code } ?: HAS_SLOW_NOTIFICATIONS
fun fromCode(code: String) = entries.firstOrNull { it.code == code } ?: NONE
}
}

View File

@@ -63,7 +63,7 @@ object SlowNotificationHeuristics {
}
@JvmStatic
fun shouldPromptUserForLogs(): Boolean {
fun shouldPromptUserForDelayedNotificationLogs(): Boolean {
if (!LocaleRemoteConfig.isDelayedNotificationPromptEnabled() || SignalStore.uiHints.hasDeclinedToShareNotificationLogs()) {
return false
}
@@ -143,11 +143,11 @@ object SlowNotificationHeuristics {
return true
}
fun showCondition(): DeviceSpecificNotificationConfig.ShowCondition {
fun getDeviceSpecificShowCondition(): DeviceSpecificNotificationConfig.ShowCondition {
return DeviceSpecificNotificationConfig.currentConfig.showCondition
}
fun shouldShowDialog(): Boolean {
fun shouldShowDeviceSpecificDialog(): Boolean {
return LocaleRemoteConfig.isDeviceSpecificNotificationEnabled() && SignalStore.uiHints.lastSupportVersionSeen < DeviceSpecificNotificationConfig.currentConfig.version
}

View File

@@ -15,6 +15,9 @@ import io.reactivex.rxjava3.subjects.BehaviorSubject
import org.thoughtcrime.securesms.crash.CrashConfig
import org.thoughtcrime.securesms.database.LogDatabase
import org.thoughtcrime.securesms.keyvalue.SignalStore
import org.thoughtcrime.securesms.notifications.DeviceSpecificNotificationConfig.ShowCondition
import org.thoughtcrime.securesms.util.ConnectivityWarning
import org.thoughtcrime.securesms.util.NetworkUtil
import java.util.concurrent.TimeUnit
import kotlin.time.Duration.Companion.days
@@ -45,34 +48,48 @@ class VitalsViewModel(private val context: Application) : AndroidViewModel(conte
private fun checkHeuristics(): Single<State> {
return Single.fromCallable {
var state = State.NONE
when (SlowNotificationHeuristics.showCondition()) {
DeviceSpecificNotificationConfig.ShowCondition.ALWAYS -> {
if (SlowNotificationHeuristics.shouldShowDialog()) {
state = State.PROMPT_SPECIFIC_BATTERY_SAVER_DIALOG
}
}
DeviceSpecificNotificationConfig.ShowCondition.HAS_BATTERY_OPTIMIZATION_ON -> {
if (SlowNotificationHeuristics.shouldShowDialog() && SlowNotificationHeuristics.isBatteryOptimizationsOn()) {
state = State.PROMPT_SPECIFIC_BATTERY_SAVER_DIALOG
}
}
DeviceSpecificNotificationConfig.ShowCondition.HAS_SLOW_NOTIFICATIONS -> {
if (SlowNotificationHeuristics.isHavingDelayedNotifications() && SlowNotificationHeuristics.shouldPromptBatterySaver()) {
state = State.PROMPT_GENERAL_BATTERY_SAVER_DIALOG
} else if (SlowNotificationHeuristics.isHavingDelayedNotifications() && SlowNotificationHeuristics.shouldPromptUserForLogs()) {
state = State.PROMPT_DEBUGLOGS_FOR_NOTIFICATIONS
} else if (LogDatabase.getInstance(context).crashes.anyMatch(patterns = CrashConfig.patterns, promptThreshold = System.currentTimeMillis() - 14.days.inWholeMilliseconds)) {
val timeSinceLastPrompt = System.currentTimeMillis() - SignalStore.uiHints.lastCrashPrompt
val deviceSpecificCondition = SlowNotificationHeuristics.getDeviceSpecificShowCondition()
if (timeSinceLastPrompt > 1.days.inWholeMilliseconds) {
state = State.PROMPT_DEBUGLOGS_FOR_CRASH
}
}
if (deviceSpecificCondition == ShowCondition.ALWAYS && SlowNotificationHeuristics.shouldShowDeviceSpecificDialog()) {
return@fromCallable State.PROMPT_SPECIFIC_BATTERY_SAVER_DIALOG
}
if (deviceSpecificCondition == ShowCondition.HAS_BATTERY_OPTIMIZATION_ON && SlowNotificationHeuristics.shouldShowDeviceSpecificDialog() && SlowNotificationHeuristics.isBatteryOptimizationsOn()) {
return@fromCallable State.PROMPT_SPECIFIC_BATTERY_SAVER_DIALOG
}
if (deviceSpecificCondition == ShowCondition.HAS_SLOW_NOTIFICATIONS && SlowNotificationHeuristics.shouldPromptBatterySaver()) {
return@fromCallable State.PROMPT_SPECIFIC_BATTERY_SAVER_DIALOG
}
if (SlowNotificationHeuristics.isHavingDelayedNotifications() && SlowNotificationHeuristics.shouldPromptBatterySaver()) {
return@fromCallable State.PROMPT_GENERAL_BATTERY_SAVER_DIALOG
}
if (SlowNotificationHeuristics.isHavingDelayedNotifications() && SlowNotificationHeuristics.shouldPromptUserForDelayedNotificationLogs()) {
return@fromCallable State.PROMPT_DEBUGLOGS_FOR_NOTIFICATIONS
}
val timeSinceLastConnection = System.currentTimeMillis() - SignalStore.misc.lastWebSocketConnectTime
val timeSinceLastConnectionWarning = System.currentTimeMillis() - SignalStore.misc.lastConnectivityWarningTime
if (ConnectivityWarning.isEnabled && timeSinceLastConnection > ConnectivityWarning.threshold && timeSinceLastConnectionWarning > 14.days.inWholeMilliseconds && NetworkUtil.isConnected(context)) {
return@fromCallable if (ConnectivityWarning.isDebugPromptEnabled) {
State.PROMPT_DEBUGLOGS_FOR_CONNECTIVITY_WARNING
} else {
State.PROMPT_CONNECTIVITY_WARNING
}
}
return@fromCallable state
if (LogDatabase.getInstance(context).crashes.anyMatch(patterns = CrashConfig.patterns, promptThreshold = System.currentTimeMillis() - 14.days.inWholeMilliseconds)) {
val timeSinceLastPrompt = System.currentTimeMillis() - SignalStore.uiHints.lastCrashPrompt
if (timeSinceLastPrompt > 1.days.inWholeMilliseconds) {
return@fromCallable State.PROMPT_DEBUGLOGS_FOR_CRASH
}
}
return@fromCallable State.NONE
}.subscribeOn(Schedulers.io())
}
@@ -81,6 +98,8 @@ class VitalsViewModel(private val context: Application) : AndroidViewModel(conte
PROMPT_SPECIFIC_BATTERY_SAVER_DIALOG,
PROMPT_GENERAL_BATTERY_SAVER_DIALOG,
PROMPT_DEBUGLOGS_FOR_NOTIFICATIONS,
PROMPT_DEBUGLOGS_FOR_CRASH
PROMPT_DEBUGLOGS_FOR_CRASH,
PROMPT_CONNECTIVITY_WARNING,
PROMPT_DEBUGLOGS_FOR_CONNECTIVITY_WARNING
}
}