fix android vpn permission grant (#2023)

* fix android vpn permission grant
* fix url input behaviour
This commit is contained in:
KKRainbow
2026-03-29 23:16:32 +08:00
committed by GitHub
parent 7e289865b2
commit a1bec48dc9
22 changed files with 496 additions and 162 deletions
@@ -14,6 +14,9 @@ class TauriVpnService : VpnService() {
companion object {
@JvmField var triggerCallback: (String, JSObject) -> Unit = { _, _ -> }
@JvmField var self: TauriVpnService? = null
@JvmField var ipv4Addr: String? = null
@JvmField var routes: Array<String> = emptyArray()
@JvmField var dns: String? = null
const val IPV4_ADDR = "IPV4_ADDR"
const val ROUTES = "ROUTES"
@@ -27,6 +30,9 @@ class TauriVpnService : VpnService() {
override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int {
println("vpn on start command ${intent?.getExtras()} $intent")
var args = intent?.getExtras()
ipv4Addr = args?.getString(IPV4_ADDR)
routes = args?.getStringArray(ROUTES) ?: emptyArray()
dns = args?.getString(DNS)
vpnInterface = createVpnInterface(args)
println("vpn created ${vpnInterface.fd}")
@@ -63,6 +69,13 @@ class TauriVpnService : VpnService() {
triggerCallback("vpn_service_stop", JSObject())
vpnInterface.close()
}
clearStatus()
}
private fun clearStatus() {
ipv4Addr = null
routes = emptyArray()
dns = null
}
private fun createVpnInterface(args: Bundle?): ParcelFileDescriptor {
@@ -3,7 +3,9 @@ package com.plugin.vpnservice
import android.app.Activity
import android.content.Intent
import android.net.VpnService
import androidx.activity.result.ActivityResult
import app.tauri.annotation.Command
import app.tauri.annotation.ActivityCallback
import app.tauri.annotation.InvokeArg
import app.tauri.annotation.TauriPlugin
import app.tauri.plugin.Invoke
@@ -48,46 +50,70 @@ class VpnServicePlugin(private val activity: Activity) : Plugin(activity) {
@Command
fun prepareVpn(invoke: Invoke) {
println("prepare vpn in plugin")
val it = VpnService.prepare(activity)
var ret = JSObject()
if (it != null) {
activity.startActivityForResult(it, 0x0f)
ret.put("errorMsg", "again")
activity.runOnUiThread {
println("prepare vpn in plugin")
val it = VpnService.prepare(activity)
if (it != null) {
startActivityForResult(invoke, it, "onPrepareVpnResult")
return@runOnUiThread
}
val ret = JSObject()
ret.put("granted", true)
invoke.resolve(ret)
}
}
@ActivityCallback
fun onPrepareVpnResult(invoke: Invoke, result: ActivityResult) {
val ret = JSObject()
ret.put("granted", result.resultCode == Activity.RESULT_OK)
invoke.resolve(ret)
}
@Command
fun startVpn(invoke: Invoke) {
val args = invoke.parseArgs(StartVpnArgs::class.java)
println("start vpn in plugin, args: $args")
activity.runOnUiThread {
println("start vpn in plugin, args: $args")
TauriVpnService.self?.onRevoke()
TauriVpnService.self?.onRevoke()
val it = VpnService.prepare(activity)
var ret = JSObject()
if (it != null) {
ret.put("errorMsg", "need_prepare")
} else {
var intent = Intent(activity, TauriVpnService::class.java)
intent.putExtra(TauriVpnService.IPV4_ADDR, args.ipv4Addr)
intent.putExtra(TauriVpnService.ROUTES, args.routes)
intent.putExtra(TauriVpnService.DNS, args.dns)
intent.putExtra(TauriVpnService.DISALLOWED_APPLICATIONS, args.disallowedApplications)
intent.putExtra(TauriVpnService.MTU, args.mtu)
val it = VpnService.prepare(activity)
val ret = JSObject()
if (it != null) {
ret.put("errorMsg", "need_prepare")
} else {
val intent = Intent(activity, TauriVpnService::class.java)
intent.putExtra(TauriVpnService.IPV4_ADDR, args.ipv4Addr)
intent.putExtra(TauriVpnService.ROUTES, args.routes)
intent.putExtra(TauriVpnService.DNS, args.dns)
intent.putExtra(TauriVpnService.DISALLOWED_APPLICATIONS, args.disallowedApplications)
intent.putExtra(TauriVpnService.MTU, args.mtu)
activity.startService(intent)
activity.startService(intent)
}
invoke.resolve(ret)
}
invoke.resolve(ret)
}
@Command
fun stopVpn(invoke: Invoke) {
println("stop vpn in plugin")
TauriVpnService.self?.onRevoke()
activity.stopService(Intent(activity, TauriVpnService::class.java))
println("stop vpn in plugin end")
invoke.resolve(JSObject())
activity.runOnUiThread {
println("stop vpn in plugin")
TauriVpnService.self?.onRevoke()
activity.stopService(Intent(activity, TauriVpnService::class.java))
println("stop vpn in plugin end")
invoke.resolve(JSObject())
}
}
@Command
fun getVpnStatus(invoke: Invoke) {
val ret = JSObject()
ret.put("running", TauriVpnService.self != null)
ret.put("ipv4Addr", TauriVpnService.ipv4Addr)
ret.put("routes", TauriVpnService.routes)
ret.put("dns", TauriVpnService.dns)
invoke.resolve(ret)
}
}