Skip to content

BraveVPNService.onDestroy: STOP_FOREGROUND_REMOVE so notification clears on stop#2695

Open
dsremo wants to merge 1 commit into
celzero:mainfrom
dsremo:dsremo/stopforeground-remove
Open

BraveVPNService.onDestroy: STOP_FOREGROUND_REMOVE so notification clears on stop#2695
dsremo wants to merge 1 commit into
celzero:mainfrom
dsremo:dsremo/stopforeground-remove

Conversation

@dsremo
Copy link
Copy Markdown
Contributor

@dsremo dsremo commented May 25, 2026

Problem

BraveVPNService.onDestroy() currently calls:

```kotlin
ServiceCompat.stopForeground(this, ServiceCompat.STOP_FOREGROUND_DETACH)
```

STOP_FOREGROUND_DETACH strips the service's foreground status while leaving the persistent notification visible. After the user taps Stop (or the service is destroyed via any other path), the "RethinkDNS protected" notification lingers until the user either manually swipes it away or the service is re-created. This is confusing UX: the user has just stopped the VPN, yet sees what looks like an "active" notification.

Fix

Switch to STOP_FOREGROUND_REMOVE:

```kotlin
ServiceCompat.stopForeground(this, ServiceCompat.STOP_FOREGROUND_REMOVE)
```

REMOVE clears the notification along with the foreground flag — which is what onDestroy() actually wants: this is the final cleanup, not a "keep showing the user we're still around" stop.

Why this is safe

  • ServiceCompat.stopForeground is the AndroidX shim that handles the API-level differences. Both STOP_FOREGROUND_REMOVE and STOP_FOREGROUND_DETACH are supported on all API levels this app targets.
  • This is onDestroy() — the service is going away anyway. Whether the foreground notification is detached-and-left-visible vs detached-and-removed is purely a UI-cleanup choice; service lifecycle is unchanged.
  • No tunnel/network impact. The VPN tunnel is already being torn down via stopVpnAdapter and related cleanup earlier in onDestroy.

Tested

  • Built debug APK, installed.
  • Started VPN, verified persistent notification appears with "VPN active" / similar.
  • Tapped Stop from in-app.
  • After this fix: notification clears immediately along with the service. Before the fix: notification stays visible until manually dismissed or until next service start.
  • Repeated the cycle 5x — no leaked or duplicate notifications.

…EMOVE

The current `stopForeground(STOP_FOREGROUND_DETACH)` only strips the service's
foreground status while leaving the persistent VPN notification visible. After
the user taps Stop (or the service is otherwise destroyed), the "RethinkDNS
protected" notification lingers until the user swipes it away manually or the
service is re-created.

`STOP_FOREGROUND_REMOVE` removes the notification along with the foreground
flag, which matches the actual lifecycle intent at this code point — onDestroy
is the final cleanup, not a "keep showing the user we're still around" stop.

Single-line change. ServiceCompat.stopForeground is API-compatible across all
the minSdk range this app supports.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant