diff --git a/app/src/main/java/at/lockstep/player/playback/PlaybackService.kt b/app/src/main/java/at/lockstep/player/playback/PlaybackService.kt index 59f234b..6bd0b69 100644 --- a/app/src/main/java/at/lockstep/player/playback/PlaybackService.kt +++ b/app/src/main/java/at/lockstep/player/playback/PlaybackService.kt @@ -62,6 +62,7 @@ class PlaybackService : Service() { private var queue: List = emptyList() private var index: Int = 0 + private var tornDown = false /** Updated on the main thread whenever progress is read from the engine — safe for sensor threads. */ @Volatile @@ -524,17 +525,39 @@ class PlaybackService : Service() { .build() } + override fun onTaskRemoved(rootIntent: Intent?) { + stopPlaybackAndTeardown() + stopSelf() + super.onTaskRemoved(rootIntent) + } + override fun onDestroy() { - positionPollJob?.cancel() - positionCachePollJob?.cancel() - releaseEngine() - mediaSession.run { - isActive = false - release() - } + stopPlaybackAndTeardown() super.onDestroy() } + /** Stops audio, clears queue state, and removes the foreground notification. Idempotent. */ + private fun stopPlaybackAndTeardown() { + if (tornDown) return + tornDown = true + positionPollJob?.cancel() + positionPollJob = null + positionCachePollJob?.cancel() + positionCachePollJob = null + releaseEngine() + queue = emptyList() + index = 0 + cachedPlaybackPositionMs = 0L + _uiState.value = PlaybackUiState.initial() + if (::mediaSession.isInitialized) { + mediaSession.run { + isActive = false + release() + } + } + stopForeground(STOP_FOREGROUND_REMOVE) + } + data class PlaybackUiState( val title: String, val artist: String,