1
0
mirror of git://f0xx.org/android_cast synced 2026-07-29 03:38:52 +03:00

sync with BE requested by AI Auto Agent

This commit is contained in:
Anton Afanasyeu
2026-06-05 12:54:41 +02:00
parent c5857e65f6
commit 617670ad96
11 changed files with 650 additions and 90 deletions

View File

@@ -0,0 +1,149 @@
# Opus / Speex / stream protection — validation checklist (task 3)
E2E validation guide for **audio codecs** and **UDP stream protection** (FEC, NACK, negotiation). Code is on **`next`**; this doc is the operator checklist.
**See also:** [ndk/README.md](../ndk/README.md), [ROADMAP.md](ROADMAP.md), [AV_QUALITY_QA_SESSION.md](AV_QUALITY_QA_SESSION.md).
## Table of contents
<!-- toc -->
- [Prerequisites](#prerequisites)
- [Automated baseline (CI / dev machine)](#automated-baseline-ci-dev-machine)
- [User settings (both peers)](#user-settings-both-peers)
- [Developer settings](#developer-settings)
- [E2E matrix — run on two devices](#e2e-matrix-run-on-two-devices)
- [What to capture per run](#what-to-capture-per-run)
- [Pass criteria](#pass-criteria)
- [Known limits (next)](#known-limits-next)
<!-- /toc -->
---
## Prerequisites
- Two Android devices (or sender + receiver) on **same LAN** for first pass; repeat subset on lossy/WAN if possible.
- Debug builds with NDK codecs built if testing native Opus/Speex probes:
```bash
./scripts/build-native-codecs.sh arm64-v8a # optional; see ndk/README.md
./gradlew :app:assembleDebug
```
---
## Automated baseline (CI / dev machine)
Run before field soak:
```bash
./gradlew :app:testDebugUnitTest --tests 'com.foxx.androidcast.network.transport.StreamProtectionNegotiatorTest'
./gradlew :app:testDebugUnitTest --tests 'com.foxx.androidcast.media.AudioNegotiatorTest'
./gradlew :app:testDebugUnitTest --tests 'com.foxx.androidcast.media.codec.*'
```
Or:
```bash
bash scripts/validate_opus_speex.sh
```
Expect **BUILD SUCCESSFUL** and all tests green.
---
## User settings (both peers)
**Global settings** (main UI):
| Control | Location | Notes |
|---------|----------|--------|
| Transport | Sender / receiver | Use **UDP** for FEC/NACK tests |
| Stream protection (UDP) | Global settings | Default **None**; try FEC 3/4, NACK, FEC+NACK |
| Audio codec | Global settings | **AUTO**, **Opus**, **Speex**, AAC baseline |
After changing protection, **start a new session** — negotiation runs at handshake (`CastSession` / `StreamProtectionNegotiator`).
---
## Developer settings
Enable **Developer options** on both devices if testing passthrough / debug audio:
| Control | Purpose |
|---------|---------|
| Passthrough / debug audio | `PASSTHROUGH_DEBUG` path |
| Codec overrides | Align with `CodecCatalog` / `PassthroughCodecPolicy` |
| Diagnostics export | Session stats + negotiated mime + protection string |
Check **session diagnostics** after connect: protection line should match `PassthroughCodecPolicy.protectionDescription()`.
---
## E2E matrix — run on two devices
Mark each cell **PASS / FAIL / SKIP** in a ticket tagged `20260604`.
### A. Handshake and negotiation
| # | Sender protection | Receiver capability | Audio | Expected |
|---|-------------------|---------------------|-------|----------|
| A1 | None | Any | AUTO | No FEC/NACK; stable video+audio |
| A2 | FEC 3/4 | FEC 3/4 | AUTO | Agreed FEC 3/4; loss recovery under artificial drop |
| A3 | NACK | NACK | AUTO | Retransmit under single-packet loss |
| A4 | FEC+NACK | FEC+NACK | AUTO | Combined behavior; no deadlock |
| A5 | FEC 3/4 | NONE only | AUTO | Prompt or downgrade per `StreamProtectionNegotiator` |
### B. Audio codec
| # | Sender audio | Receiver audio | Expected |
|---|--------------|----------------|----------|
| B1 | AUTO | AUTO | AAC or negotiated fallback |
| B2 | Opus | Opus | Opus native if `.so` present; else stub/fallback per `AudioNegotiator` |
| B3 | Speex | Speex | Speex native if built; else fallback |
| B4 | Opus | AUTO (no Opus) | Fallback — no silent failure |
### C. Controls (user vs developer)
| # | Check |
|---|--------|
| C1 | User can change transport UDP ↔ TCP without crash |
| C2 | User protection change applies on **next** session |
| C3 | Developer diagnostics show negotiated video mime + audio + protection |
| C4 | Receiver UI shows aligned protection label after handshake |
### D. Stress (optional)
| # | Check |
|---|--------|
| D1 | Background/rotate sender — session recovers or fails cleanly |
| D2 | ~5 min soak with FEC on — no memory runaway (logcat) |
| D3 | Switch WiFi ↔ mobile data mid-cast — defined behavior (fail or reconnect) |
---
## What to capture per run
1. **Diagnostics** export from both devices (or logcat filter `androidcast|CastSession|StreamProtection|AudioNegotiator`).
2. Negotiated lines: `negotiatedVideoMime`, `audioCodec`, `streamProtection`, `wantsNack`.
3. Subjective: audio dropouts, video freezes, recovery after packet loss (FEC/NACK test: weak WiFi or `tc netem` on Linux AP if available).
---
## Pass criteria
- All **automated** tests green (`validate_opus_speex.sh`).
- Matrix **A1A4** and **B1B2** pass on reference hardware.
- No unexplained **silent** fallback (user sees toast/prompt when negotiation downgrades).
- Diagnostics string matches actual wire behavior for UDP protection.
---
## Known limits (next)
| Item | Status |
|------|--------|
| Opus / Speex native encode | Probe + bridge; full native path per [ndk/README.md](../ndk/README.md) |
| FEC 3/4 + RS | Per-shard wire (`FecShardWire`); v1 monolithic still accepted |
| TCP transport | Protection spinners disabled / N/A for TCP |
File issues under Tickets → tag **`20260604`**, component Opus/Speex.

View File

@@ -35,6 +35,7 @@ Click a link to open a guide. Section links jump within the document (GitHub, Cu
| [GRAFANA_vs_others_graphvis_pivot.md](GRAFANA_vs_others_graphvis_pivot.md) | Custom graphs vs Grafana decision memo. |
| [INFRA.md](INFRA.md) | Production topology: Gentoo FE → Alpine BE, ports, nginx, sshfs. |
| [OPEN_API.md](OPEN_API.md) | Crash ingest API design, triage tags, heuristics. |
| [OPUS_SPEEX_VALIDATION.md](OPUS_SPEEX_VALIDATION.md) | Opus/Speex + UDP stream protection E2E checklist. |
| [OTA.md](OTA.md) | OTA channel layout v0, manifests, MQTT, publish flow. |
| [PRO_AAR.md](PRO_AAR.md) | cast-core / cast-pro AAR split and Play Billing. |
| [REMOTE_ACCESS_IMPL.md](REMOTE_ACCESS_IMPL.md) | WireGuard v1 impl + deploy |
@@ -77,6 +78,7 @@ Click a link to open a guide. Section links jump within the document (GitHub, Cu
- [PRO_AAR.md](PRO_AAR.md) — Pro AAR split
- [USB_HDMI_CAST.md](USB_HDMI_CAST.md) — HDMI / USB-tether
- [AV_QUALITY_QA_SESSION.md](AV_QUALITY_QA_SESSION.md) — AV enhancement Q&A
- [OPUS_SPEEX_VALIDATION.md](OPUS_SPEEX_VALIDATION.md) — codec + FEC/NACK field matrix ([§E2E matrix](OPUS_SPEEX_VALIDATION.md#e2e-matrix-run-on-two-devices))
---

View File

@@ -11,6 +11,7 @@ Companion to [REMOTE_ACCESS_IMPL.md](REMOTE_ACCESS_IMPL.md). Use this when verif
- [Scripts](#scripts)
- [Quick start (local orchestration)](#quick-start-local-orchestration)
- [Production / staging BE](#production--staging-be)
- [UDP / WireGuard data plane (`ra_udp_debug.sh`)](#udp--wireguard-data-plane-ra_udp_debugsh)
- [Optional: bring up WireGuard on Linux](#optional-bring-up-wireguard-on-linux)
- [Mobile vs CLI checklist](#mobile-vs-cli-checklist)
- [Troubleshooting](#troubleshooting)
@@ -47,6 +48,7 @@ All under `examples/crash_reporter/backend/scripts/`:
| `ra_e2e_cli.sh` | Full flow: disable → wait → whitelist → open → connect → close → disable |
| `test_remote_access_api.sh` | Minimal API smoke (grep, no jq) |
| `verify_remote_access_prod.sh` | BE preflight: config, wg tools, DB tables, optional smoke |
| `ra_udp_debug.sh` | DNS + UDP port + HTTP smoke + connect + `wg-quick` + ping BE (`10.66.66.1`) |
```bash
cd examples/crash_reporter/backend
@@ -110,6 +112,27 @@ RA_E2E=1 BASE="$CRASHES_BASE" ./scripts/verify_remote_access_prod.sh
---
## UDP / WireGuard data plane (`ra_udp_debug.sh`)
After HTTP E2E is green, run from a Linux laptop with `curl`, `jq`, `dig`, and optional `wireguard-tools`:
```bash
cd examples/crash_reporter/backend
export CRASHES_BASE=https://apps.f0xx.org/app/androidcast_project/crashes
export ADMIN_USER=admin ADMIN_PASS='…'
./scripts/ra_udp_debug.sh # DNS, UDP nc, HTTP smoke, connect, wg conf
./scripts/ra_udp_debug.sh --apply # also wg-quick up + ping 10.66.66.1 + teardown
```
Steps: CNAME check (`ra.apps.f0xx.org` → same A as `apps.f0xx.org`) → UDP `51820``test_remote_access_api.sh` → whitelist + open + poll connect → write `/tmp/ra-udp-<id>.conf`. With `--apply`, brings tunnel up and pings the BE WG address.
Skip HTTP re-check when control plane was just verified: `./scripts/ra_udp_debug.sh --skip-http --apply`.
See also [20260602_REVERSE_SSH_proposals_summary.md — Appendix 1](20260602_REVERSE_SSH_proposals_summary.md) (Linux laptop WG test).
---
## Optional: bring up WireGuard on Linux
After `poll --until connect` returns credentials: