# Android Cast (POC)

**Roadmap & alpha:** [docs/ROADMAP.md](docs/ROADMAP.md) · **Alpha QA & feature freeze:** [docs/ALPHA.md](docs/ALPHA.md) · **Production infra (agents: read first):** [docs/INFRA.md](docs/INFRA.md) · USB-C/HDMI: [docs/USB_HDMI_CAST.md](docs/USB_HDMI_CAST.md) · Commercial (dev-gated): [docs/COMMERCIAL.md](docs/COMMERCIAL.md)

Minimal LAN screen-casting proof of concept in **Java**. Captures screen + playback audio, encodes **H.264 + AAC**, streams over **TCP or UDP** to a receiver that decodes and plays back.

## Features

- UDP broadcast discovery on the local network
- **UDP (default)** or TCP stream transport (selectable; must match on both devices)
- PIN auth (SHA-256 hash, default `1234`)
- Screen capture → H.264 (AVC) with quality presets and scaled capture resolution
- Playback audio capture (API 29+) → AAC-LC
- Camera capture modes (API 29+, rear/front) — best-effort
- Runtime notification permission (Android 13+)

## Quick start (alpha)

1. Install the same APK on two devices on the **same Wi‑Fi**.
2. **Receiver:** **Receive** → transport **UDP** → stream protection **None** → **Start listening** (notification *Listening* / *Ready*).
3. **Sender:** **Send** → **UDP** → protection **None** → discover receiver → PIN → approve screen capture.
4. Watch **notifications** on both devices for status.
5. Stop from either notification **Stop** action.

Full sign-off checklist: [docs/ALPHA.md](docs/ALPHA.md).

### If video never appears

- Transport must match on both sides (e.g. both UDP).
- Stream protection **None** on both sides for alpha.
- Receiver must show *Listening* or *Ready* before you cast.
- Sender notification should reach *Casting* with resolution — if it shows *Screen capture data missing*, reinstall (Android 13+ intent fix).
- Open receiver playback once so the video `Surface` attaches (or return after rotation).
- On rotation-sensitive senders, try **system rotation lock** during cast.

## Build

Use **JDK 17 or 21** (Gradle does not run on JDK 25 yet):

```bash
export JAVA_HOME=/usr/lib/jvm/openjdk-bin-21
cd "/home/foxx/repos/My Projects/android cast"
./gradlew assembleDebug
adb install -r app/build/outputs/apk/debug/app-debug.apk
```

## Stream options (defaults)

| Option | Default / alpha note |
|--------|----------------------|
| **Transport** | **UDP** (`CastConfig.DEFAULT_TRANSPORT`) |
| **Stream protection** | **None** |
| **Quality** | Medium — 5 Mbps, 30 fps |
| **Resolution** | Adaptive (sender) |
| **Multi-receiver** | **Off** while `CastConfig.ALPHA_FEATURE_FREEZE` |
| **Audio** | On when API 29+ (`AudioPlaybackCapture` + AAC) |

| Quality | Video bitrate | FPS |
|---------|---------------|-----|
| Low | 1.5 Mbps | 24 |
| Medium | 5 Mbps | 30 |
| High | 10 Mbps | 30 |

## Protocol

| Step | Description |
|------|-------------|
| Discovery | UDP `41234`, JSON with `magic`, `name`, `port`, `transport` |
| Connect | TCP or UDP port `41235` (QUIC `41236` when enabled post-alpha) |
| Auth | `HELLO` → `AUTH` → `AUTH_OK` → `CAST_SETTINGS` |
| Stream | `STREAM_CONFIG`, `VIDEO_FRAME`, `AUDIO_CONFIG`, `AUDIO_FRAME` |

UDP frames use `ACUD` header and fragmentation for payloads &gt; ~1.2 KB.

## Bluetooth / BLE

**Not viable for this video stream.** Use **Wi‑Fi** for media; BLE could be added later only for discovery/pairing.

## Persistent services (AIDL)

Casting runs in **foreground services** with tray notifications:

| Service | Role |
|---------|------|
| `ScreenCastService` | Sender — capture, encode, stream |
| `ReceiverCastService` | Receiver — listen, decode, play |

Activities bind via AIDL for status and (on the receiver) attaching the video `Surface`. Leaving the app does **not** stop the receiver listener; the sender keeps casting until **Stop** in the notification.

## Limitations

- No TLS encryption (LAN cleartext POC)
- UDP mode may glitch under load (try TCP)
- Audio captures **playback** routed through the system (not microphone)
- Single receiver per session during alpha freeze
- No live sender preview while casting (stability)

## Development (git flow)

Green **`master`** plus integration branch **`next`**. See [docs/GIT_FLOW.md](docs/GIT_FLOW.md).

## PDF helpers

Generate the GraphVis decision memo PDF (from `docs/GRAFANA_vs_others_graphvis_pivot.md` source):

```bash
bash scripts/build-graphvis-pdf.sh
```

Output:

`docs/GRAFANA_vs_others_graphvis_pivot.pdf`
