From 635581719b80d028884064e4bb1d8c9b6ac2c67e Mon Sep 17 00:00:00 2001 From: 2dust <31833384+2dust@users.noreply.github.com> Date: Tue, 1 Oct 2024 11:30:55 +0800 Subject: [PATCH] Fix latency test --- .../com/v2ray/ang/service/ProcessService.kt | 45 +++++++++ .../com/v2ray/ang/service/V2RayTestService.kt | 14 +-- .../kotlin/com/v2ray/ang/util/PluginUtil.kt | 96 ++++++++++--------- 3 files changed, 98 insertions(+), 57 deletions(-) create mode 100644 V2rayNG/app/src/main/kotlin/com/v2ray/ang/service/ProcessService.kt diff --git a/V2rayNG/app/src/main/kotlin/com/v2ray/ang/service/ProcessService.kt b/V2rayNG/app/src/main/kotlin/com/v2ray/ang/service/ProcessService.kt new file mode 100644 index 00000000..e88f7a29 --- /dev/null +++ b/V2rayNG/app/src/main/kotlin/com/v2ray/ang/service/ProcessService.kt @@ -0,0 +1,45 @@ +package com.v2ray.ang.service + +import android.content.Context +import android.util.Log +import com.v2ray.ang.AppConfig.ANG_PACKAGE +import kotlinx.coroutines.CoroutineScope +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.launch + +class ProcessService { + private val TAG = ANG_PACKAGE + private lateinit var process: Process + + fun runProcess(context: Context, cmd: MutableList) { + Log.d(TAG, cmd.toString()) + + try { + val proBuilder = ProcessBuilder(cmd) + proBuilder.redirectErrorStream(true) + process = proBuilder + .directory(context.filesDir) + .start() + + CoroutineScope(Dispatchers.IO).launch { + Thread.sleep(50L) + Log.d(TAG, "runProcess check") + process.waitFor() + Log.d(TAG, "runProcess exited") + } + Log.d(TAG, process.toString()) + + } catch (e: Exception) { + Log.d(TAG, e.toString()) + } + } + + fun stopProcess() { + try { + Log.d(TAG, "runProcess destroy") + process?.destroy() + } catch (e: Exception) { + Log.d(TAG, e.toString()) + } + } +} \ No newline at end of file diff --git a/V2rayNG/app/src/main/kotlin/com/v2ray/ang/service/V2RayTestService.kt b/V2rayNG/app/src/main/kotlin/com/v2ray/ang/service/V2RayTestService.kt index b90efdfd..3e12f8b0 100644 --- a/V2rayNG/app/src/main/kotlin/com/v2ray/ang/service/V2RayTestService.kt +++ b/V2rayNG/app/src/main/kotlin/com/v2ray/ang/service/V2RayTestService.kt @@ -3,7 +3,6 @@ package com.v2ray.ang.service import android.app.Service import android.content.Intent import android.os.IBinder -import android.util.Log import com.v2ray.ang.AppConfig.MSG_MEASURE_CONFIG import com.v2ray.ang.AppConfig.MSG_MEASURE_CONFIG_CANCEL import com.v2ray.ang.AppConfig.MSG_MEASURE_CONFIG_SUCCESS @@ -59,17 +58,8 @@ class V2RayTestService : Service() { val server = MmkvManager.decodeServerConfig(guid) ?: return retFailure if (server.getProxyOutbound()?.protocol?.equals(EConfigType.HYSTERIA2.name, true) == true) { - val socksPort = Utils.findFreePort(listOf(0)) - PluginUtil.runPlugin(this, server, "0:${socksPort}") - Thread.sleep(1000L) - - var delay = SpeedtestUtil.testConnection(this, socksPort) - if (delay.first < 0) { - Thread.sleep(10L) - delay = SpeedtestUtil.testConnection(this, socksPort) - } - PluginUtil.stopPlugin() - return delay.first + val delay = PluginUtil.realPingHy2(this, server) + return delay } else { val config = V2rayConfigUtil.getV2rayConfig(this, guid) if (!config.status) { diff --git a/V2rayNG/app/src/main/kotlin/com/v2ray/ang/util/PluginUtil.kt b/V2rayNG/app/src/main/kotlin/com/v2ray/ang/util/PluginUtil.kt index bb585ca1..08616856 100644 --- a/V2rayNG/app/src/main/kotlin/com/v2ray/ang/util/PluginUtil.kt +++ b/V2rayNG/app/src/main/kotlin/com/v2ray/ang/util/PluginUtil.kt @@ -3,45 +3,33 @@ package com.v2ray.ang.util import android.content.Context import android.os.SystemClock import android.util.Log - import com.v2ray.ang.AppConfig.ANG_PACKAGE import com.v2ray.ang.dto.EConfigType import com.v2ray.ang.dto.ServerConfig +import com.v2ray.ang.service.ProcessService import com.v2ray.ang.util.fmt.Hysteria2Fmt -import kotlinx.coroutines.CoroutineScope -import kotlinx.coroutines.Dispatchers -import kotlinx.coroutines.launch import java.io.File object PluginUtil { //private const val HYSTERIA2 = "hysteria2-plugin" private const val HYSTERIA2 = "libhysteria2.so" - private const val packageName = ANG_PACKAGE - private lateinit var process: Process + private const val TAG = ANG_PACKAGE + private lateinit var procService: ProcessService // fun initPlugin(name: String): PluginManager.InitResult { // return PluginManager.init(name)!! // } fun runPlugin(context: Context, config: ServerConfig?, domainPort: String?) { - Log.d(packageName, "runPlugin") + Log.d(TAG, "runPlugin") val outbound = config?.getProxyOutbound() ?: return if (outbound.protocol.equals(EConfigType.HYSTERIA2.name, true)) { - Log.d(packageName, "runPlugin $HYSTERIA2") + val configFile = genConfigHy2(context, config, domainPort) ?: return + val cmd = genCmdHy2(context, configFile) - val socksPort = domainPort?.split(":")?.last() - .let { if (it.isNullOrEmpty()) return else it.toInt() } - val hy2Config = Hysteria2Fmt.toNativeConfig(config, socksPort) ?: return - - val configFile = File(context.noBackupFilesDir, "hy2_${SystemClock.elapsedRealtime()}.json") - Log.d(packageName, "runPlugin ${configFile.absolutePath}") - - configFile.parentFile?.mkdirs() - configFile.writeText(JsonUtil.toJson(hy2Config)) - Log.d(packageName, JsonUtil.toJson(hy2Config)) - - runHy2(context, configFile) + procService = ProcessService() + procService.runProcess(context, cmd) } } @@ -49,8 +37,46 @@ object PluginUtil { stopHy2() } - private fun runHy2(context: Context, configFile: File) { - val cmd = mutableListOf( + fun realPingHy2(context: Context, config: ServerConfig?): Long { + Log.d(TAG, "realPingHy2") + val retFailure = -1L + + val outbound = config?.getProxyOutbound() ?: return retFailure + if (outbound.protocol.equals(EConfigType.HYSTERIA2.name, true)) { + val socksPort = Utils.findFreePort(listOf(0)) + val configFile = genConfigHy2(context, config, "0:${socksPort}") ?: return retFailure + val cmd = genCmdHy2(context, configFile) + + val proc = ProcessService() + proc.runProcess(context, cmd) + Thread.sleep(1000L) + val delay = SpeedtestUtil.testConnection(context, socksPort) + proc.stopProcess() + + return delay.first + } + return retFailure + } + + private fun genConfigHy2(context: Context, config: ServerConfig, domainPort: String?): File? { + Log.d(TAG, "runPlugin $HYSTERIA2") + + val socksPort = domainPort?.split(":")?.last() + .let { if (it.isNullOrEmpty()) return null else it.toInt() } + val hy2Config = Hysteria2Fmt.toNativeConfig(config, socksPort) ?: return null + + val configFile = File(context.noBackupFilesDir, "hy2_${SystemClock.elapsedRealtime()}.json") + Log.d(TAG, "runPlugin ${configFile.absolutePath}") + + configFile.parentFile?.mkdirs() + configFile.writeText(JsonUtil.toJson(hy2Config)) + Log.d(TAG, JsonUtil.toJson(hy2Config)) + + return configFile + } + + private fun genCmdHy2(context: Context, configFile: File): MutableList { + return mutableListOf( File(context.applicationInfo.nativeLibraryDir, HYSTERIA2).absolutePath, //initPlugin(HYSTERIA2).path, "--disable-update-check", @@ -60,34 +86,14 @@ object PluginUtil { "warn", "client" ) - Log.d(packageName, cmd.toString()) - - try { - val proBuilder = ProcessBuilder(cmd) - proBuilder.redirectErrorStream(true) - process = proBuilder - .directory(context.filesDir) - .start() - - CoroutineScope(Dispatchers.IO).launch { - Thread.sleep(500L) - Log.d(packageName, "$HYSTERIA2 check") - process.waitFor() - Log.d(packageName, "$HYSTERIA2 exited") - } - Log.d(packageName, process.toString()) - - } catch (e: Exception) { - Log.d(packageName, e.toString()) - } } private fun stopHy2() { try { - Log.d(packageName, "$HYSTERIA2 destroy") - process?.destroy() + Log.d(TAG, "$HYSTERIA2 destroy") + procService?.stopProcess() } catch (e: Exception) { - Log.d(packageName, e.toString()) + Log.d(TAG, e.toString()) } } } \ No newline at end of file