mirror of
https://github.com/d4rken-org/capod.git
synced 2026-09-14 18:26:11 -04:00
fix(monitor): Stop re-promoting a stale notification into a new session
This commit is contained in:
@@ -184,7 +184,15 @@ class MonitorService : Service() {
|
||||
override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int {
|
||||
// Every startForegroundService() re-arms the startForeground() obligation,
|
||||
// so every onStartCommand has to satisfy it again, no matter how it exits.
|
||||
if (!promoteToForeground(lastNotification ?: MonitorNotifications.createEarlyNotification(this))) {
|
||||
//
|
||||
// Only reuse the cached notification while a monitor session is actually live. It is a fully
|
||||
// built object whose `when` is frozen at build time, so re-promoting it to open a NEW session
|
||||
// would re-post the previous session's last content under its original timestamp — which is
|
||||
// how a stale "unknown device" frame survives a teardown/restart cycle. Rebuilding is not an
|
||||
// option here: this has to stay cheap enough to satisfy the obligation before DI is ready.
|
||||
val reusable = lastNotification?.takeIf { monitoringJob?.isActive == true }
|
||||
if (reusable == null) lastNotification = null
|
||||
if (!promoteToForeground(reusable ?: MonitorNotifications.createEarlyNotification(this))) {
|
||||
stopSelf(startId)
|
||||
return START_NOT_STICKY
|
||||
}
|
||||
|
||||
@@ -125,6 +125,28 @@ class MonitorServiceTest {
|
||||
shadowOf(service).lastForegroundNotificationId shouldBe MonitorNotifications.NOTIFICATION_ID
|
||||
}
|
||||
|
||||
/**
|
||||
* A built Notification's `when` is frozen, so re-promoting the previous session's last frame to
|
||||
* open a new one re-posts stale content under its original timestamp — the way an "unknown
|
||||
* device" placeholder survives a teardown/restart cycle.
|
||||
*/
|
||||
@Test
|
||||
fun `a start with no live monitor does not reuse the previous notification`() {
|
||||
val service = createService()
|
||||
service.readyForMonitoring()
|
||||
|
||||
val stale = notification("stale")
|
||||
service.postPrimaryNotification(stale)
|
||||
|
||||
// Monitor session has ended — the cached frame no longer reflects anything current.
|
||||
service.setField("monitoringJob", null)
|
||||
|
||||
service.onStartCommand(MonitorService.intent(context), 0, 1) shouldBe Service.START_STICKY
|
||||
|
||||
shadowOf(service).lastForegroundNotification shouldNotBeSameInstanceAs stale
|
||||
service.getField("lastNotification") shouldNotBeSameInstanceAs stale
|
||||
}
|
||||
|
||||
/**
|
||||
* The FGS notification can outlive `stopSelf()`. Leaving it up strands whatever content was last
|
||||
* posted — including the unknown-device placeholder built before the first BLE scan batch landed.
|
||||
|
||||
Reference in New Issue
Block a user