- 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>
3.7 KiB
Build Guide
Prerequisites
| Tool | Version | Purpose |
|---|---|---|
| JDK | 17 | Android Gradle builds |
| Android SDK | 34 | Compile SDK |
| Android NDK | 26.1.10909125 | Native C++/Rust compilation |
| Rust | 1.85+ | Native engine (edition 2024) |
| cargo-ndk | latest | Cross-compile Rust → Android |
aarch64-linux-android target |
- | Rust target for ARM64 |
Install Rust Android target
rustup target add aarch64-linux-android
cargo install cargo-ndk
Environment Variables
export JAVA_HOME="/usr/lib/jvm/java-17-openjdk-amd64"
export ANDROID_HOME="$HOME/android-sdk"
export ANDROID_NDK_HOME="$ANDROID_HOME/ndk/26.1.10909125"
# For manual cargo-ndk builds (Gradle sets these automatically):
export CC_aarch64_linux_android="$ANDROID_NDK_HOME/toolchains/llvm/prebuilt/linux-x86_64/bin/aarch64-linux-android21-clang"
export CXX_aarch64_linux_android="$ANDROID_NDK_HOME/toolchains/llvm/prebuilt/linux-x86_64/bin/aarch64-linux-android21-clang++"
export AR_aarch64_linux_android="$ANDROID_NDK_HOME/toolchains/llvm/prebuilt/linux-x86_64/bin/llvm-ar"
Build Commands
Full Build (Gradle drives everything)
cd android
./gradlew assembleRelease
This runs:
cargoNdkBuildtask: invokescargo ndk -t arm64-v8a -o app/src/main/jniLibs build --release -p wzp-android- Compiles Kotlin/Compose code
- Packages APK with signing
Native Library Only
cargo ndk -t arm64-v8a -o android/app/src/main/jniLibs build --release -p wzp-android
Output: android/app/src/main/jniLibs/arm64-v8a/libwzp_android.so
Skip Native Rebuild
If the .so hasn't changed:
cd android
./gradlew assembleRelease -x cargoNdkBuild
Debug Build
cd android
./gradlew assembleDebug
Debug APK is ~8.9 MB (unstripped .so), release is ~6.9 MB.
Signing
Debug
Keystore: android/keystore/wzp-debug.jks
Password: android
Key alias: wzp-debug
Release
Keystore: android/keystore/wzp-release.jks
Password: wzphone2024
Key alias: wzp-release
Both keystores are checked into the repo for development convenience. For production, replace with proper key management.
Build Artifacts
| Artifact | Path | Size |
|---|---|---|
| Debug APK | android/app/build/outputs/apk/debug/app-debug.apk |
~8.9 MB |
| Release APK | android/app/build/outputs/apk/release/app-release.apk |
~6.9 MB |
| Native lib | android/app/src/main/jniLibs/arm64-v8a/libwzp_android.so |
~5 MB |
ABI Support
Currently only arm64-v8a (ARM64) is built. This covers 95%+ of modern Android devices.
To add more ABIs, edit build.gradle.kts:
ndk { abiFilters += listOf("arm64-v8a", "armeabi-v7a") }
And update the cargo-ndk command in cargoNdkBuild task:
commandLine("cargo", "ndk", "-t", "arm64-v8a", "-t", "armeabi-v7a", ...)
Oboe Dependency
The Oboe C++ audio library is fetched at build time by build.rs:
- Attempts
git cloneof Oboe 1.8.1 into$OUT_DIR/oboe - If successful, compiles
oboe_bridge.cppwith Oboe headers - If clone fails (no network), falls back to
oboe_stub.cpp(no-op audio)
This means first build requires internet to fetch Oboe. Subsequent builds use the cached checkout.
Common Build Issues
cargo ndk not found
cargo install cargo-ndk
Missing Android target
rustup target add aarch64-linux-android
NDK not found
Ensure ANDROID_NDK_HOME points to the NDK directory containing toolchains/llvm/.
C++ compilation errors
Check that CXX_aarch64_linux_android points to a valid clang++ from the NDK.
Gradle daemon issues
./gradlew --stop
./gradlew assembleRelease --no-daemon