# Android Cast — implementation roadmap Last updated: 2026-05-23. Living document — refine as alpha and commercial tracks progress. --- --- ## Table of contents - [Alpha definition](#alpha-definition) - [Alpha app checklist](#alpha-app-checklist) - [Alpha backend checklist](#alpha-backend-checklist) - [Product positioning](#product-positioning) - [USB-C / HDMI (roadmap D) and USB-tether cast (roadmap E)](#usb-c-hdmi-roadmap-d-and-usb-tether-cast-roadmap-e) - [Commercial (Play Store prep)](#commercial-play-store-prep) - [Crash console open API](#crash-console-open-api) - [Stream protection (FEC / NACK)](#stream-protection-fec-nack) - [libvpx / Opus / Speex](#libvpx-opus-speex) - [Transports & protocols](#transports-protocols) - [Receiver / sender UX](#receiver-sender-ux) - [Deferred / post-alpha](#deferred-post-alpha) - [Related docs](#related-docs) **Documentation index:** [README.md](README.md) --- ## Alpha definition | Track | Goal | Status | |-------|------|--------| | **Android app** | Stable, feature-rich, **demo-ready** on LAN (discover → PIN → cast → stop; soak two devices) | Core path done; polish UX/docs and gate experimental options for show | | **Backend** | Deployed **OTA channel** + **crash ingest** (+ optional MQTT per `docs/OTA.md`) | WIP — examples under `examples/`; deployment blocked | **Alpha app** can ship before backend is live if the demo is LAN-only. **Full alpha** includes OTA/crash URLs configured in developer settings or `local.properties`. ### Alpha app checklist **Runbook:** [ALPHA.md](ALPHA.md) (feature freeze, defaults, sign-off tables, log script). | Checkpoint | Engineering | Manual sign-off | |------------|---------------|-----------------| | Happy path: UDP + H.264/AAC + single receiver, protection **None** | Defaults + freeze in code | ☐ [ALPHA.md](ALPHA.md) § A, C1 | | README matches `CastSettings` / `CastConfig` | Done | — | | Fix misleading strings (camera permission vs unavailable) | Done | — | | Two-device QA (rotate, background, notification stop) | Script in `scripts/alpha-qa-logcat.sh` | ☐ [ALPHA.md](ALPHA.md) § B | | Cap multi-receiver at 1 for alpha | `MULTI_RECEIVER_ENABLED` off while freeze on | — | | Hide QUIC/WebRTC/USB in settings for alpha | `ALPHA_FEATURE_FREEZE` | — | | Receiver stuck on rotation / STREAM_CONFIG storm | Debounce + idle grace in code | ☐ B4–B5 | ### Alpha backend checklist - [ ] Host `examples/ota/v0/` channel JSON + APK artifacts - [ ] Deploy `examples/crash_reporter/backend/` (see `nginx.conf`, `README.md`) - [ ] Set `ota.channel.url` and crash upload URL in dev settings / `local.properties` --- ## Product positioning - **Primary:** Wi‑Fi LAN cast when **USB-C→HDMI** wired mirror fails or is unavailable (common on some tablets). - **Not in scope for v0:** Internet relay (`gateway_url_hint`), TLS on cast protocol, WebRTC as default transport. See [USB_HDMI_CAST.md](USB_HDMI_CAST.md) for wired display vs Wi‑Fi cast. --- ## USB-C / HDMI (roadmap D) and USB-tether cast (roadmap E) | Item | Status | |------|--------| | `WiredDisplayMonitor` — detect external displays | Done | | `ExternalDisplayCapturePolicy` + developer UI | Done (policy stored; capture still default display) | | `ScreenCastService` display hot-plug hooks | Done | | Secondary-display MediaProjection capture | TODO | | `UsbTetherCastTransport` stub + dev-gated transport id | Done | | USB tether / ADB reverse discovery + framing | TODO | Details: [USB_HDMI_CAST.md](USB_HDMI_CAST.md). --- ## Commercial (Play Store prep) All **off by default**. Enable only in **Developer settings** for internal testing. | Item | Status | |------|--------| | `CommercialFeatures` gate | Done | | `InAppPurchaseCoordinator` (Play Billing 7.x) | Done (connects when dev IAP on; SKU placeholder) | | `InAppAdCoordinator` (placeholder, no AdMob SDK yet) | Done | | `PlayStoreIntegration` (listing intent + in-app review API) | Done | | AdMob / unit IDs / banner layouts in main UI | TODO | | Play Console products + privacy policy | TODO | See [COMMERCIAL.md](COMMERCIAL.md). Pro/OSS module split: [PRO_AAR.md](PRO_AAR.md) (design). --- ## Crash console open API | Item | Status | |------|--------| | Workflow triage tags + multi-tag (duplicate+fixed, etc.) | Done — [OPEN_API.md](OPEN_API.md) | | `GET /api/reports.php?tag=…&tag_mode=and\|or` | Done | | `ingest.source` / run metadata in payload | Design — [OPEN_API.md](OPEN_API.md) | | List filters + synthetic tagging | TODO | | API key upload auth (per company) | TODO | --- ## Stream protection (FEC / NACK) | Item | Status | |------|--------| | GF(256) Reed–Solomon + `ProtectionEnvelope` v1 (monolithic) | Done | | **v2 per-shard FEC** (`FecShardWire`, one ACUD message per RS shard) | Done | | NACK + `RetransmitCache` + `MSG_NACK` | Done | | Post-handshake negotiation | Done | | Backward compat (defer FEC until negotiated; ignore foreign FEC/NACK) | Done | | Default protection **NONE** (stable cast) | Done | | Integration tests (`FecShard*`, `UdpCastTransportFecTest`) | Done | | Lab soak under loss (HY300 / BL6000) | TODO (manual) | | NACK rate limit / backoff | Done (`NackRateLimiter`) | | `MSG_FEC_NACK` by groupId (optional) | Deferred | Enable in **Settings → Stream protection (UDP)** on both sender and receiver, then reconnect. --- ## libvpx / Opus / Speex | Item | Status | |------|--------| | `libandroidcast_codecs.so` + JNI probes | Done | | Cross-compile `libvpx.a` (`scripts/build-native-codecs.sh`) | Done | | JNI encode/decode in `libvpx_bridge.c` | Done (when `libvpx.a` linked per ABI) | | `LibvpxVideoEncoderSink` (surface + buffer) | Done | | libvpx decoder on receiver (`LibvpxCapableVideoDecoder`) | Done | | Surface → libvpx without MediaCodec passthrough on cast | Done (ImageReader) | | Opus / Speex build + sinks | TODO | See [ndk/README.md](../ndk/README.md). --- ## Transports & protocols | Transport | Status | |-----------|--------| | UDP (default) | Done | | TCP | Done | | QUIC (Cronet, experimental) | Partial | | WebRTC | Stub (`WebRtcCastTransport`) | | USB tether (`usb_tether`) | Stub — dev settings only | --- ## Receiver / sender UX | Item | Status | |------|--------| | `ReceiverPlaybackActivity` (primary receiver UI) | Done | | Settings drawer + themes + RU locale | Done | | Multi-receiver 1:N | Done (gated off while `ALPHA_FEATURE_FREEZE`) | | Legacy `ReceiverActivity` in manifest | Orphan — remove or wire | | Immersive A/V presets (dev) | Experimental | | Sender resolution UI modes (dev: Separated / Legacy / Combined) | Done (test) | | True dual-stream encode (480p + 720p simultaneous) | Deferred | --- ## Deferred / post-alpha - Internet relay gateway - TLS on cast stream - Passthrough video codec - Lab automation under simulated loss - Full wired-HDMI capture (roadmap D phase 2) - USB-tether cast production path (roadmap E) --- ## Related docs - [README.md](README.md) — **documentation index** (all `docs/*.md` with section links) - [GIT_FLOW.md](GIT_FLOW.md) — green `master` / `next` development cycle ([PDF](GIT_FLOW.pdf)) - [INFRA.md](INFRA.md) — production FE/BE topology - [../README.md](../README.md) — repo quick start - [ALPHA.md](ALPHA.md) — alpha freeze & QA sign-off - [USB_HDMI_CAST.md](USB_HDMI_CAST.md) — D & E - [COMMERCIAL.md](COMMERCIAL.md) — ads / IAP / Play - [PRO_AAR.md](PRO_AAR.md) — cast-core / cast-pro entitlements - [OPEN_API.md](OPEN_API.md) — crash ingest triage API - [OTA.md](OTA.md) — backend layout v0 - [BUILD_DEPLOY.md](BUILD_DEPLOY.md) — Docker build, staging OTA, deploy flow - [CRASH_REPORTER.md](CRASH_REPORTER.md) — crash upload - [GRAFANA_vs_others_graphvis_pivot.md](GRAFANA_vs_others_graphvis_pivot.md) — graphs dashboard pivot - [20260602_REVERSE_SSH_proposals_summary.md](20260602_REVERSE_SSH_proposals_summary.md) — on-demand remote access - [AV_QUALITY_QA_SESSION.md](AV_QUALITY_QA_SESSION.md) — AV quality enhancement Q&A