|
|
@@ -1,14 +1,16 @@
|
|
|
package com.github.kr328.clash.service.clash.module
|
|
|
|
|
|
import android.app.Service
|
|
|
+import android.content.Intent
|
|
|
import android.net.*
|
|
|
-import android.os.Build
|
|
|
+import android.os.PowerManager
|
|
|
import androidx.core.content.getSystemService
|
|
|
import com.github.kr328.clash.common.log.Log
|
|
|
import com.github.kr328.clash.core.Clash
|
|
|
import com.github.kr328.clash.service.util.resolveDns
|
|
|
import kotlinx.coroutines.NonCancellable
|
|
|
import kotlinx.coroutines.channels.Channel
|
|
|
+import kotlinx.coroutines.selects.select
|
|
|
import kotlinx.coroutines.withContext
|
|
|
|
|
|
class NetworkObserveModule(service: Service) :
|
|
|
@@ -18,23 +20,9 @@ class NetworkObserveModule(service: Service) :
|
|
|
private val connectivity = service.getSystemService<ConnectivityManager>()!!
|
|
|
private val networks: Channel<Network?> = Channel(Channel.CONFLATED)
|
|
|
private val request = NetworkRequest.Builder().apply {
|
|
|
- addTransportType(NetworkCapabilities.TRANSPORT_WIFI)
|
|
|
- addTransportType(NetworkCapabilities.TRANSPORT_BLUETOOTH)
|
|
|
- addTransportType(NetworkCapabilities.TRANSPORT_CELLULAR)
|
|
|
- addTransportType(NetworkCapabilities.TRANSPORT_ETHERNET)
|
|
|
addCapability(NetworkCapabilities.NET_CAPABILITY_NOT_VPN)
|
|
|
addCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET)
|
|
|
addCapability(NetworkCapabilities.NET_CAPABILITY_NOT_RESTRICTED)
|
|
|
- if (Build.VERSION.SDK_INT >= 26)
|
|
|
- addTransportType(NetworkCapabilities.TRANSPORT_WIFI_AWARE)
|
|
|
- if (Build.VERSION.SDK_INT >= 27)
|
|
|
- addTransportType(NetworkCapabilities.TRANSPORT_LOWPAN)
|
|
|
- if (Build.VERSION.SDK_INT >= 31)
|
|
|
- addTransportType(NetworkCapabilities.TRANSPORT_USB)
|
|
|
- if (Build.VERSION.SDK_INT == 23) { // workarounds for OEM bugs
|
|
|
- removeCapability(NetworkCapabilities.NET_CAPABILITY_VALIDATED)
|
|
|
- removeCapability(NetworkCapabilities.NET_CAPABILITY_CAPTIVE_PORTAL)
|
|
|
- }
|
|
|
}.build()
|
|
|
|
|
|
private val callback = object : ConnectivityManager.NetworkCallback() {
|
|
|
@@ -53,30 +41,70 @@ class NetworkObserveModule(service: Service) :
|
|
|
}
|
|
|
}
|
|
|
|
|
|
- override suspend fun run() {
|
|
|
- try {
|
|
|
+ private fun register(): Boolean {
|
|
|
+ return try {
|
|
|
connectivity.registerNetworkCallback(request, callback)
|
|
|
+
|
|
|
+ true
|
|
|
} catch (e: Exception) {
|
|
|
Log.w("Observe network changed: $e", e)
|
|
|
|
|
|
- return
|
|
|
+ false
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ private fun unregister(): Boolean {
|
|
|
+ try {
|
|
|
+ connectivity.unregisterNetworkCallback(callback)
|
|
|
+ } catch (e: Exception) {
|
|
|
+ // ignored
|
|
|
+ }
|
|
|
+
|
|
|
+ return false
|
|
|
+ }
|
|
|
+
|
|
|
+ override suspend fun run() {
|
|
|
+ val screenToggle = receiveBroadcast(false, Channel.CONFLATED) {
|
|
|
+ addAction(Intent.ACTION_SCREEN_ON)
|
|
|
+ addAction(Intent.ACTION_SCREEN_OFF)
|
|
|
+ }
|
|
|
+
|
|
|
+ if (service.getSystemService<PowerManager>()?.isInteractive != false) {
|
|
|
+ register()
|
|
|
}
|
|
|
|
|
|
try {
|
|
|
while (true) {
|
|
|
- val network = networks.receive()
|
|
|
+ val quit = select<Boolean> {
|
|
|
+ screenToggle.onReceive {
|
|
|
+ when (it.action) {
|
|
|
+ Intent.ACTION_SCREEN_ON ->
|
|
|
+ register()
|
|
|
+ Intent.ACTION_SCREEN_OFF ->
|
|
|
+ unregister()
|
|
|
+ else ->
|
|
|
+ false
|
|
|
+ }
|
|
|
+ }
|
|
|
+ networks.onReceive {
|
|
|
+ val dns = connectivity.resolveDns(it)
|
|
|
|
|
|
- val dns = connectivity.resolveDns(network)
|
|
|
+ Clash.notifyDnsChanged(dns)
|
|
|
|
|
|
- Clash.notifyDnsChanged(dns)
|
|
|
+ Log.d("Network changed, system dns = $dns")
|
|
|
|
|
|
- Log.d("Network changed, system dns = $dns")
|
|
|
+ enqueueEvent(NetworkChanged(it))
|
|
|
|
|
|
- enqueueEvent(NetworkChanged(network))
|
|
|
+ false
|
|
|
+ }
|
|
|
+ }
|
|
|
+ if (quit) {
|
|
|
+ return
|
|
|
+ }
|
|
|
}
|
|
|
} finally {
|
|
|
withContext(NonCancellable) {
|
|
|
- connectivity.unregisterNetworkCallback(callback)
|
|
|
+ unregister()
|
|
|
|
|
|
Clash.notifyDnsChanged(emptyList())
|
|
|
}
|