8.5 KiB
chatgui-android — этапы реализации и проверки
Документ описывает текущие точки входа и критерии проверки. Наличие реализации
не означает, что соответствующий сценарий выполнен на устройстве.
Архитектура и контракты: ARCHITECTURE.md, заголовки libutun_lite/ и jni_bridge/.
1. Сборка общего ядра
Реализовано: utun_sources.cmake использует общие lib/ и src/, включая ETCP,
STCP, NCD и группы/BGP. Android не требует отдельной реализации chat_sync и
не исключает UDP/маршрутизатор. Источники голосового стека собираются отдельно
через src/call/voice_sources.cmake. Итог NDK — libutun.so.
Проверять состав и исключения по app/src/main/cpp/CMakeLists.txt, а версии SDK,
NDK, JVM и ABI — по app/build.gradle.kts. Не создавать второй lite-instance или
локальную схему БД ради Android. UTUN-сервис управляется [gui] utun_enabled.
Сборка из корня репозитория:
./build.sh --no-gui -j4
cd tools/chatgui-android
./gradlew assembleDebug
Критерий: обе сборки завершились успешно; APK появился в
app/build/outputs/apk/debug/app-debug.apk. Сборка APK не подтверждает работу на устройстве.
2. Lifecycle и JNI
Реализовано: NativeLib.init сохраняет callbacks, start передаёт INI и создаёт worker,
SERVICE_STARTED подтверждает готовность. Restart пересоздаёт ядро; updateSockets
согласует [server:*] без рестарта. Код stop ждёт worker до двух секунд, после
таймаута возврат не подтверждает освобождение ресурсов.
Проверять последовательно: init → установка event callback → start → SERVICE_STARTED → рабочая команда → результат → остановка media workers → stop. Отдельно проверить restart и смену интерфейсов через updateSockets. Возврат nativeRestart/nativeUpdateSockets не является подтверждением применения конфигурации.
Критерий: события приходят в Kotlin, нет обращений по старым inst/ua, stop/restart не пересекаются с внешними I/O workers. Проверять категории sys/socket/connection/chat и сообщения lifecycle; при таймауте остановки сначала установить причину по логам.
3. Каналы, приглашения и личные беседы
Реализовано: Compose UI, ChatRepository с JSON/JNI и ViewModel/StateFlow; SQLite принадлежит общему ядру. Room/отдельный Kotlin SQL-reader не используются. InviteLink.kt вызывает общий native-кодек для предпросмотра и передаёт исходную ссылку JOIN-port с request ID. connectNode остался логирующей заглушкой.
Проверять на двух узлах: создать канал → запросить invite → дождаться готовой ссылки →
JOIN → CONNECT_RESULT → синхронизация участников и сообщений. Для сетевого baseline
на Linux использовать основной src/utun и tools/chatcli, описание команд —
../../chatcli_commands.txt. Android-каталог headless/ не запускает ядро и не подходит
для такого end-to-end сценария.
Критерий: request результата совпадает, сообщение появляется на другом узле, готовность JOIN и READY групповой сессии различается в диагностике. Для DM отдельно проверить поколения беседы: поздняя история/подготовленное вложение после удаления беседы не должны появиться в новом поколении.
4. Вложения, звонки, рация и трансляции
Реализовано: file/photo для каналов, общий attachment_send для voice/video каналов и DM, DM files, native голосовой стек звонка/рации, MediaCodec и независимые stream workers.
При проверке файлов учитывать владение: file/photo caller сохраняет до завершения копирования; принятые video/DM-file запросы забирают временный cache-файл и удаляют также при ошибке/отмене. Отказ постановки оставляет источник caller. Успешный return не подтверждает публикацию или доставку; смотреть события подготовки и отправки.
Для звонка/рации проверять capture/playback, PTT/auto, смену маршрута и остановку I/O до освобождения DSP. Для stream — KEY/revision, отдельные viewers, demand/pull, GAP/CLOSED, завершение аудио/видео и wake/освобождение signal.
Существующие native-проверки из корня репозитория:
make -C tests test_android_bridge test_android_replies test_android_udp_log test_android_stream test_standby test_standby_transport test_group_connect_standby
(cd tests && ./test_android_bridge && ./test_android_replies && ./test_android_udp_log && ./test_android_stream && ./test_standby && ./test_standby_transport && ./test_group_connect_standby)
test_android_bridge проверяет владение config callbacks, повторный init/destroy и покадровое/батчевое декодирование настоящих Opus-файлов (пять частот, mono/stereo, EOF). Эти тесты проверяют отдельные native-контракты, не весь Android lifecycle. Устройство с собранным APK: сценарий задержки video worker на 500мс, EOF/reset и независимых аппаратных аудиочасов — stream_worker_smoke. Критерии и зависимости заданы там; сетевой путь этим тестом не проверяется.
5. Фоновый сервис и диагностика устройства
Реализовано: HeadlessService как foreground service, сеть через NetworkChangeMonitor,
уведомления activity через NetworkActivityMonitor и native standby ACTIVE/SLEEP.
Отдельный Linux headless control socket не встроен в этот Android-сервис.
Общий headless API ядра требует явного [chatserver] headless_control_bind; параметр
controlPort у NativeLib.init listener не открывает.
Проверять: foreground → background → SLEEP → timer/ранний wake → foreground;
затем смену сети и restart. Уровни категорий задать до повторного прогона, чтобы
логи показывали причину перехода и согласованный набор сокетов.
UDP-лог настроить через [log_udp]; приёмник запускать по инструкции tools/logreceiver/.
После shutdown/restart не должно оставаться таймера старого uasync.
Критерий: ядро продолжает обслуживать события, standby-ожидания корректно будятся или отменяются, UI получает новое состояние; при ошибке причина видна в логах. Проверки на физическом устройстве выполняются отдельно от сборки и Linux-тестов.