From b88d76a8abba3a6bd3f7c1f4346294dd60421ed1 Mon Sep 17 00:00:00 2001 From: evgeny Date: Thu, 15 Oct 2026 18:35:08 +0200 Subject: [PATCH] Fix Windows stream test and compact Android call diagnostics --- tests/test_stream_core.c | 46 +++++++++---------- .../com/utun/chat/ui/screens/CallScreen.kt | 46 ++++++++++--------- .../app/src/main/res/values-ru/strings.xml | 4 +- .../app/src/main/res/values/strings.xml | 4 +- 4 files changed, 51 insertions(+), 49 deletions(-) diff --git a/tests/test_stream_core.c b/tests/test_stream_core.c index ab13f5fc..54c5e82d 100644 --- a/tests/test_stream_core.c +++ b/tests/test_stream_core.c @@ -507,36 +507,36 @@ static void test_source_timer(void) { /* Близкий сосед, цена дополнительных hops и проблем сравниваются в одних единицах, неизвестный RTT не становится нулём. */ static void test_supplier_score(void) { - struct stream_receive_info near = {.rtt_ms = 10, .path_rtt_ms = 80, .rtt_valid = 1, .path_rtt_valid = 1, .path = {.count = 3}}; - struct stream_receive_info far = {.rtt_ms = 45, .path_rtt_ms = 40, .rtt_valid = 1, .path_rtt_valid = 1, .path = {.count = 2}}; + struct stream_receive_info near_peer = {.rtt_ms = 10, .path_rtt_ms = 80, .rtt_valid = 1, .path_rtt_valid = 1, .path = {.count = 3}}; + struct stream_receive_info far_peer = {.rtt_ms = 45, .path_rtt_ms = 40, .rtt_valid = 1, .path_rtt_valid = 1, .path = {.count = 2}}; struct stream_metric_snapshot clean = {.blocks = 100}, late = {.blocks = 100, .late_blocks = 2}; - CHECK(stream_supplier_score(&near, &clean, 1) == 109 && stream_supplier_score(&far, &clean, 1) == 136); - /* Обычная сумма RTT предпочла бы far (85 < 90); удвоенный RTT соседа предпочитает near. */ - CHECK(stream_supplier_score(&near, &clean, 1) < stream_supplier_score(&far, &clean, 1)); - CHECK(stream_supplier_score(&near, &late, 1) == 129); - CHECK(stream_supplier_score(&near, &late, 1) < stream_supplier_score(&far, &clean, 1)); + CHECK(stream_supplier_score(&near_peer, &clean, 1) == 109 && stream_supplier_score(&far_peer, &clean, 1) == 136); + /* Обычная сумма RTT предпочла бы far_peer (85 < 90); удвоенный RTT соседа предпочитает near_peer. */ + CHECK(stream_supplier_score(&near_peer, &clean, 1) < stream_supplier_score(&far_peer, &clean, 1)); + CHECK(stream_supplier_score(&near_peer, &late, 1) == 129); + CHECK(stream_supplier_score(&near_peer, &late, 1) < stream_supplier_score(&far_peer, &clean, 1)); late.late_blocks = 3; - CHECK(stream_supplier_score(&near, &late, 1) > stream_supplier_score(&far, &clean, 1)); - far = near; far.rtt_ms = 9; far.path.count = 4; - CHECK(stream_supplier_score(&far, &clean, 1) == 110); - CHECK(stream_supplier_score(&near, &clean, 1) < stream_supplier_score(&far, &clean, 1)); + CHECK(stream_supplier_score(&near_peer, &late, 1) > stream_supplier_score(&far_peer, &clean, 1)); + far_peer = near_peer; far_peer.rtt_ms = 9; far_peer.path.count = 4; + CHECK(stream_supplier_score(&far_peer, &clean, 1) == 110); + CHECK(stream_supplier_score(&near_peer, &clean, 1) < stream_supplier_score(&far_peer, &clean, 1)); late = (struct stream_metric_snapshot){.blocks = 4, .late_blocks = 1, .stops = 7}; - CHECK(stream_supplier_score(&near, &late, 1) == 369); + CHECK(stream_supplier_score(&near_peer, &late, 1) == 369); late.lag_ms = STREAM_LATE_MS; - CHECK(stream_supplier_score(&near, &late, 1) == 369); + CHECK(stream_supplier_score(&near_peer, &late, 1) == 369); late.lag_ms++; - CHECK(stream_supplier_score(&near, &late, 1) == 1109); + CHECK(stream_supplier_score(&near_peer, &late, 1) == 1109); late.lag_ms = 0; late.stopped = 1; - CHECK(stream_supplier_score(&near, &late, 1) == 1109); + CHECK(stream_supplier_score(&near_peer, &late, 1) == 1109); late.stopped = 0; late.late_blocks = late.blocks; - CHECK(stream_supplier_score(&near, &late, 1) == 1109); /* История остановок не превышает лимит штрафа. */ - CHECK(stream_supplier_score(&near, &late, 0) == 109); - near.rtt_valid = 0; - CHECK(stream_supplier_score(&near, &clean, 1) == UINT64_MAX); - near.rtt_valid = 1; near.path_rtt_valid = 0; - CHECK(stream_supplier_score(&near, &clean, 1) == UINT64_MAX); - near.path_rtt_valid = 1; near.rtt_ms = near.path_rtt_ms = UINT32_MAX; - CHECK(stream_supplier_score(&near, &late, 1) == 3 * (uint64_t)UINT32_MAX + 1009); + CHECK(stream_supplier_score(&near_peer, &late, 1) == 1109); /* История остановок не превышает лимит штрафа. */ + CHECK(stream_supplier_score(&near_peer, &late, 0) == 109); + near_peer.rtt_valid = 0; + CHECK(stream_supplier_score(&near_peer, &clean, 1) == UINT64_MAX); + near_peer.rtt_valid = 1; near_peer.path_rtt_valid = 0; + CHECK(stream_supplier_score(&near_peer, &clean, 1) == UINT64_MAX); + near_peer.path_rtt_valid = 1; near_peer.rtt_ms = near_peer.path_rtt_ms = UINT32_MAX; + CHECK(stream_supplier_score(&near_peer, &late, 1) == 3 * (uint64_t)UINT32_MAX + 1009); DEBUG_INFO(DEBUG_CATEGORY_STREAM, "[PASS] supplier score: nearby peer, hop cost, problem tradeoffs, 1000ms cap, unknown and wide RTT"); } diff --git a/tools/chatgui-android/app/src/main/java/com/utun/chat/ui/screens/CallScreen.kt b/tools/chatgui-android/app/src/main/java/com/utun/chat/ui/screens/CallScreen.kt index eeef9d5b..e6d7b0fc 100644 --- a/tools/chatgui-android/app/src/main/java/com/utun/chat/ui/screens/CallScreen.kt +++ b/tools/chatgui-android/app/src/main/java/com/utun/chat/ui/screens/CallScreen.kt @@ -43,6 +43,7 @@ import androidx.compose.ui.graphics.vector.ImageVector import androidx.compose.ui.input.pointer.pointerInput import androidx.compose.ui.platform.LocalContext import androidx.compose.ui.platform.LocalView +import androidx.compose.ui.text.PlatformTextStyle import androidx.compose.ui.text.font.FontWeight import androidx.compose.ui.text.style.TextAlign import androidx.compose.ui.unit.dp @@ -240,28 +241,29 @@ fun CallScreen( fontSize = 16.sp ) Spacer(Modifier.height(8.dp)) - Text(stringResource(R.string.connection_label, st?.connectionType?.label ?: stringResource(R.string.connection_none)), - color = Color(0xFFAEBCC8), fontSize = 13.sp) - val bgpPath = st?.bgpPath ?: "" - if (bgpPath.isNotEmpty()) { - Spacer(Modifier.height(8.dp)) - Text( - bgpPath, - color = Color(0xFFAEBCC8), - fontSize = 13.sp - ) - } - if (phase == CallPhase.ACTIVE) st?.stats?.let { stats -> - Spacer(Modifier.height(8.dp)) - Text(stringResource(R.string.call_stats, stats.bufferMs, stats.reserveMs, - stats.minMs, stats.maxMs, "%.2f".format(stats.tempoX100 / 100.0), stats.rttMs, stats.dropped, stats.underruns), - modifier = Modifier.padding(horizontal = 16.dp), color = Color(0xFFAEBCC8), - fontSize = 12.sp, textAlign = TextAlign.Center) - Text(stringResource(R.string.call_output_stats, - stats.output.queueMs.takeIf { it >= 0 }?.toString() ?: "—", - stats.output.outputMs.takeIf { it >= 0 }?.toString() ?: "—"), - modifier = Modifier.padding(horizontal = 16.dp), color = Color(0xFFAEBCC8), - fontSize = 12.sp, textAlign = TextAlign.Center) + ProvideTextStyle(MaterialTheme.typography.bodySmall.copy( + color = Color(0xFFAEBCC8), fontSize = 12.sp, lineHeight = 14.sp, + textAlign = TextAlign.Center, platformStyle = PlatformTextStyle(includeFontPadding = false) + )) { + Column(Modifier.fillMaxWidth().padding(horizontal = 16.dp), + horizontalAlignment = Alignment.CenterHorizontally, verticalArrangement = Arrangement.spacedBy(2.dp)) { + LaunchedEffect(Unit) { + LogManager.addLog("DEBUG", "call", "compact call diagnostics shown: font=12sp lineHeight=14sp gap=2dp") + } + Text(stringResource(R.string.connection_label, st?.connectionType?.label ?: stringResource(R.string.connection_none)), + modifier = Modifier.fillMaxWidth()) + val bgpPath = st?.bgpPath ?: "" + if (bgpPath.isNotEmpty()) Text(bgpPath, modifier = Modifier.fillMaxWidth()) + if (phase == CallPhase.ACTIVE) st?.stats?.let { stats -> + Text(stringResource(R.string.call_stats, stats.bufferMs, stats.reserveMs, + stats.minMs, stats.maxMs, "%.2f".format(stats.tempoX100 / 100.0), stats.rttMs, stats.dropped, stats.underruns), + modifier = Modifier.fillMaxWidth()) + Text(stringResource(R.string.call_output_stats, + stats.output.queueMs.takeIf { it >= 0 }?.toString() ?: "—", + stats.output.outputMs.takeIf { it >= 0 }?.toString() ?: "—"), + modifier = Modifier.fillMaxWidth()) + } + } } Spacer(Modifier.height(40.dp)) } diff --git a/tools/chatgui-android/app/src/main/res/values-ru/strings.xml b/tools/chatgui-android/app/src/main/res/values-ru/strings.xml index 2eaef868..fc5157f8 100644 --- a/tools/chatgui-android/app/src/main/res/values-ru/strings.xml +++ b/tools/chatgui-android/app/src/main/res/values-ru/strings.xml @@ -373,8 +373,8 @@ "неизвестный (%1$d)" "Не удалось сохранить файл" "Передать приватный ключ канала участнику «%1$s»?\n\nКлюч передаётся зашифрованным и подписанным. Получатель станет совладельцем и сможет управлять участниками." - "Буфер: %1$s мс · Запас: %2$s мс\nЗа 10 с: минимум %3$s · максимум %4$s мс\nСкорость: %5$s× · RTT: %6$s мс\nПотери буфера: %7$s · Недостачи: %8$s" - "Аудиовыход: %2$s мс (включая очередь приложения: %1$s мс)" + "Буфер %1$s · запас %2$s мс\nМин–макс за 10 с: %3$s–%4$s мс\nТемп %5$s× · RTT %6$s мс\nСбросы %7$s · недостачи %8$s" + "Выход %2$s мс · из них очередь %1$s мс" BGP: %1$d узел BGP: %1$d узла diff --git a/tools/chatgui-android/app/src/main/res/values/strings.xml b/tools/chatgui-android/app/src/main/res/values/strings.xml index d5d5a23c..40cdec22 100644 --- a/tools/chatgui-android/app/src/main/res/values/strings.xml +++ b/tools/chatgui-android/app/src/main/res/values/strings.xml @@ -374,8 +374,8 @@ "unknown (%1$d)" "Could not save file" "Send the channel private key to “%1$s”?\n\nThe key is transferred encrypted and signed. The recipient will become a co-owner and will be able to manage members." - "Buffer: %1$s ms · Reserve: %2$s ms\nOver 10 s: min %3$s · max %4$s ms\nSpeed: %5$s× · RTT: %6$s ms\nBuffer drops: %7$s · Underruns: %8$s" - "Audio output: %2$s ms (includes app queue: %1$s ms)" + "Buffer %1$s · reserve %2$s ms\nMin–max over 10 s: %3$s–%4$s ms\nTempo %5$s× · RTT %6$s ms\nDrops %7$s · underruns %8$s" + "Output %2$s ms · includes queue %1$s ms" BGP: %1$d node BGP: %1$d nodes