Browse Source

Fix Windows stream test and compact Android call diagnostics

master
evgeny 4 days ago
parent
commit
b88d76a8ab
  1. 46
      tests/test_stream_core.c
  2. 46
      tools/chatgui-android/app/src/main/java/com/utun/chat/ui/screens/CallScreen.kt
  3. 4
      tools/chatgui-android/app/src/main/res/values-ru/strings.xml
  4. 4
      tools/chatgui-android/app/src/main/res/values/strings.xml

46
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");
}

46
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))
}

4
tools/chatgui-android/app/src/main/res/values-ru/strings.xml

@ -373,8 +373,8 @@
<string name="address_unknown">"неизвестный (%1$d)"</string>
<string name="file_save_failed">"Не удалось сохранить файл"</string>
<string name="transfer_key_confirm">"Передать приватный ключ канала участнику «%1$s»?\n\nКлюч передаётся зашифрованным и подписанным. Получатель станет совладельцем и сможет управлять участниками."</string>
<string name="call_stats">"Буфер: %1$s мс · Запас: %2$s мс\nЗа 10 с: минимум %3$s · максимум %4$s мс\nСкорость: %5$s× · RTT: %6$s мс\nПотери буфера: %7$s · Недостачи: %8$s"</string>
<string name="call_output_stats">"Аудиовыход: %2$s мс (включая очередь приложения: %1$s мс)"</string>
<string name="call_stats">"Буфер %1$s · запас %2$s мс\nМин–макс за 10 с: %3$s–%4$s мс\nТемп %5$s× · RTT %6$s мс\nСбросы %7$s · недостачи %8$s"</string>
<string name="call_output_stats">"Выход %2$s мс · из них очередь %1$s мс"</string>
<plurals name="bgp_nodes">
<item quantity="one">BGP: %1$d узел</item>
<item quantity="few">BGP: %1$d узла</item>

4
tools/chatgui-android/app/src/main/res/values/strings.xml

@ -374,8 +374,8 @@
<string name="address_unknown">"unknown (%1$d)"</string>
<string name="file_save_failed">"Could not save file"</string>
<string name="transfer_key_confirm">"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."</string>
<string name="call_stats">"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"</string>
<string name="call_output_stats">"Audio output: %2$s ms (includes app queue: %1$s ms)"</string>
<string name="call_stats">"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"</string>
<string name="call_output_stats">"Output %2$s ms · includes queue %1$s ms"</string>
<plurals name="bgp_nodes">
<item quantity="one">BGP: %1$d node</item>
<item quantity="other">BGP: %1$d nodes</item>

Loading…
Cancel
Save