android: byte-level upload progress + debug logging; document 28.3

- UploadWorker: ProgressRequestBody (okio ForwardingSink) tracks real bytes
  sent including already-received chunks, instead of chunk count
- Robust chunk reads (loop skip/read) + Log.d/Log.e debug logging
- DashcamViewModel: upload state/progress debug logging
- android/plan.md + PLAN.md: 28.3 marked in progress with built items
This commit is contained in:
Mathieu Moran
2026-08-12 19:00:00 -04:00
parent 6398baaa6b
commit 2e8e42a165
4 changed files with 113 additions and 27 deletions
+19 -18
View File
@@ -124,33 +124,34 @@ android/
- Phase 28.2 — dashcam video browser + WiFi download
- fix: downloads use WorkManager foreground service + inline progress
### 28.3 — Cellular upload ⬜ NOT STARTED
### 28.3 — Cellular upload 🚧 IN PROGRESS (2026-08-12)
**Depends on: 28.2 (files on phone local storage).**
#### 28.3.1 — Server upload data layer
- [ ] Retrofit interface for server chunked upload:
#### 28.3.1 — Server upload data layer ✅ DONE
- [x] Retrofit interface for server chunked upload (`data/remote/ServerApi.kt`):
- `GET /api/v1/dashcam/upload/status?sha256={hash}` → `UploadStatus`
- `POST /api/v1/dashcam/upload/chunk` → multipart (file chunk, sha256, chunk_index, total_chunks)
- [ ] Data classes: `UploadStatus` (already_uploaded, received_chunk_indices, total_chunks)
- [ ] Commit: `feat: server chunked upload API`
- [x] Data classes: `UploadStatus` (already_uploaded, received_chunk_indices, total_chunks)
#### 28.3.2 — Upload worker
- [ ] WorkManager `CoroutineWorker`:
- Input: file local URI, sha256, relative_path
- Step 1: check `/status` for already-received chunks
#### 28.3.2 — Upload worker ✅ DONE
- [x] WorkManager `CoroutineWorker` (`UploadWorker.kt`):
- Input: filename, server URL, device name, API key
- Step 1: compute SHA256, check `/status` for already-received chunks
- Step 2: read file in 40MB chunks (matching `DASHCAM_CHUNK_SIZE`)
- Step 3: POST each missing chunk via cellular-bound OkHttp client
- Step 3: POST each missing chunk (skips already-received chunks)
- Step 4: verify server reports `already_uploaded` after last chunk
- Step 5: delete local file copy on success (optional, configurable)
- [ ] Foreground service notification: "Uploading VID_00234.MOV — 3/8 chunks (37%)"
- [ ] Retry on failure: WorkManager backoff policy (exponential, max 3 attempts)
- [ ] Commit: `feat: WorkManager cellular upload worker`
- [x] Foreground service notification with live % ("Uploading VID_00234.MOV — 62%")
- [x] Byte-level upload progress via `ProgressRequestBody` (okio `ForwardingSink`) — progress
reflects actual bytes sent including already-received chunks, not just chunk count
- [x] Robust chunk reads (loop `skip()`/`read()` instead of single calls)
- [x] Debug logging (`Log.d`/`Log.e`, tag `UploadWorker`) throughout
- [x] Re-upload guard: skips files already on server (`already_uploaded`)
#### 28.3.3 — Upload queue UI
- [ ] Screen: list of downloaded files waiting to upload
- [ ] Per-file: status (queued / uploading / done / failed), progress bar, retry button
#### 28.3.3 — Upload queue UI 🚧 IN PROGRESS
- [x] Downloads screen shows per-file upload status + inline progress bar
- [x] In-app test file generator for upload testing
- [ ] "Upload all" button → enqueue all pending files
- [ ] Observation: watch WorkManager `WorkInfo` via `LiveData`/`Flow` for real-time status
- [ ] Retry button per failed file
- [ ] Commit: `feat: upload queue screen`
### 28.4 — Live dashboard ⬜ NOT STARTED