From d4cc1057a81ca76668066e979849a2fa094c25d7 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:Fixed latency test --- .../com/neko/v2ray/service/ProcessService.kt | 45 +++++++++ .../neko/v2ray/service/V2RayTestService.kt | 14 +-- .../kotlin/com/neko/v2ray/util/PluginUtil.kt | 93 ++++++++++--------- 3 files changed, 97 insertions(+), 55 deletions(-) create mode 100644 app/src/main/kotlin/com/neko/v2ray/service/ProcessService.kt diff --git a/app/src/main/kotlin/com/neko/v2ray/service/ProcessService.kt b/app/src/main/kotlin/com/neko/v2ray/service/ProcessService.kt new file mode 100644 index 00000000..6475f613 --- /dev/null +++ b/app/src/main/kotlin/com/neko/v2ray/service/ProcessService.kt @@ -0,0 +1,45 @@ +package com.neko.v2ray.service + +import android.content.Context +import android.util.Log +import com.neko.v2ray.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/app/src/main/kotlin/com/neko/v2ray/service/V2RayTestService.kt b/app/src/main/kotlin/com/neko/v2ray/service/V2RayTestService.kt index 4c9a1869..148e1e94 100644 --- a/app/src/main/kotlin/com/neko/v2ray/service/V2RayTestService.kt +++ b/app/src/main/kotlin/com/neko/v2ray/service/V2RayTestService.kt @@ -3,7 +3,6 @@ package com.neko.v2ray.service import android.app.Service import android.content.Intent import android.os.IBinder -import android.util.Log import com.neko.v2ray.AppConfig.MSG_MEASURE_CONFIG import com.neko.v2ray.AppConfig.MSG_MEASURE_CONFIG_CANCEL import com.neko.v2ray.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/app/src/main/kotlin/com/neko/v2ray/util/PluginUtil.kt b/app/src/main/kotlin/com/neko/v2ray/util/PluginUtil.kt index 1e48332e..3cd80cb9 100644 --- a/app/src/main/kotlin/com/neko/v2ray/util/PluginUtil.kt +++ b/app/src/main/kotlin/com/neko/v2ray/util/PluginUtil.kt @@ -6,50 +6,77 @@ import android.util.Log import com.neko.v2ray.AppConfig.ANG_PACKAGE import com.neko.v2ray.dto.EConfigType import com.neko.v2ray.dto.ServerConfig +import com.neko.v2ray.service.ProcessService import com.neko.v2ray.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 + procService = ProcessService() + procService.runProcess(context, cmd) + } + } + + fun stopPlugin() { + stopHy2() + } + + fun realPingHy2(context: Context, config: ServerConfig?): Long { + Log.d(TAG, "realPingHy2") + val retFailure = -1L - val configFile = File(context.noBackupFilesDir, "hy2_${SystemClock.elapsedRealtime()}.json") - Log.d(packageName, "runPlugin ${configFile.absolutePath}") + 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) - configFile.parentFile?.mkdirs() - configFile.writeText(JsonUtil.toJson(hy2Config)) - Log.d(packageName, JsonUtil.toJson(hy2Config)) + val proc = ProcessService() + proc.runProcess(context, cmd) + Thread.sleep(1000L) + val delay = SpeedtestUtil.testConnection(context, socksPort) + proc.stopProcess() - runHy2(context, configFile) + return delay.first } + return retFailure } - fun stopPlugin() { - stopHy2() + 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 runHy2(context: Context, configFile: File) { - val cmd = mutableListOf( + private fun genCmdHy2(context: Context, configFile: File): MutableList { + return mutableListOf( File(context.applicationInfo.nativeLibraryDir, HYSTERIA2).absolutePath, //initPlugin(HYSTERIA2).path, "--disable-update-check", @@ -59,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