50 lines
3.4 KiB
Markdown
50 lines
3.4 KiB
Markdown
# vojo proxy — agent onboarding
|
|
|
|
Native Android proxy client. App traffic is captured by a `VpnService` tun, fed through a
|
|
vendored native tun2socks engine into a **local** SOCKS5 server, then out to a real upstream
|
|
proxy (SOCKS5 / HTTP(S) / Shadowsocks). UI is Jetpack Compose; persistence is DataStore.
|
|
|
|
The repo-root [`README.md`](../README.md) is the product / Russian overview; this `docs/` set is
|
|
the agent map. It exists so an agent session can load context fast. Read in this order:
|
|
|
|
1. **[architecture.md](architecture.md)** — the data path, the component map, and *why* the
|
|
design is shaped this way (the local-SOCKS5-bridge, what runs native vs Kotlin).
|
|
2. **[building-testing.md](building-testing.md)** — how to build the APK and run the three
|
|
test layers (JVM unit tests, the interop harness, on-device QA).
|
|
3. **[conventions.md](conventions.md)** — code style, commit rules, and the **load-bearing
|
|
invariants** — choices that look wrong but are deliberate. Read this before "fixing" the
|
|
data path; several obvious-looking changes have already been tried and reverted.
|
|
|
|
## 60-second orientation
|
|
|
|
- **Language/stack:** Kotlin + Compose (Material3), coroutines, kotlinx-serialization,
|
|
DataStore Preferences. Native C: a vendored `hev-socks5-tunnel` + a thin JNI bridge.
|
|
- **Modules:** single Gradle module `:app`. `minSdk 28`, `compileSdk 35`, `arm64-v8a` only.
|
|
- **Package root:** `chat.vojo.proxy` (debug app id `chat.vojo.proxy.debug`).
|
|
- **Entry points:** `MainActivity` → `ui/MainScreen` (4 tabs: Туннель / Серверы / Приложения /
|
|
Опции). `service/ProxyVpnService` is the `VpnService`. `service/ProxyTileService` is the
|
|
quick-settings tile.
|
|
- **Single source of truth for state:** `data/ConfigStore` (persisted `ProxyState`) and
|
|
`service/VpnState` (live tunnel status/journal as `StateFlow`s).
|
|
- **No upstream "universal core".** sing-box / xray / clash are GPLv3 and would force
|
|
open-sourcing this closed app (and bloat the APK). The engine is `hev-socks5-tunnel` (MIT);
|
|
the Shadowsocks crypto and proxy clients are our own Kotlin, verified against canon. See
|
|
conventions.md before proposing a core swap.
|
|
|
|
## Where things live
|
|
|
|
| Area | Path |
|
|
|---|---|
|
|
| VpnService lifecycle, tun builder, probe, reaper | `app/src/main/java/chat/vojo/proxy/service/ProxyVpnService.kt` |
|
|
| Local loopback SOCKS5 server (hev talks to this) | `core/socks/LocalSocks5Server.kt` |
|
|
| Upstream clients | `core/upstream/{Socks5,Http,Shadowsocks}Upstream.kt`, `Upstream.kt` |
|
|
| Shadowsocks AEAD (SIP004) | `core/crypto/{ShadowsocksCrypto,ShadowsocksStream}.kt` |
|
|
| SOCKS address codec / stream utils | `core/net/{SocksAddress,StreamUtils}.kt` |
|
|
| Config model + share-link import | `core/ProxyConfig.kt`, `core/ConfigImport.kt` |
|
|
| Persistence / app list | `data/{ConfigStore,AppRepository}.kt` |
|
|
| UI | `ui/` (`MainScreen`, `ConnectionScreen`, `ServersScreen`, `AppsScreen`, `SettingsScreen`, `MainViewModel`) |
|
|
| Native (JNI bridge + engine) | `core/Tun2Socks.kt`, `app/src/main/jni/tun2socks.c`, `app/src/main/jni/hev-socks5-tunnel/` |
|
|
| Domain routing (matcher, geosite, direct dial) | `core/route/`, `core/upstream/DirectDialer.kt` |
|
|
| UI language (RU/EN, no AppCompat) | `core/LocaleManager.kt`, `res/values{,-ru}/strings.xml` |
|
|
| Dev tools (geosite refresh, device config injector) | `tools/fetch-geosite.sh`, `tools/mk_datastore.py` |
|
|
| Unit tests | `app/src/test/` |
|