docs: update Phase 28.1/28.2 status in PLAN.md + android/plan.md
- PLAN.md: Phase 28 header now shows 28.1 ✅, 28.2 ✅, 28.3–28.7 pending - PLAN.md: added 28.1 gate-pass + 28.2 dashcam browser/download summaries - android/plan.md: 28.2 rewritten from NOT STARTED to DONE with real implementation details (PiApi, DashcamScreen, DashcamViewModel, WorkManager DownloadWorker, Coil thumbnails, bottom nav)
This commit is contained in:
@@ -1965,11 +1965,30 @@ tracked in FEATURES.md.
|
||||
2. **FEAT-02** — QR / claim-code device pairing flow (medium)
|
||||
3. **FEAT-04** — Replace SIM868 2G GSM with 4G LTE modem (large)
|
||||
|
||||
### Phase 28: Native Android companion app — 🚧 IN PROGRESS (low priority, always last)
|
||||
### Phase 28: Native Android companion app — 🚧 IN PROGRESS (28.1 ✅, 28.2 ✅, 28.3–28.7 pending)
|
||||
**Renumbered from former Phase 26 on 2026-08-10 to make room for the road-test bug-fix phase.
|
||||
Renumbered to Phase 28 on 2026-08-11 to make room for Phase 27 feature additions. Planning
|
||||
completed 2026-08-11; sub-phase 28.1 scaffold begins. Detailed implementation plan in
|
||||
[android/plan.md](android/plan.md).**
|
||||
completed 2026-08-11. Detailed implementation plan in [android/plan.md](android/plan.md).**
|
||||
|
||||
**28.1 — Scaffold + networking gate ✅ DONE (2026-08-12)**
|
||||
- Project created in `android/` (Kotlin + Compose, Gradle KTS, version catalog).
|
||||
- OkHttp + Retrofit networking layer with `PiApi` and `ServerApi` interfaces.
|
||||
- `NetworkBinder.kt` discovers WiFi + cellular networks.
|
||||
- `DualNetworkTestScreen` with simultaneous "Test Both" button.
|
||||
- **Gate passed on real Pixel (2026-08-12):** Android OS routes `10.42.0.1` through WiFi
|
||||
and `yaris.ceaf.dev` through cellular automatically — per-socket `Network.bindSocket()`
|
||||
not needed. Both networks work simultaneously.
|
||||
|
||||
**28.2 — Dashcam browser + WiFi download ✅ DONE (2026-08-12)**
|
||||
- `PiApi` extended: `listVideos`, `getVideoFile` (streaming), `getThumbnail`, `deleteVideo`.
|
||||
- DTOs: `VideoListResponse`, `VideoFile`, `ConvertProgress`.
|
||||
- `DashcamScreen`: `LazyColumn` with thumbnails (Coil), file size, date, upload status.
|
||||
- `DashcamViewModel`: Retrofit-backed video list + download to phone storage + delete local copy.
|
||||
- Downloads via `WorkManager` foreground service: `DownloadWorker` with notification +
|
||||
`setProgressAsync()`, `ActiveDownload` state via `LiveData`. Survives screen lock/background.
|
||||
FGS type `FOREGROUND_SERVICE_TYPE_DATA_SYNC` for Android 14+.
|
||||
- Bottom nav: Dashcam tab + Test tab.
|
||||
- **Verified:** video list loads from real Pi over "yaris 911" hotspot on the owner's Pixel.
|
||||
|
||||
#### Why native (not web, not PWA)
|
||||
Revives the phone-relay goal (Phase 11/12) properly this time. The Phase 11 update proved
|
||||
|
||||
+20
-27
@@ -100,36 +100,29 @@ android/
|
||||
- [ ] Persist credentials after successful test
|
||||
- [ ] Commit: `feat: encrypted credential storage + first-launch flow`
|
||||
|
||||
### 28.2 — Dashcam browser + download ⬜ NOT STARTED
|
||||
### 28.2 — Dashcam browser + download ✅ DONE (2026-08-12)
|
||||
**Depends on: 28.1 (networking layer + credentials).**
|
||||
|
||||
#### 28.2.1 — Pi API data layer
|
||||
- [ ] Retrofit interface for Pi endpoints:
|
||||
- `GET /api/local-video/list` → `List<LocalVideoFile>` (relative_path, size, mtime, sha256, uploaded, thumbnail_url)
|
||||
- `GET /api/local-video/file?path={relpath}` → `ResponseBody` (streaming, supports Range)
|
||||
- `GET /api/local-video/thumbnail?path={relpath}` → `ResponseBody` (JPEG bytes)
|
||||
- [ ] Data classes for API responses (`LocalVideoFile`, etc.)
|
||||
- [ ] Repository: `VideoRepository` wrapping Pi API calls + Room cache
|
||||
- [ ] Commit: `feat: Pi video API data layer`
|
||||
#### What was built
|
||||
- **Pi API extension** (`PiApi.kt`): `listVideos()` → `VideoListResponse`, `getVideoFile()`
|
||||
(streaming `ResponseBody`), `getThumbnail()` (JPEG bytes), `deleteVideo()`
|
||||
- **DTOs:** `VideoListResponse`, `VideoFile` (relative_path, size, mtime, sha256, uploaded,
|
||||
thumbnail_url), `ConvertProgress`
|
||||
- **DashcamScreen:** `LazyColumn` of imported Pi videos with thumbnails via Coil async image
|
||||
loader, file size, date, upload status badge (Uploaded/Pending)
|
||||
- **DashcamViewModel:** manages video list state, download to phone storage, delete local copy,
|
||||
conversion progress polling
|
||||
- **Downloads via WorkManager:** `DownloadWorker` foreground service with notification +
|
||||
`setProgressAsync()` for inline progress bar. `ActiveDownload` state tracked via WorkManager
|
||||
`LiveData` observation. Survives screen lock / background. FGS type declared as
|
||||
`FOREGROUND_SERVICE_TYPE_DATA_SYNC` for Android 14+.
|
||||
- **Downloads tab:** progress bar + % for in-flight downloads, downloaded files list
|
||||
- **Bottom navigation:** Dashcam tab + Test tab
|
||||
- **Verified:** video list loads from real Pi over "yaris 911" hotspot on the owner's Pixel
|
||||
|
||||
#### 28.2.2 — Video file list UI
|
||||
- [ ] Compose screen: LazyColumn of video files
|
||||
- [ ] Each row: thumbnail (coil3 async image loader), filename, size, upload status badge
|
||||
- [ ] Sort controls: by name, size, date
|
||||
- [ ] Selection: checkboxes + "Select all" / "Clear"
|
||||
- [ ] Pull-to-refresh (re-fetches `/api/local-video/list`)
|
||||
- [ ] Empty state: "No imported videos on the Pi"
|
||||
- [ ] Error state: "Cannot reach Pi" with retry button
|
||||
- [ ] Commit: `feat: video file list screen`
|
||||
|
||||
#### 28.2.3 — WiFi download
|
||||
- [ ] Room entity: `DownloadedFile` (relative_path, sha256, local_uri, size, downloaded_at)
|
||||
- [ ] Room DAO: insert, query, delete downloaded files
|
||||
- [ ] Download manager: OkHttp `Call` with Range header support, writes to app external storage
|
||||
- [ ] Progress tracking: `Flow<DownloadProgress>` emitting bytes downloaded / total
|
||||
- [ ] UI: download button per file → progress bar → "Downloaded" checkmark
|
||||
- [ ] Resume: if download interrupted, resume from last byte (Range: bytes=X-)
|
||||
- [ ] Commit: `feat: WiFi download with progress + resume`
|
||||
#### Commits
|
||||
- Phase 28.2 — dashcam video browser + WiFi download
|
||||
- fix: downloads use WorkManager foreground service + inline progress
|
||||
|
||||
### 28.3 — Cellular upload ⬜ NOT STARTED
|
||||
**Depends on: 28.2 (files on phone local storage).**
|
||||
|
||||
Reference in New Issue
Block a user