# Android Cast — alpha release & QA Last updated: 2026-05-23. Use this document for **feature freeze**, **alpha builds**, and **sign-off** before widening testing. **Related:** [ROADMAP.md](ROADMAP.md) · [README.md](../README.md) --- --- --- ## Table of contents - [Alpha scope (what we ship)](#alpha-scope-what-we-ship) - [Recommended defaults (both devices)](#recommended-defaults-both-devices) - [Feature freeze checklist (engineering)](#feature-freeze-checklist-engineering) - [Alpha app sign-off (manual QA)](#alpha-app-sign-off-manual-qa) - [A. Smoke (required — all must pass)](#a-smoke-required-all-must-pass) - [B. Resilience (required)](#b-resilience-required) - [C. Settings matrix (pick one row for official alpha demo)](#c-settings-matrix-pick-one-row-for-official-alpha-demo) - [D. Regression guards (quick)](#d-regression-guards-quick) - [E. Known limitations (not alpha blockers)](#e-known-limitations-not-alpha-blockers) - [Log capture (when something fails)](#log-capture-when-something-fails) - [Alpha backend (optional for LAN-only alpha)](#alpha-backend-optional-for-lan-only-alpha) - [Ending feature freeze](#ending-feature-freeze) **Documentation index:** [README.md](README.md) --- ## Alpha scope (what we ship) | In scope | Out of scope (frozen) | |----------|------------------------| | LAN discover → PIN → cast → stop | Internet relay, TLS on stream | | **UDP** or **TCP** transport (must match on both devices) | QUIC, WebRTC, USB-tether transport in UI | | H.264 + AAC (Android 10+ audio) | Passthrough video, Opus/Speex as default | | **Single receiver** per cast session | 1:N multi-receiver (disabled in `CastConfig`) | | Stream protection **None** (default) | FEC/NACK soak required for alpha sign-off | | Screen capture (full / user-choice on API 34+) | Secondary-display capture, Miracast in-app | | Camera cast (API 29+, best-effort) | Live sender mirror while casting | | Receiver playback + notification stop | Play Store / AdMob production | Code gate: `CastConfig.ALPHA_FEATURE_FREEZE = true` hides experimental transports and turns off multi-receiver selection. --- ## Recommended defaults (both devices) Set in **Settings** (or use fresh install defaults): | Setting | Sender | Receiver | |---------|--------|----------| | Transport | **UDP** | **UDP** | | Stream protection | **None** | **None** | | Quality | Medium | Medium | | Resolution | Adaptive (or HD 720p if rotation is shaky) | — | | Video codec | Auto | Auto | | Audio | On (if API 29+) | Play incoming audio: On | | Capture mode | Full screen (or User choice on Android 14+) | — | | PIN | Same on both (default `1234`) | Same | **Rotation soak:** On Mediatek / Freeme senders (e.g. BL6000), prefer **system rotation lock ON** during first alpha pass; then repeat with lock **OFF** to validate debounced reconfigure. --- ## Feature freeze checklist (engineering) | Item | Status | |------|--------| | `ALPHA_FEATURE_FREEZE` — UDP/TCP only in settings | Done | | Multi-receiver disabled for alpha | Done | | Stored QUIC/WebRTC transport clamped to UDP on load | Done | | Camera strings (permission vs unavailable) | Done | | README matches `CastConfig` / `CastSettings` defaults | Done | | Receiver: keyframe idle grace + debounced sender resize | Done (verify on soak) | | Preview paused during cast (single MediaProjection) | Done | | Developer-only: FEC, QUIC, USB-tether, immersive presets | Gated (dev settings) | --- ## Alpha app sign-off (manual QA) Run on **two physical devices**, same Wi‑Fi subnet. Record build: About / `versionName` from APK, git commit, date. ### A. Smoke (required — all must pass) | # | Step | Pass | |---|------|------| | A1 | Install same debug/release APK on sender + receiver | ☐ | | A2 | Receiver: **Receive** → Start listening → notification *Listening* / *Ready* | ☐ | | A3 | Sender: **Send** → discover receiver → correct PIN → approve capture | ☐ | | A4 | Video appears on receiver within **15 s** of auth | ☐ | | A5 | Audio audible (if enabled and API 29+) within **20 s** | ☐ | | A6 | Sender notification shows *Casting* with resolution | ☐ | | A7 | **Stop** from sender notification → stream ends, receiver returns to idle | ☐ | | A8 | **Stop** from receiver notification → sender stops cleanly | ☐ | | A9 | Second cast without reinstall (A2→A7 again) | ☐ | ### B. Resilience (required) | # | Step | Pass | |---|------|------| | B1 | Sender home → cast 5 min, no reboot / ANR | ☐ | | B2 | Receiver app to background 2 min → return → video recovers or clean idle | ☐ | | B3 | Receiver rotate once → video continues or recovers within 10 s | ☐ | | B4 | Sender rotate **with rotation lock ON** → 5 min stable | ☐ | | B5 | Sender rotate **with lock OFF** (optional / device-specific) → no permanent freeze; note if reboot | ☐ | ### C. Settings matrix (pick one row for official alpha demo) | Profile | Transport | Protection | Use | |---------|-----------|------------|-----| | **Alpha default** | UDP | None | Primary sign-off | | Fallback | TCP | None | If UDP glitches on your AP | | # | Step | Pass | |---|------|------| | C1 | UDP + None: 10 min soak | ☐ | | C2 | (Optional) TCP + None: 10 min soak | ☐ | ### D. Regression guards (quick) | # | Step | Pass | |---|------|------| | D1 | Wrong PIN → clear error, no crash | ☐ | | D2 | Mismatched transport (sender TCP / receiver UDP) → fails fast with message | ☐ | | D3 | Camera mode (if used): permission grant → cast 2 min | ☐ | | D4 | Calibration test mode → pattern on receiver | ☐ | ### E. Known limitations (not alpha blockers) - No TLS; LAN cleartext. - UDP may drop frames under congestion. - No live preview on sender while casting. - Some apps silent under playback capture policy. - Heavy rotation on some OEMs may still stress system WFD/WM (watchdog) — document device + lock state. **Alpha approved when:** all **A**, **B1–B4**, and **C1** pass on your reference sender + receiver pair. --- ## Log capture (when something fails) From repo root: ```bash ./scripts/alpha-qa-logcat.sh SENDER_SERIAL RECEIVER_SERIAL ``` Or manually: ```bash adb -s SENDER logcat -s ScreenCastService:* ReceiverCastService:* AndroidCast:* SenderScreenPreview:* adb -s RECEIVER logcat -s ReceiverCastService:* AndroidCast:* ``` --- ## Alpha backend (optional for LAN-only alpha) LAN demo does **not** require OTA/crash backend. For **full alpha** with updates and crash upload: | Item | Notes | |------|--------| | Host `examples/ota/v0/` | See [OTA.md](OTA.md) | | Deploy crash reporter | See [CRASH_REPORTER.md](CRASH_REPORTER.md) | | Configure URLs | Developer settings or `local.properties` | --- ## Ending feature freeze 1. Complete sign-off table above; note devices + APK build id in git tag message. 2. Tag release on `master` per [GIT_FLOW.md](GIT_FLOW.md). 3. To re-enable experiments on a dev branch: set `CastConfig.ALPHA_FEATURE_FREEZE = false` and restore `MULTI_RECEIVER_ENABLED` as needed. Post-alpha priorities: rotation-stable encode path, encoder thumbnail on sender, secondary-display capture (roadmap D).