|
| 1 | +# Fiver Wireless Companion App — Implementation Complete |
| 2 | + |
| 3 | +## What Was Built |
| 4 | + |
| 5 | +A complete **wireless screen mirroring** system that works **without USB debugging**. When a phone scans a QR code, it downloads a companion Android app that captures the screen and streams it live to the laptop over WiFi. |
| 6 | + |
| 7 | +## New Files Created |
| 8 | + |
| 9 | +| File | Purpose | |
| 10 | +|------|---------| |
| 11 | +| [`companion/__init__.py`](file:///home/cachy/github-p/fiver/src/fiver/companion/__init__.py) | Package marker | |
| 12 | +| [`companion/AndroidManifest.xml`](file:///home/cachy/github-p/fiver/src/fiver/companion/AndroidManifest.xml) | Android app manifest with MediaProjection permissions | |
| 13 | +| [`companion/MainActivity.java`](file:///home/cachy/github-p/fiver/src/fiver/companion/MainActivity.java) | Dark-themed UI, requests screen capture permission | |
| 14 | +| [`companion/ScreenCaptureService.java`](file:///home/cachy/github-p/fiver/src/fiver/companion/ScreenCaptureService.java) | Foreground service: captures screen → JPEG → HTTP POST to laptop | |
| 15 | +| [`apk_builder.py`](file:///home/cachy/github-p/fiver/src/fiver/apk_builder.py) | Auto-builds APK: finds/downloads SDK → javac → d8 → aapt2 → sign | |
| 16 | + |
| 17 | +## Modified Files |
| 18 | + |
| 19 | +| File | Changes | |
| 20 | +|------|---------| |
| 21 | +| [`web_mirror.py`](file:///home/cachy/github-p/fiver/src/fiver/web_mirror.py) | New `/download/companion.apk` endpoint, raw JPEG frame support, APK download page | |
| 22 | +| [`tui.py`](file:///home/cachy/github-p/fiver/src/fiver/tui.py) | Companion app fallback when ADB fails: build APK → serve → show QR | |
| 23 | +| [`pyproject.toml`](file:///home/cachy/github-p/fiver/pyproject.toml) | Include companion source files in package data | |
| 24 | + |
| 25 | +## Complete Flow |
| 26 | + |
| 27 | +``` |
| 28 | +User runs: fiver --setup-wifi |
| 29 | + │ |
| 30 | + ▼ |
| 31 | +TUI scans WiFi → picks device → tries ADB connect |
| 32 | + │ |
| 33 | + ▼ (ADB fails — no USB debugging) |
| 34 | +APK Builder activates: |
| 35 | + ├── Checks for Android SDK tools |
| 36 | + ├── Auto-downloads SDK if missing (~1 min first time) |
| 37 | + ├── Embeds laptop IP into Java source |
| 38 | + ├── javac → d8 → aapt2 → apksigner |
| 39 | + └── Caches built APK |
| 40 | + │ |
| 41 | + ▼ |
| 42 | +Web server starts → Cloudflare tunnel → QR code shown |
| 43 | + │ |
| 44 | + ▼ (Phone scans QR) |
| 45 | +Phone opens page → "DOWNLOAD & INSTALL" button |
| 46 | + │ |
| 47 | + ▼ (User installs APK) |
| 48 | +APK opens → "START SCREEN SHARE" button |
| 49 | + │ |
| 50 | + ▼ (User taps "Start Now" on permission dialog) |
| 51 | +ScreenCaptureService starts: |
| 52 | + ├── MediaProjection captures screen at 720p |
| 53 | + ├── JPEG frames at ~20 FPS, quality 60 |
| 54 | + └── HTTP POST raw JPEG to laptop:8080/api/frame |
| 55 | + │ |
| 56 | + ▼ |
| 57 | +Desktop browser shows live MJPEG stream at /desktop |
| 58 | +``` |
| 59 | + |
| 60 | +## Required Dependencies |
| 61 | + |
| 62 | +Before the APK can be built, you need **JDK** installed: |
| 63 | + |
| 64 | +```bash |
| 65 | +# Arch / CachyOS |
| 66 | +sudo pacman -S jdk-openjdk |
| 67 | + |
| 68 | +# Debian / Ubuntu |
| 69 | +sudo apt install default-jdk |
| 70 | + |
| 71 | +# Fedora |
| 72 | +sudo dnf install java-latest-openjdk-devel |
| 73 | +``` |
| 74 | + |
| 75 | +> [!IMPORTANT] |
| 76 | +> The **Android SDK build-tools** and **platform** will be **auto-downloaded** on first use to `~/.fiver/sdk/`. No manual Android Studio setup needed. |
| 77 | +
|
| 78 | +## Key Design Decisions |
| 79 | + |
| 80 | +- **View-only**: Laptop can see the phone screen but not control it (avoids Accessibility Service complexity) |
| 81 | +- **JPEG over HTTP**: Simple, universal, ~15-25 FPS at 720p |
| 82 | +- **Auto SDK install**: Downloads `commandlinetools` from Google, then uses `sdkmanager` to install `build-tools;34.0.0` and `platforms;android-34` |
| 83 | +- **APK caching**: Built APKs are cached at `~/.fiver/apk/` keyed by server URL hash |
| 84 | +- **No USB debugging required**: Uses Android's `MediaProjection` API which only needs user consent |
0 commit comments