# 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`; `` для обнаружения установленных приложений (нужно для сплит-туннелинга). ## ⚠️ Обязательно прочитать до правок **`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//libnetrunner_client.so` — скомпилированная нативная библиотека. Все три файла из пп. 2–3 **гитигнорены** (`*uniffi`, `*jniLibs` в `.gitignore` плагина) — они не часть репозитория, их нужно вручную регенерировать/копировать при каждом изменении `.udl` в `netrunner-core`: ```bash # в репозитории netrunner-proxy make build-android # пересобирает .so под все ABI + генерит Kotlin-биндинги # (tools/bindgen — обёртка над uniffi_bindgen_main) # результат: gen/uniffi/netrunner_client/netrunner_client.kt # gen//libnetrunner_client.so # скопировать в netrunner-app: cp gen/uniffi/netrunner_client/netrunner_client.kt \ /src-tauri/src/plugins/vpn-plugin/android/src/main/java/uniffi/netrunner_client/ cp gen//libnetrunner_client.so \ /src-tauri/src/plugins/vpn-plugin/android/src/main/jniLibs// ``` Забытый шаг копирования — уже реальная причина падения сборки (Kotlin компилятор ругается на несовпадение сигнатуры `spawnSession`, если `.kt` отстал от `.so`/UDL). Если сборка падает быстро (~секунды, до NDK-этапа) — проверяйте это в первую очередь.