The hardware path's progress callback has never been invoked #196

Closed
opened 2026-09-02 12:46:19 +00:00 by JMR-dev · 0 comments
JMR-dev commented 2026-09-02 12:46:19 +00:00 (Migrated from github.com)

Wave 4, filed from a coverage read on main @ 54ca2dd, 2026-09-02. The shared filter note is on #194.

The hardware path reports progress to nobody

app/src/main/java/org/libremediaconverter/work/ConversionWorker.kt:208-210
engine.transcode(inputUri, staged, request) { percent ->
    publishProgress(displayName, percent)
}

Lines 209-210 report ci == 0. The lambda is constructed and handed to the engine; its body has never run.

Why the software side does not cover it

ProgressNotificationTest pins this plumbing thoroughly — but on the FFmpeg path, through runFFmpeg's own onProgress. The Media3 path has a separate lambda at a separate call site, and HardwareFallbackTest's RecordingHardwareTranscoder records the call and never invokes the callback it was handed. So the two engines' progress wiring is one tested and one not, and they are the same shape — which is exactly the asymmetry argument CLAUDE.md used to include ContainerCapabilities:94.

That matters because the hardware path is the default: ConversionRouter sends everything it can to Media3, so this is the lambda most conversions actually use.

The work

Have RecordingHardwareTranscoder call onProgress(42) before returning, and assert what comes out the other side. One test, in HardwareFallbackTest or beside it.

Assert on the progress Data, not only on the notification. publishProgress (:272-278) calls setProgressAsync(workDataOf(KEY_PROGRESS to percent)) unconditionally, then throttles the foreground update behind NOTIFICATION_INTERVAL_MS. The Data write is the unconditional half and the one that carries the number; RecordingForegroundUpdater from ProgressNotificationTest (via .setForegroundUpdater(...)) can pin the notification alongside it.

Assert the percent that arrives, not merely that something was recorded: dropping percent for a constant compiles fine.

Acceptance: the mutation that must go red

Empty the lambda body at :209 — no second ForegroundInfo is recorded. Then, separately, replace percent with 0 — the percent assertion must fail. Restore, confirm green.

_Wave 4, filed from a coverage read on `main` @ `54ca2dd`, 2026-09-02. The shared filter note is on #194._ ## The hardware path reports progress to nobody ``` app/src/main/java/org/libremediaconverter/work/ConversionWorker.kt:208-210 ``` ```kotlin engine.transcode(inputUri, staged, request) { percent -> publishProgress(displayName, percent) } ``` Lines 209-210 report `ci == 0`. The lambda is constructed and handed to the engine; its body has never run. ## Why the software side does not cover it `ProgressNotificationTest` pins this plumbing thoroughly — but on the **FFmpeg** path, through `runFFmpeg`'s own `onProgress`. The Media3 path has a separate lambda at a separate call site, and `HardwareFallbackTest`'s `RecordingHardwareTranscoder` records the call and never invokes the callback it was handed. So the two engines' progress wiring is one tested and one not, and they are the same shape — which is exactly the asymmetry argument `CLAUDE.md` used to include `ContainerCapabilities:94`. That matters because the hardware path is the *default*: `ConversionRouter` sends everything it can to Media3, so this is the lambda most conversions actually use. ## The work Have `RecordingHardwareTranscoder` call `onProgress(42)` before returning, and assert what comes out the other side. One test, in `HardwareFallbackTest` or beside it. **Assert on the progress `Data`, not only on the notification.** `publishProgress` (`:272-278`) calls `setProgressAsync(workDataOf(KEY_PROGRESS to percent))` unconditionally, then throttles the foreground update behind `NOTIFICATION_INTERVAL_MS`. The `Data` write is the unconditional half and the one that carries the number; `RecordingForegroundUpdater` from `ProgressNotificationTest` (via `.setForegroundUpdater(...)`) can pin the notification alongside it. Assert the **percent that arrives**, not merely that something was recorded: dropping `percent` for a constant compiles fine. ## Acceptance: the mutation that must go red Empty the lambda body at `:209` — no second `ForegroundInfo` is recorded. Then, separately, replace `percent` with `0` — the percent assertion must fail. Restore, confirm green.
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: JMR-dev/LibreMediaConverter#196