Files
wz-phone/docs/android/roadmap.md
Claude 8d5f6fe044 feat: wire QUIC transport, JNI bridge, connect UI + add docs
- Replace raw FFI with proper `jni` crate for string marshalling
- Wire QUIC transport in engine: connect to relay, crypto handshake
  (CallOffer/CallAnswer, X25519+Ed25519), send/recv MediaPackets
- Feed received packets into jitter buffer (was previously ignored)
- Add connect screen UI with CALL button (idle state) and in-call
  controls (mute, speaker, hang up, live stats)
- Hardcode relay 172.16.81.125:4433, room "android"
- Add comprehensive docs in docs/android/:
  architecture.md (8 mermaid diagrams), build-guide.md,
  debugging.md, maintenance.md, roadmap.md

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-05 04:43:49 +00:00

113 lines
4.9 KiB
Markdown

# Roadmap & Known Gaps
## Current State Summary
The Android client can connect to a WZP relay, complete the crypto handshake, and exchange audio in real-time. Two phones on the same network can talk to each other through the relay.
## What Works (April 2025)
- QUIC transport to relay with room-based SFU
- Full crypto handshake (X25519 ephemeral + Ed25519 signatures)
- Opus 24kbps encoding/decoding at 48kHz
- Lock-free audio I/O via Oboe (capture + playout)
- AEC (acoustic echo cancellation) with 100ms tail
- AGC (automatic gain control)
- RaptorQ FEC encoder/decoder (wired to pipeline)
- Adaptive jitter buffer (10-250 packets)
- UI with connect/disconnect, mute, speaker, live stats
- Random identity seed per app launch
## Known Gaps
### P0 — Must fix for usable calls
| Gap | Impact | Where to fix |
|-----|--------|--------------|
| **Media encryption not applied** | Audio sent in cleartext over QUIC | `engine.rs` — pass `_session` to send/recv, encrypt/decrypt payloads |
| **FEC repair symbols not sent** | No loss recovery — audio gaps on packet loss | `engine.rs` send task — call `fec_encoder.generate_repair()` and send repair packets |
| **Quality reports not sent** | Relay can't monitor quality, no adaptive switching | `engine.rs` — periodically attach `QualityReport` to MediaPacket header |
| **CallService not started** | Call dies when app is backgrounded | `CallViewModel.startCall()` — call `CallService.start(context)` |
### P1 — Important for production
| Gap | Impact | Where to fix |
|-----|--------|--------------|
| **Hardcoded relay address** | Can't change server without rebuild | Add settings screen with `SharedPreferences` |
| **No reconnection logic** | Connection drop = call over | `engine.rs` network task — detect disconnect, retry with backoff |
| **No adaptive quality switching** | Stays on GOOD profile even in bad conditions | Wire `AdaptiveQualityController` to network path quality from `QuinnTransport` |
| **Identity seed not persisted** | New identity every launch | Save seed to Android Keystore or SharedPreferences |
| **No Bluetooth audio routing** | `AudioRouteManager` exists but not wired to UI | Add Bluetooth button to InCallScreen, call `AudioRouteManager` methods |
| **No ringtone/notification for incoming** | Only outgoing calls supported | Need signaling for call setup (currently both sides initiate independently) |
### P2 — Nice to have
| Gap | Impact | Where to fix |
|-----|--------|--------------|
| **No android_logger** | Rust tracing output lost on Android | Add `android_logger` crate, init in `nativeInit()` |
| **Stats don't include network metrics** | Loss/RTT/jitter always 0 | Feed `QuinnTransport.path_quality()` back to stats |
| **No ProGuard/R8 minification** | Release APK larger than necessary | Enable `isMinifyEnabled = true` in build.gradle.kts |
| **Single ABI (arm64-v8a)** | No support for older 32-bit devices or emulators | Add `armeabi-v7a` and `x86_64` to cargo-ndk build |
| **No call history** | Can't see past calls | Add Room database for call log |
| **No contact integration** | Manual relay/room entry | Add contacts with fingerprint-based identity |
## Architecture Evolution Plan
### Phase 1: Make Calls Reliable (current → next)
```
[x] QUIC connection to relay
[x] Crypto handshake
[x] Audio encode/decode pipeline
[ ] Media encryption (ChaCha20-Poly1305)
[ ] FEC repair packet transmission
[ ] Foreground service for background calls
[ ] Reconnection on network change
```
### Phase 2: Quality & Polish
```
[ ] Adaptive quality (GOOD → DEGRADED → CATASTROPHIC switching)
[ ] Quality reports in MediaPacket headers
[ ] Network path quality display (real RTT, loss, jitter)
[ ] Settings screen (relay, room, seed persistence)
[ ] Bluetooth/wired headset audio routing
[ ] Rust android_logger for debugging
```
### Phase 3: Production Features
```
[ ] featherChat authentication
[ ] Persistent identity (Android Keystore)
[ ] Push notifications for incoming calls
[ ] Multi-party rooms (already supported by relay)
[ ] Call transfer
[ ] End-to-end encryption (bypass relay decryption)
```
## Dependency Upgrade Path
### quinn 0.11 → 0.12 (when released)
Quinn 0.12 will likely require rustls 0.24. Update both together:
1. `Cargo.toml`: bump quinn and rustls versions
2. Check `client_config()` and `server_config()` in wzp-transport for API changes
3. DATAGRAM API may change — check `send_datagram()` / `read_datagram()`
### Compose BOM 2024.01 → 2025.x
The `LinearProgressIndicator` `progress` parameter changed from `Float` to `() -> Float` in Material3 1.2+. If upgrading the BOM:
```kotlin
// Old (current):
LinearProgressIndicator(progress = level, ...)
// New (Material3 1.2+):
LinearProgressIndicator(progress = { level }, ...)
```
### Kotlin 1.9 → 2.x
Kotlin 2.0 changed the Compose compiler plugin. Update `kotlinCompilerExtensionVersion` in `composeOptions` and the Kotlin Gradle plugin version together.