fix metered vpn
This commit is contained in:
2 files changed
+70
-20
No files matched your search
@@ -8,6 +8,7 @@ import android.os.IBinder
|
||||
import android.os.ParcelFileDescriptor
|
||||
import android.util.Log
|
||||
import com.github.kr328.clash.core.ClashProcessStatus
|
||||
import com.github.kr328.clash.service.net.DefaultNetworkObserver
|
||||
|
||||
class TunService : VpnService() {
|
||||
companion object {
|
||||
@@ -28,11 +29,11 @@ class TunService : VpnService() {
|
||||
private const val PRIVATE_VLAN6_CLIENT = "fdfe:dcba:9876::1"
|
||||
}
|
||||
|
||||
private var fileDescriptor: ParcelFileDescriptor? = null
|
||||
private var clash: IClashService? = null
|
||||
private lateinit var fileDescriptor: ParcelFileDescriptor
|
||||
private lateinit var clash: IClashService
|
||||
private lateinit var defaultNetworkObserver: DefaultNetworkObserver
|
||||
private val connection = object: ServiceConnection {
|
||||
override fun onServiceDisconnected(name: ComponentName?) {
|
||||
clash = null
|
||||
stopSelf()
|
||||
}
|
||||
|
||||
@@ -66,16 +67,7 @@ class TunService : VpnService() {
|
||||
this@TunService.clash = clash
|
||||
}
|
||||
}
|
||||
private val networkChangedCallback = object: ConnectivityManager.NetworkCallback() {
|
||||
override fun onCapabilitiesChanged(
|
||||
network: Network,
|
||||
networkCapabilities: NetworkCapabilities
|
||||
) {
|
||||
val connectivity = getSystemService(ConnectivityManager::class.java)!!
|
||||
|
||||
setUnderlyingNetworks(connectivity.activeNetwork?.run { arrayOf(this) })
|
||||
}
|
||||
}
|
||||
|
||||
override fun onCreate() {
|
||||
super.onCreate()
|
||||
@@ -94,13 +86,19 @@ class TunService : VpnService() {
|
||||
.addRoute("::", 0)
|
||||
.setMtu(VPN_MTU)
|
||||
.setBlocking(false)
|
||||
.setUnderlyingNetworks(null)
|
||||
.setMeteredCompat(false)
|
||||
.establish() ?: throw NullPointerException("Unable to establish VPN")
|
||||
|
||||
bindService(Intent(this, ClashService::class.java), connection, Context.BIND_AUTO_CREATE)
|
||||
|
||||
getSystemService(ConnectivityManager::class.java)!!
|
||||
.registerDefaultNetworkCallback(networkChangedCallback)
|
||||
defaultNetworkObserver = DefaultNetworkObserver(this) {
|
||||
val data = getSystemService(ConnectivityManager::class.java)!!.getNetworkCapabilities(it)
|
||||
Log.d(TAG, "Network $data")
|
||||
|
||||
setUnderlyingNetworks(it?.run { arrayOf(this) })
|
||||
}
|
||||
|
||||
defaultNetworkObserver.register()
|
||||
}
|
||||
|
||||
override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int {
|
||||
@@ -110,15 +108,14 @@ class TunService : VpnService() {
|
||||
}
|
||||
|
||||
override fun onDestroy() {
|
||||
fileDescriptor?.close()
|
||||
fileDescriptor.close()
|
||||
|
||||
clash?.stopTunDevice()
|
||||
clash?.stop()
|
||||
clash.stopTunDevice()
|
||||
clash.stop()
|
||||
|
||||
unbindService(connection)
|
||||
|
||||
getSystemService(ConnectivityManager::class.java)!!
|
||||
.unregisterNetworkCallback(networkChangedCallback)
|
||||
defaultNetworkObserver.unregister()
|
||||
|
||||
super.onDestroy()
|
||||
}
|
||||
@@ -129,4 +126,10 @@ class TunService : VpnService() {
|
||||
}
|
||||
return this
|
||||
}
|
||||
|
||||
private fun Builder.setMeteredCompat(isMetered: Boolean): Builder {
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q)
|
||||
setMetered(isMetered)
|
||||
return this
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,47 @@
|
||||
// from https://github.com/shadowsocks/shadowsocks-android/blob/master/core/src/main/java/com/github/shadowsocks/net/DefaultNetworkListener.kt
|
||||
package com.github.kr328.clash.service.net
|
||||
|
||||
import android.content.Context
|
||||
import android.net.ConnectivityManager
|
||||
import android.net.Network
|
||||
import android.net.NetworkCapabilities
|
||||
import android.net.NetworkRequest
|
||||
|
||||
class DefaultNetworkObserver(val context: Context, val listener: (Network?) -> Unit) {
|
||||
private val connectivity = context.getSystemService(ConnectivityManager::class.java)!!
|
||||
private val active: Network?
|
||||
get() = connectivity.activeNetwork
|
||||
private var current: Network? = null
|
||||
private val callback = object: ConnectivityManager.NetworkCallback() {
|
||||
override fun onAvailable(network: Network) {
|
||||
current = active
|
||||
|
||||
listener(current)
|
||||
}
|
||||
|
||||
override fun onCapabilitiesChanged(
|
||||
network: Network,
|
||||
networkCapabilities: NetworkCapabilities
|
||||
) {
|
||||
if ( current == active )
|
||||
listener(active)
|
||||
}
|
||||
|
||||
override fun onLost(network: Network) {
|
||||
if ( active == current )
|
||||
current = null
|
||||
|
||||
listener(current)
|
||||
}
|
||||
}
|
||||
|
||||
fun register() {
|
||||
listener(active)
|
||||
|
||||
connectivity.registerDefaultNetworkCallback(callback)
|
||||
}
|
||||
|
||||
fun unregister() {
|
||||
connectivity.unregisterNetworkCallback(callback)
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user