Browse Source

Fix instance error handle

世界 3 years ago
parent
commit
7693e0af47

+ 8 - 3
app/src/main/java/io/nekohasekai/sagernet/bg/BaseService.kt

@@ -46,6 +46,7 @@ import kotlinx.coroutines.*
 import kotlinx.coroutines.sync.Mutex
 import kotlinx.coroutines.sync.withLock
 import libcore.AppStats
+import libcore.ErrorHandler
 import libcore.Libcore
 import libcore.TrafficListener
 import java.net.UnknownHostException
@@ -256,7 +257,7 @@ class BaseService {
 
         override fun stopListeningForBandwidth(cb: ISagerNetServiceCallback) {
             launch {
-                if (bandwidthListeners.remove(cb.asBinder()) != null && bandwidthListeners.isEmpty()) {
+                if (bandwidthListeners.remove(cb.asBinder()) != null && bandwidthListeners.isEmpty() && looper != null) {
                     looper!!.cancel()
                     looper = null
                 }
@@ -329,7 +330,7 @@ class BaseService {
 
         override fun stopListeningForStats(cb: ISagerNetServiceCallback) {
             launch {
-                if (statsListeners.remove(cb.asBinder()) != null && statsListeners.isEmpty()) {
+                if (statsListeners.remove(cb.asBinder()) != null && statsListeners.isEmpty() && statsLooper != null) {
                     statsLooper!!.cancel()
                     statsLooper = null
                 }
@@ -384,7 +385,7 @@ class BaseService {
         }
     }
 
-    interface Interface {
+    interface Interface : ErrorHandler {
         val data: Data
         val tag: String
         fun createNotification(profileName: String): ServiceNotification
@@ -461,6 +462,10 @@ class BaseService {
             }
         }
 
+        override fun handleError(err: String) {
+            stopRunner(false, err)
+        }
+
         fun persistStats() {
             Logs.w(Exception())
             data.proxy?.persistStats()

+ 4 - 2
app/src/main/java/io/nekohasekai/sagernet/bg/ExternalInstance.kt

@@ -23,10 +23,12 @@ import io.nekohasekai.sagernet.bg.proto.V2RayInstance
 import io.nekohasekai.sagernet.database.ProxyEntity
 import io.nekohasekai.sagernet.fmt.buildCustomConfig
 import io.nekohasekai.sagernet.ktx.Logs
+import libcore.ErrorHandler
 
 class ExternalInstance(
-    profile: ProxyEntity, val port: Int
-) : V2RayInstance(profile) {
+    profile: ProxyEntity, val port: Int, val errorHandler: ErrorHandler
+) : V2RayInstance(profile),
+    ErrorHandler by errorHandler {
 
     override fun init() {
         super.init()

+ 1 - 3
app/src/main/java/io/nekohasekai/sagernet/bg/VpnService.kt

@@ -373,9 +373,6 @@ class VpnService : BaseVpnService(),
             dumpUID = data.proxy!!.config.dumpUid
             trafficStats = DataStore.appTrafficStatistics
             pCap = DataStore.enablePcap
-            errorHandler = ErrorHandler {
-                stopRunner(false, it)
-            }
             if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
                 bindUpstream = Protector {
                     protect(it)
@@ -390,6 +387,7 @@ class VpnService : BaseVpnService(),
                 }
             }
 
+            errorHandler = this@VpnService
             protector = this@VpnService
         }
 

+ 8 - 5
app/src/main/java/io/nekohasekai/sagernet/bg/proto/ProxyInstance.kt

@@ -21,10 +21,8 @@ package io.nekohasekai.sagernet.bg.proto
 
 import cn.hutool.core.util.NumberUtil
 import com.v2ray.core.app.observatory.OutboundStatus
-import io.nekohasekai.sagernet.BuildConfig
 import io.nekohasekai.sagernet.SagerNet
 import io.nekohasekai.sagernet.bg.BaseService
-import io.nekohasekai.sagernet.bg.test.DebugInstance
 import io.nekohasekai.sagernet.database.DataStore
 import io.nekohasekai.sagernet.database.ProxyEntity
 import io.nekohasekai.sagernet.database.SagerDatabase
@@ -33,7 +31,9 @@ import io.nekohasekai.sagernet.ktx.runOnDefaultDispatcher
 import io.nekohasekai.sagernet.utils.DirectBoot
 import kotlinx.coroutines.Job
 import kotlinx.coroutines.runBlocking
+import libcore.ErrorHandler
 import libcore.Libcore
+import libcore.ObservatoryStatusUpdateListener
 import java.io.IOException
 import java.util.*
 import java.util.concurrent.ConcurrentHashMap
@@ -41,7 +41,9 @@ import kotlin.concurrent.timerTask
 
 class ProxyInstance(profile: ProxyEntity, val service: BaseService.Interface) : V2RayInstance(
     profile
-) {
+),
+    ObservatoryStatusUpdateListener,
+    ErrorHandler by service {
 
     lateinit var observatoryJob: Job
 
@@ -59,7 +61,7 @@ class ProxyInstance(profile: ProxyEntity, val service: BaseService.Interface) :
         super.launch()
 
         if (config.observerTag.isNotBlank()) {
-            v2rayPoint.setStatusUpdateListener(config.observerTag, ::sendObservatoryResult)
+            v2rayPoint.setStatusUpdateListener(config.observerTag, this)
             observatoryJob = runOnDefaultDispatcher {
                 sendInitStatuses()
             }
@@ -110,7 +112,8 @@ class ProxyInstance(profile: ProxyEntity, val service: BaseService.Interface) :
     val updateTimer = lazy { Timer("Observatory Timer") }
     val updateTasks by lazy { ConcurrentHashMap<Long, TimerTask>() }
 
-    fun sendObservatoryResult(statusPb: ByteArray?) {
+    @Throws(Exception::class)
+    override fun onUpdateObservatoryStatus(statusPb: ByteArray?) {
         if (statusPb == null || statusPb.isEmpty()) {
             return
         }

+ 5 - 3
app/src/main/java/io/nekohasekai/sagernet/bg/proto/V2RayInstance.kt

@@ -57,13 +57,15 @@ import io.nekohasekai.sagernet.fmt.trojan_go.buildTrojanGoConfig
 import io.nekohasekai.sagernet.ktx.*
 import io.nekohasekai.sagernet.plugin.PluginManager
 import kotlinx.coroutines.*
+import libcore.ErrorHandler
 import libcore.V2RayInstance
 import java.io.File
 import java.util.concurrent.atomic.AtomicBoolean
 
 abstract class V2RayInstance(
     val profile: ProxyEntity
-) : AbstractInstance {
+) : AbstractInstance,
+    ErrorHandler {
 
     lateinit var config: V2rayBuildResult
     lateinit var v2rayPoint: V2RayInstance
@@ -150,7 +152,7 @@ abstract class V2RayInstance(
                             }
                             else -> {
                                 externalInstances[port] = ExternalInstance(
-                                    profile, port
+                                    profile, port, this
                                 ).apply {
                                     init()
                                 }
@@ -340,7 +342,7 @@ abstract class V2RayInstance(
             }
         }
 
-        v2rayPoint.start()
+        v2rayPoint.start(this)
 
         if (config.requireWs) {
             val url = "http://$LOCALHOST:" + (config.wsPort) + "/"

+ 5 - 3
app/src/main/java/io/nekohasekai/sagernet/bg/test/V2RayTestInstance.kt

@@ -28,14 +28,17 @@ import io.nekohasekai.sagernet.ktx.runOnDefaultDispatcher
 import io.nekohasekai.sagernet.ktx.tryResume
 import io.nekohasekai.sagernet.ktx.tryResumeWithException
 import libcore.Libcore
+import kotlin.coroutines.Continuation
 import kotlin.coroutines.suspendCoroutine
 
 class V2RayTestInstance(profile: ProxyEntity, val link: String, val timeout: Int) : V2RayInstance(
     profile
 ) {
 
+    lateinit var continuation: Continuation<Int>
     suspend fun doTest(): Int {
         return suspendCoroutine { c ->
+            continuation = c
             processes = GuardedProcessPool {
                 Logs.w(it)
                 c.tryResumeWithException(it)
@@ -56,8 +59,7 @@ class V2RayTestInstance(profile: ProxyEntity, val link: String, val timeout: Int
         config = buildV2RayConfig(profile, true)
     }
 
-    override fun loadConfig() {
-        v2rayPoint.loadConfig(config.config)
+    override fun handleError(err: String) {
+        continuation.tryResumeWithException(Exception(err))
     }
-
 }

+ 1 - 1
external/v2ray-core

@@ -1 +1 @@
-Subproject commit 60450fe06380b87a6b8232e7945225bf81dd03ec
+Subproject commit c88631c40a71790ccc336783e26aceb691585401

+ 1 - 1
library/core

@@ -1 +1 @@
-Subproject commit 7856db5c653001fea1ec8353a67ecd77a3252889
+Subproject commit c2b144a2dfb26c267979d0111fa5b62c22272aa1