# AGENTS.md This file provides guidance to Codex (Codex.ai/code) when working with code in this repository. ## Project Overview TeamSpeak Android native client with a two-layer architecture: - **Protocol layer**: Go + [teamspeak-go](https://github.com/honeybbq/teamspeak-go) → compiled to `.aar` via gomobile - **UI layer**: Kotlin + Jetpack Compose + Material Design 3 ## Build Commands ### Full Build (Recommended) ```bash # Windows build.bat # Linux/macOS ./build.sh ``` ### Manual Build (Two Steps Required) **Step 1: Compile Go → AAR** ```bash cd go set JAVA_TOOL_OPTIONS=-Dfile.encoding=UTF-8 -Dsun.jnu.encoding=UTF-8 # Windows only gomobile bind -target=android -androidapi=26 -ldflags="-linkmode=external -extldflags=-Wl,--hash-style=both" -o ../android/app/libs/teamspeak.aar ./teamspeak ``` **Step 2: Build Android APK** ```bash cd android gradlew.bat assembleDebug # Windows ./gradlew assembleDebug # Linux/macOS ``` ### Development Workflow - **Modified Go code** (`go/`): Re-run Step 1, then run from IDE - **Modified Kotlin code** (`android/`): Just run from IDE (IntelliJ/Android Studio) Open the `android/` directory (not root) in IntelliJ IDEA or Android Studio. ## Architecture ### Go ↔ Kotlin Bridge Communication flows through two bridge layers: 1. **Go side** (`go/teamspeak/bridge.go`): Exports `TSClient` class via gomobile 2. **Kotlin side** (`android/app/src/main/java/com/tsmobile/app/TSBridge.kt`): Wraps gomobile API **Key constraints** (gomobile limitations): - Cannot export `[]string`, `[]*T`, or Go `error` types - Complex data passed as JSON strings (channels, clients) - Events delivered via callback interfaces - All JNI callbacks serialized through an event queue to avoid threading issues **Event flow**: Go library → event queue → single consumer goroutine → JNI callback → Kotlin callback → ViewModel ### Android Layer Structure ``` android/app/src/main/java/com/tsmobile/app/ ├── MainActivity.kt # Entry point ├── TSBridge.kt # Go bridge wrapper ├── ui/ │ ├── components/ # Reusable UI components │ ├── screens/ # Top-level screens │ ├── navigation/NavGraph.kt # App navigation │ └── theme/ # Material Design 3 theme └── viewmodel/ # State management ├── ChannelViewModel.kt # Channel list & navigation ├── ChatViewModel.kt # Text messaging ├── ServerViewModel.kt # Connection & server info └── VoiceViewModel.kt # Voice communication ``` State flows from ViewModels → Screens via `StateFlow`. User actions flow back via ViewModel methods. ## Critical Build Details ### Required Flags for gomobile The `-ldflags` are **mandatory** to avoid runtime crashes: 1. **`-linkmode=external`**: Use NDK's external linker instead of Go's built-in linker - **Why**: Prevents `SIGSEGV` crashes due to signal handling conflicts between Go runtime and Android - Go uses SIGSEGV for GC and goroutine scheduling; Android's memory protection blocks this 2. **`-extldflags=-Wl,--hash-style=both`**: Generate compatible ELF hash tables - **Why**: Go 1.24+ uses `DT_SUNW_HASH` by default; Android requires `DT_HASH` or `DT_GNU_HASH` - Without this: `dlopen failed: empty/missing DT_HASH/DT_GNU_HASH` error ### Local Patches The `go/_patches/github.com/honeybbq/teamspeak-go/` directory contains modified upstream code: - Fixes 32-bit integer overflow issues (`math.MaxUint32` → platform-specific limits) - Applied via `go.mod` replace directive: `replace github.com/honeybbq/teamspeak-go => ./_patches/github.com/honeybbq/teamspeak-go` Do not remove this directory or the replace directive. ## Common Issues ### "javac: 非法字符" or "GBK unmappable character" Set encoding before running gomobile on Windows: ```bash set JAVA_TOOL_OPTIONS=-Dfile.encoding=UTF-8 -Dsun.jnu.encoding=UTF-8 ``` ### App crashes with "SIGSEGV" on startup Missing `-linkmode=external` flag. Rebuild AAR with correct flags. ### App crashes with "empty/missing DT_HASH" Missing `-Wl,--hash-style=both` flag. Rebuild AAR with correct flags. ### "Unresolved reference: teamspeak" AAR not compiled or not in `android/app/libs/teamspeak.aar`. Run Step 1 of manual build. ## Testing Run from IDE with connected device or emulator. Check Logcat in IDE for runtime logs. No automated test suite currently exists.