diff options
Diffstat (limited to 'CLAUDE.md')
| -rw-r--r-- | CLAUDE.md | 28 |
1 files changed, 23 insertions, 5 deletions
@@ -240,11 +240,13 @@ out of a possibly-partial MP3, and the JSON path covers the shows that mark chap slow drip on or off" rather than "Slow drip", because a description identical to the heading beside it makes the tap ambiguous. -- **`connectedDebugAndroidTest` can wipe the app's data.** A run cleared `listen.db` on the - emulator mid-session. It is the test harness's install path, not a migration: a real v2 - database seeded with a subscription, an episode at position 424242 and a rule was upgraded in - place by launching the v3 build, and all three survived with drip defaulting to off. Do not - read an empty database after an instrumented run as a migration failure -- but do check. +- **`connectedDebugAndroidTest` uninstalls the app when it finishes**, taking the database with + it. Isolated on the emulator: a plain `adb install -r` left four episodes in place, and the + very next instrumented run left `run-as: unknown package`. So an empty or missing database + after an instrumented run is the harness, not a migration -- and any device state you want to + keep has to be re-seeded afterwards. Migrations were separately proven safe by seeding a real + v2 database (a subscription, an episode at position 424242, a rule) and upgrading it in place + by launching the v3 build: all three survived, with drip defaulting to off. - **The drip released-set is a query parameter, not stored state.** `observeVisible`/`getVisible` take `dripEnabled` and hide unreleased episodes only when it is true, so switching drip off @@ -252,6 +254,22 @@ out of a possibly-partial MP3, and the JSON path covers the shows that mark chap left off. `getForSubscription` deliberately still returns everything: feed reconciliation must see held-back episodes or it re-inserts them on every refresh. +- **Completion belongs to the service, not to a view model.** Marking an episode played, + advancing the queue, the outro offset and ad-chapter skipping all live in `PlaybackService` + via `PlaybackAdvancer` and `PlayheadPolicy`. They used to live in `PlayerViewModel`, which is + scoped to the activity and releases its MediaController in `onCleared` -- so with the activity + gone the audio played on from the foreground service while nothing marked anything played or + moved the queue on. Background listening is the normal case for this app. Verified with + "don't keep activities" on: with no activity alive, an episode reached its outro line, was + marked played, and the next one started. + + `PlayerConnection` deliberately no longer handles `STATE_ENDED`, and `PlayerViewModel` no + longer has an `onFinished`. Putting either back means the queue advances twice. + +- **Where an episode starts is decided in exactly one place**, `PlaybackAdvancer.start`, used by + both the service (queue advance) and the view model (a tap on Play). Two copies of the resume + rules would drift. + - **A start position belongs to `setMediaItem`, not a `seekTo` after `prepare()`.** Seeking afterwards is silently dropped across the MediaController-to-service boundary. This was found wiring up the intro offset -- an episode set to start sixty seconds in began at zero -- and it |
