diff --git a/android/src/main/java/com/tailscale/ipn/ui/notifier/HealthNotifier.kt b/android/src/main/java/com/tailscale/ipn/ui/notifier/HealthNotifier.kt index 17d86a92d7..3af7e25dd1 100644 --- a/android/src/main/java/com/tailscale/ipn/ui/notifier/HealthNotifier.kt +++ b/android/src/main/java/com/tailscale/ipn/ui/notifier/HealthNotifier.kt @@ -45,26 +45,30 @@ class HealthNotifier( "wantrunning-false") init { + // This roughly matches the iOS/macOS implementation in terms of debouncing, and ingoring + // health warnings in various states. scope.launch { healthStateFlow .distinctUntilChanged { old, new -> old?.Warnings?.count() == new?.Warnings?.count() } .combine(ipnStateFlow, ::Pair) - .debounce(5000) + .debounce(3000) .collect { pair -> val health = pair.first - val ipnState = pair.second - // When the client is Stopped, no warnings should get added, and any warnings added - // previously should be removed. - if (ipnState == Ipn.State.Stopped) { - TSLog.d( - TAG, - "Ignoring and dropping all pre-existing health messages in the Stopped state") - dropAllWarnings() - return@collect - } else { - TSLog.d(TAG, "Health updated: ${health?.Warnings?.keys?.sorted()}") - health?.Warnings?.let { - notifyHealthUpdated(it.values.mapNotNull { it }.toTypedArray()) + // When the client is Stopped, requires Login or has no state, we should drop all + // existing warnings + when (val ipnState = pair.second) { + Ipn.State.NeedsLogin, + Ipn.State.Stopped, + Ipn.State.NoState -> { + TSLog.d(TAG, "Ignoring and dropping all health messages in state ${ipnState}") + dropAllWarnings() + return@collect + } + else -> { + TSLog.d(TAG, "Health updated: ${health?.Warnings?.keys?.sorted()}") + health?.Warnings?.let { + notifyHealthUpdated(it.values.mapNotNull { it }.toTypedArray()) + } } } }