diff options
| author | Peter Stone <thepeterstone@gmail.com> | 2026-09-25 19:07:04 +0000 |
|---|---|---|
| committer | Peter Stone <thepeterstone@gmail.com> | 2026-09-25 19:07:04 +0000 |
| commit | 4965d5971c1443ee69af42b9f86920fd6121fea5 (patch) | |
| tree | abb32766511b063154fc167dc0c4f3793200e45c /.githooks/pre-commit | |
| parent | 3f650131627f6737e01585b97519e03413119b44 (diff) | |
Advance the queue from the service, not from the activity
Marking an episode played and moving the queue on lived in PlayerViewModel,
which is scoped to the activity and releases its MediaController in onCleared.
So with the activity gone -- swiped off recents, or reclaimed under memory
pressure -- the audio carried on from the foreground service while nothing
marked anything played and nothing advanced the queue. Background listening with
the screen off is the normal case for a podcast app, so this was broken in the
case that matters most. The outro offset and ad-chapter skipping added last
commit rode the same tick and had the same hole.
Completion now belongs to PlaybackService, which is the component that survives
backgrounding. Two new tested classes carry the thinking: PlayheadPolicy decides
what a tick means (finish early on an outro offset, seek past a marked break, or
nothing -- with finishing beating skipping, or a show with both would seek into
the credits it was told to skip and sit there), and PlaybackAdvancer owns
finishing, advancing, and working out where the next episode starts. Neither
knows about Media3, so both are testable off-device; the service turns their
answers into player calls.
Where an episode starts is now decided in exactly one place. PlaybackAdvancer
.start is used by the service when the queue moves on and by the view model when
you tap Play, so an episode begins in the same position however it got there.
PlayerConnection no longer carries its own copy of the resume rules.
PlayerConnection deliberately stops handling STATE_ENDED and PlayerViewModel
loses onFinished entirely -- with both in place the queue would advance twice.
The view model now follows whatever is playing rather than only what it started,
so the player screen's show, speed and chapter list stay right when the service
moves on by itself.
Verified on a device with "don't keep activities" enabled, which destroys the
activity the moment it is backgrounded: an episode was resumed, the app sent to
home with no activity records left, and the service took the episode to its
outro line, marked it played, dropped it from the queue and started the next
one, which went on playing.
Also isolated the data loss seen twice this session: connectedDebugAndroidTest
uninstalls the app when it finishes, taking the database with it. A plain adb
install -r left four episodes in place and the next instrumented run left
"run-as: unknown package". Not a migration fault, and now written down as such.
No permission changes, no schema change. 385 unit tests green, detekt and lint
clean. Coverage 66.23 -> 65.33 with an exception recorded: the logic moved out of
the coverage-excluded ui/** tree into the counted service, and the ExoPlayer glue
that remains cannot run off-device.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_018AwnALZL6bD4VBtATDVv3B
Diffstat (limited to '.githooks/pre-commit')
0 files changed, 0 insertions, 0 deletions
