From c496ce8d8fb9d91d41cd544800a1f7fabb5d3ca1 Mon Sep 17 00:00:00 2001 From: Peter Stone Date: Mon, 28 Sep 2026 08:32:15 +0000 Subject: Correct durations from the file, and make the notification open the app Two from Peter, one of which turns out to matter more than it looks. **The list said 22m, the player said 29:34.** The feed is lying, not the parser: Radiolab publishes Grass Apes as `00:22:05` and the file ExoPlayer opens is 29:34. Checked against the live feed rather than guessed. The seven and a half minutes between them are dynamically inserted advertising -- the feed declares the ad-free content length and the CDN stitches in the rest -- so the error is large, systematic, and worst on exactly the shows the midroll detector exists for. The player is the first thing in the app that sees the truth, so PositionWriter now writes it back, through a new narrow PlaybackStateDao. Once per episode rather than once per tick: this runs on the position timer for the length of an episode, and a lookup on every tick is precisely the per-episode work that does not scale. A two-second disagreement is left alone, being a container arguing with an encoder rather than a lie, and an unprepared player reporting nothing never wipes what the feed said. PlaybackStateDao is a split by meaning, not by count -- it owns the two things playback learns and writes back, the only writes in the app whose loss is unrecoverable. It also keeps EpisodeDao under detekt's interface limit, which the new query had pushed it over; the config's own comment argues against splitting a DAO to satisfy a count, so this splits it for a reason that would stand on its own. **Tapping the notification opens the app**, via setSessionActivity. It had none, so the transport buttons worked and the body did nothing, which reads as breakage rather than omission. Verified on the emulator against the real feed: Grass Apes stored as 1325000ms on subscribe, 1770553ms after twenty-five seconds of playback. The notification now carries `contentIntent=PendingIntent{... startActivity}` in dumpsys -- I confirmed the intent is attached and targets this app's activity, but did not simulate the physical tap. That same dump corroborates what I told Peter about the notification being Auto's doing and not ours: importance=2, sound=null, vibrate=null, category=transport. ExoPlayhead joins the coverage exclusions. It is four one-line getters over ExoPlayer that happen to live in PlaybackService.kt, so it read as covered by that entry while actually being measured -- it is the seam that makes PositionWriter testable, not logic. 540 unit tests, detekt and lint clean. Coverage 92.73% -> 92.96%. Co-Authored-By: Claude Opus 5 Claude-Session: https://claude.ai/code/session_018AwnALZL6bD4VBtATDVv3B --- .coverage-baseline | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to '.coverage-baseline') diff --git a/.coverage-baseline b/.coverage-baseline index 4b5c51d..d7655a6 100644 --- a/.coverage-baseline +++ b/.coverage-baseline @@ -1 +1 @@ -92.73 +92.96 -- cgit v1.2.3