Files
netrunner-app/src-tauri/src/plugins/vpn-plugin/android/README.md
T
Kirill c852315d34 Add decoy SNI plumbing, bundle wintun.dll, fix flag icons, add docs
- Прокидываем sni (decoy-хост) по обновлённому UDL через весь стек:
  guest-js -> Tauri-команда -> desktop/mobile -> Kotlin spawnSession.
  Список серверов пока статичный (backend еще не отдает sni), но логика
  похода в реальный /api/v1/nodes оставлена под флагом на будущее.
- Бандлим wintun.dll в Windows-инсталлятор через bundle.resources в
  tauri.windows.conf.json - раньше он копировался только для
  локального cargo run/tauri dev, но не попадал в NSIS/MSI.
- Чиним падение мобильной сборки: гитигнорённые UniFFI Kotlin-биндинги
  отстали от обновленного UDL (не хватало параметра sni).
- Флаги стран - локальные SVG вместо react-country-flag в CDN-режиме:
  тот бился об CSP и не грузился офлайн.
- Добавляем дерево README.md по структуре проекта и точечные
  комментарии в неочевидных местах кода.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-07-02 19:29:29 +07:00

4.1 KiB

Android-часть плагина

Нативный Kotlin-код, к которому обращается src/mobile.rs через PluginHandle::run_mobile_plugin. Отдельный Gradle-модуль (com.android.library), подключается в gen/android как :tauri-plugin-vpn — см. android/settings.gradle.

src/main/java/.../VpnPlugin.kt

Файл содержит два класса:

  • TunVpnService (android.net.VpnService) — foreground-сервис, который реально держит туннель: строит VpnService.Builder (адрес/DNS/MTU), сплит-туннелинг (allow-list для Telegram sandbox-режима или disallow-list для обычного режима — взаимоисключающе), отдаёт fd созданного TUN-интерфейса в SessionManager.spawnSession(...), крутит цикл статистики и рассылает статус/трафик через sendBroadcast. Вибро-фидбек при подключении/отключении.
  • VpnPlugin (@TauriPlugin) — мост Tauri-команд к сервису: startVpn запрашивает системное разрешение VPN (VpnService.prepare) перед стартом, stopVpn/checkActualVpnStatus/getInstalledApps/launchApp. Транслирует broadcast от TunVpnService в Tauri-события (trigger("status-change" / "traffic-stats", ...)), которые ловит guest-js на JS-стороне.

AndroidManifest.xml — разрешения INTERNET, FOREGROUND_SERVICE (specialUse), POST_NOTIFICATIONS, VIBRATE; <queries> для обнаружения установленных приложений (нужно для сплит-туннелинга).

⚠️ Обязательно прочитать до правок

SessionManager.spawnSession(...) — не обычный Kotlin-класс, а UniFFI-биндинг поверх нативной .so-библиотеки. Три вещи должны совпадать между собой всегда, иначе сборка падает (или, хуже, крашится в рантайме):

  1. Сигнатура spawn_session в .udl/lib.rs крейта netrunner_client (репозиторий netrunner-proxy/netrunner-core).
  2. android/src/main/java/uniffi/netrunner_client/netrunner_client.kt — сгенерированные Kotlin-биндинги.
  3. android/src/main/jniLibs/<abi>/libnetrunner_client.so — скомпилированная нативная библиотека.

Все три файла из пп. 2–3 гитигнорены (*uniffi, *jniLibs в .gitignore плагина) — они не часть репозитория, их нужно вручную регенерировать/копировать при каждом изменении .udl в netrunner-core:

# в репозитории netrunner-proxy
make build-android            # пересобирает .so под все ABI + генерит Kotlin-биндинги
                               # (tools/bindgen — обёртка над uniffi_bindgen_main)
# результат: gen/uniffi/netrunner_client/netrunner_client.kt
#            gen/<abi>/libnetrunner_client.so

# скопировать в netrunner-app:
cp gen/uniffi/netrunner_client/netrunner_client.kt \
   <netrunner-app>/src-tauri/src/plugins/vpn-plugin/android/src/main/java/uniffi/netrunner_client/
cp gen/<abi>/libnetrunner_client.so \
   <netrunner-app>/src-tauri/src/plugins/vpn-plugin/android/src/main/jniLibs/<abi>/

Забытый шаг копирования — уже реальная причина падения сборки (Kotlin компилятор ругается на несовпадение сигнатуры spawnSession, если .kt отстал от .so/UDL). Если сборка падает быстро (~секунды, до NDK-этапа) — проверяйте это в первую очередь.