mirror of
https://github.com/vitorpamplona/amethyst.git
synced 2026-08-12 09:13:23 +00:00
fix(notifications): stop resetting the watchdog alarm on every account change
The service layers were being re-enabled level-triggered. Before this branch the inner flow was a Boolean behind distinctUntilChanged, so enableServiceLayers() ran once per real transition. It now carries (all accounts, participating accounts), and Account has no equals — so the flow re-emits whenever the account map changes identity, and the outer collector restarts on every foreground/background crossing, which includes every screen-off. That matters because ServiceWatchdogManager.schedule() calls setInexactRepeating with FLAG_UPDATE_CURRENT and a first fire of `elapsedRealtime() + 5min`. Every call replaces the alarm and pushes that first fire out again. Screen-on happens far more often than every five minutes, so L5 — the layer whose entire job is noticing a dead service and restarting it — would effectively never have fired. NotificationCatchUpWorker was unaffected: it enqueues with ExistingPeriodicWorkPolicy.KEEP, so repeat calls leave the existing period alone. Enable/disable is edge-triggered again, explicitly this time rather than as a side effect of what the upstream flow happens to emit. Also drops ActiveSubscriptionsState.busiestPurposeFilters, which has no readers — the cards draw their share against attributedFilters. Verified on emulator-5554: after a cold start, HOME, and return, the foreground service is still running and the watchdog alarm is still registered. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 5
parent
a295f31f94
commit
e3e17e8ecb
+11
-6
@@ -149,12 +149,17 @@ class AlwaysOnNotificationServiceManager(
|
||||
// The service layers are a background concern, so they stay tied to
|
||||
// the master switch and to somebody having opted in. A foreground-only
|
||||
// account must not start a foreground service that outlives the screen.
|
||||
if (masterEnabled && participating.isNotEmpty()) {
|
||||
wasEnabled = true
|
||||
enableServiceLayers()
|
||||
} else if (wasEnabled) {
|
||||
disableServiceLayers()
|
||||
wasEnabled = false
|
||||
//
|
||||
// Edge-triggered, deliberately. This flow re-emits whenever the account
|
||||
// map changes identity or the app crosses foreground — far more often
|
||||
// than the old boolean did — and ServiceWatchdogManager.schedule()
|
||||
// replaces its alarm with one starting `now + 5min`. Calling it on every
|
||||
// emission pushed the watchdog's first fire past every screen-on, so the
|
||||
// layer that exists to restart a dead service would never have run.
|
||||
val shouldRun = masterEnabled && participating.isNotEmpty()
|
||||
if (shouldRun != wasEnabled) {
|
||||
if (shouldRun) enableServiceLayers() else disableServiceLayers()
|
||||
wasEnabled = shouldRun
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+1
-4
@@ -136,10 +136,7 @@ data class ActiveSubscriptionsState(
|
||||
* overstate every card, which is the mistake the per-entity rows already taught once.
|
||||
*/
|
||||
val attributedFilters: Int = 0,
|
||||
) {
|
||||
/** The largest purpose, so every card can draw its share against a common scale. */
|
||||
val busiestPurposeFilters: Int = accounts.flatMap { it.purposes }.maxOfOrNull { it.filterCount } ?: 0
|
||||
}
|
||||
)
|
||||
|
||||
class ActiveSubscriptionsViewModel : ViewModel() {
|
||||
private val _state = MutableStateFlow(ActiveSubscriptionsState())
|
||||
|
||||
Reference in New Issue
Block a user