Disconnecting the VPN from Android's own settings left "Revolt VPN
00:28:13" in the shade, frozen, for as long as the phone stayed up - a
notification claiming a protected session over a tunnel that was gone.
updateTimer() re-posts notification id 1 as ongoing and non-dismissible
from the UI process, every tick. The service cancels its own foreground
copy when it stops, but a tick landing just after that re-creates it as
an ordinary notification nobody owns, and nothing ever cancelled it:
NotificationService.reset() only clears the dedupe cache. AGENTS.md
rule 31 describes the cancel this restores.
_doDisconnect now cancels it, after vpnConnection.disconnect() so the
service is already down - cancelling while it is still in the foreground
would be swallowed by the platform.
Verified on an emulator, revoking via Settings -> VPN -> Disconnect:
before countdown stranded at 00:28:13 indefinitely
after no live notifications
User disconnect still posts no alert, and expiry still posts "Revolt VPN
disconnected" with the countdown gone.
Co-Authored-By: Claude Opus 5 <[email protected]>