diff --git a/android/src/main/java/com/tailscale/ipn/IPNService.kt b/android/src/main/java/com/tailscale/ipn/IPNService.kt index ea2e54d..f67b800 100644 --- a/android/src/main/java/com/tailscale/ipn/IPNService.kt +++ b/android/src/main/java/com/tailscale/ipn/IPNService.kt @@ -10,8 +10,8 @@ import android.os.Build import android.system.OsConstants import androidx.core.app.NotificationCompat import androidx.core.app.NotificationManagerCompat -import java.util.UUID import libtailscale.Libtailscale +import java.util.UUID open class IPNService : VpnService(), libtailscale.IPNService { private val randomID: String = UUID.randomUUID().toString() @@ -44,9 +44,11 @@ open class IPNService : VpnService(), libtailscale.IPNService { return START_STICKY } - private fun close() { + override public fun close() { stopForeground(true) Libtailscale.serviceDisconnect(this) + val app = applicationContext as App + app.setWantRunning(false) } override fun onDestroy() { diff --git a/libtailscale/backend.go b/libtailscale/backend.go index 5932ee0..3def430 100644 --- a/libtailscale/backend.go +++ b/libtailscale/backend.go @@ -212,7 +212,7 @@ func (a *App) runBackend(ctx context.Context) error { if cfg.rcfg != nil && state >= ipn.Starting { if err := b.updateTUN(service, cfg.rcfg, cfg.dcfg); err != nil { log.Printf("VPN update failed: %v", err) - notifyVPNClosed() + service.Close() } } case s := <-onDisconnect: @@ -221,9 +221,6 @@ func (a *App) runBackend(ctx context.Context) error { netns.SetAndroidProtectFunc(nil) service = nil } - if state >= ipn.Starting { - notifyVPNClosed() - } case <-onDNSConfigChanged: if b != nil { go b.NetworkChanged() diff --git a/libtailscale/callbacks.go b/libtailscale/callbacks.go index 30daff1..bc3e489 100644 --- a/libtailscale/callbacks.go +++ b/libtailscale/callbacks.go @@ -10,9 +10,6 @@ import ( var ( // onVPNPrepared is notified when VpnService.prepare succeeds. onVPNPrepared = make(chan struct{}, 1) - // onVPNClosed is notified when VpnService.prepare fails, or when - // the a running VPN connection is closed. - onVPNClosed = make(chan struct{}, 1) // onVPNRevoked is notified whenever the VPN service is revoked. onVPNRevoked = make(chan struct{}, 1) @@ -51,13 +48,6 @@ func notifyVPNRevoked() { } } -func notifyVPNClosed() { - select { - case onVPNClosed <- struct{}{}: - default: - } -} - var android struct { // mu protects all fields of this structure. However, once a // non-nil jvm is returned from javaVM, all the other fields may diff --git a/libtailscale/interfaces.go b/libtailscale/interfaces.go index 9cd84ec..2aa7bb3 100644 --- a/libtailscale/interfaces.go +++ b/libtailscale/interfaces.go @@ -61,6 +61,8 @@ type IPNService interface { // NewBuilder creates a new VPNServiceBuilder in preparation for starting // the Android VPN. NewBuilder() VPNServiceBuilder + + Close() } // VPNServiceBuilder corresponds to Android's VpnService.Builder.