Explorar el Código

Improve: disable network observer on screen off

kr328 hace 4 años
padre
commit
c7cb1dab38

+ 52 - 24
service/src/main/java/com/github/kr328/clash/service/clash/module/NetworkObserveModule.kt

@@ -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())
             }