diff --git a/android/app/src/main/kotlin/net/defined/mobile_nebula/MainActivity.kt b/android/app/src/main/kotlin/net/defined/mobile_nebula/MainActivity.kt index 3597041..2738c4b 100644 --- a/android/app/src/main/kotlin/net/defined/mobile_nebula/MainActivity.kt +++ b/android/app/src/main/kotlin/net/defined/mobile_nebula/MainActivity.kt @@ -195,16 +195,11 @@ class MainActivity: FlutterActivity() { private fun stopSite() { val intent = Intent(this, NebulaVpnService::class.java) - intent.putExtra("COMMAND", "STOP") + intent.setAction(NebulaVpnService.ACTION_STOP) - //This is odd but stopService goes nowhere in my tests and this is correct - // according to the official example https://android.googlesource.com/platform/development/+/master/samples/ToyVpn/src/com/example/android/toyvpn/ToyVpnClient.java#116 + // We can't stopService because we have to close the fd first. The service will call stopSelf when ready. + // See the official example: https://android.googlesource.com/platform/development/+/master/samples/ToyVpn/src/com/example/android/toyvpn/ToyVpnClient.java#116 startService(intent) - //TODO: why doesn't this work!?!? -// if (serviceIntent != null) { -// Log.e(TAG, "stopping ${serviceIntent.toString()}") -// stopService(serviceIntent) -// } } private fun activeListHostmap(call: MethodCall, result: MethodChannel.Result) { diff --git a/android/app/src/main/kotlin/net/defined/mobile_nebula/NebulaVpnService.kt b/android/app/src/main/kotlin/net/defined/mobile_nebula/NebulaVpnService.kt index 3b06673..da64c14 100644 --- a/android/app/src/main/kotlin/net/defined/mobile_nebula/NebulaVpnService.kt +++ b/android/app/src/main/kotlin/net/defined/mobile_nebula/NebulaVpnService.kt @@ -18,6 +18,7 @@ class NebulaVpnService : VpnService() { companion object { private const val TAG = "NebulaVpnService" + const val ACTION_STOP = "net.defined.mobile_nebula.STOP" const val MSG_REGISTER_CLIENT = 1 const val MSG_UNREGISTER_CLIENT = 2 const val MSG_IS_RUNNING = 3 @@ -40,10 +41,10 @@ class NebulaVpnService : VpnService() { private var nebula: mobileNebula.Nebula? = null private var vpnInterface: ParcelFileDescriptor? = null private var didSleep = false - private var networkCallback: NetworkCallback = NetworkCallback(); + private var networkCallback: NetworkCallback = NetworkCallback() override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int { - if (intent?.getStringExtra("COMMAND") == "STOP") { + if (intent?.getAction() == ACTION_STOP) { stopVpn() return Service.START_NOT_STICKY } @@ -103,7 +104,7 @@ class NebulaVpnService : VpnService() { try { vpnInterface = builder.establish() - nebula = mobileNebula.MobileNebula.newNebula(site!!.config, site!!.getKey(this), site!!.logFile, vpnInterface!!.fd.toLong()) + nebula = mobileNebula.MobileNebula.newNebula(site!!.config, site!!.getKey(this), site!!.logFile, vpnInterface!!.detachFd().toLong()) } catch (e: Exception) { Log.e(TAG, "Got an error $e") @@ -115,7 +116,7 @@ class NebulaVpnService : VpnService() { registerNetworkCallback() //TODO: There is an open discussion around sleep killing tunnels or just changing mobile to tear down stale tunnels //registerSleep() - + nebula!!.start() running = true sendSimple(MSG_IS_RUNNING, if (running) 1 else 0) @@ -170,14 +171,25 @@ class NebulaVpnService : VpnService() { } private fun stopVpn() { + if (nebula == null) { + return stopSelf() + } + unregisterNetworkCallback() nebula?.stop() - vpnInterface?.close() + nebula = null running = false announceExit(site?.id, null) + stopSelf() } - override fun onDestroy() { + override fun onRevoke() { + stopVpn() + //TODO: wait for the thread to exit + super.onRevoke() + } + + override fun onDestroy() { stopVpn() //TODO: wait for the thread to exit super.onDestroy() @@ -240,7 +252,7 @@ class NebulaVpnService : VpnService() { m.data.putString("data", res) msg.replyTo.send(m) } - + private fun getHostInfo(msg: Message) { if (protect(msg)) { return } @@ -258,7 +270,7 @@ class NebulaVpnService : VpnService() { m.data.putString("data", res) msg.replyTo.send(m) } - + private fun closeTunnel(msg: Message) { if (protect(msg)) { return } @@ -300,4 +312,4 @@ class NebulaVpnService : VpnService() { messenger = Messenger(IncomingHandler(this)) return messenger.binder } -} \ No newline at end of file +}