revert playback: save state when sanitizing
Edge case I thought existed did not. PlaybackService must have saved before dying, and thus if it did not foreground after a sanitization, the saved state would still sanitize in a similar manner.
This commit is contained in:
parent
a217bde713
commit
29cc680c34
4 changed files with 42 additions and 58 deletions
|
|
@ -28,7 +28,6 @@ import kotlinx.coroutines.Job
|
||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
import org.oxycblt.auxio.IntegerTable
|
import org.oxycblt.auxio.IntegerTable
|
||||||
import org.oxycblt.auxio.R
|
import org.oxycblt.auxio.R
|
||||||
import org.oxycblt.auxio.playback.state.PlaybackStateDatabase
|
|
||||||
import org.oxycblt.auxio.playback.state.PlaybackStateManager
|
import org.oxycblt.auxio.playback.state.PlaybackStateManager
|
||||||
import org.oxycblt.auxio.settings.Settings
|
import org.oxycblt.auxio.settings.Settings
|
||||||
import org.oxycblt.auxio.util.logD
|
import org.oxycblt.auxio.util.logD
|
||||||
|
|
@ -119,8 +118,7 @@ class IndexerService : Service(), Indexer.Controller, Settings.Callback {
|
||||||
imageLoader.memoryCache?.clear()
|
imageLoader.memoryCache?.clear()
|
||||||
|
|
||||||
// Clear invalid models from PlaybackStateManager.
|
// Clear invalid models from PlaybackStateManager.
|
||||||
playbackManager.sanitize(
|
playbackManager.sanitize(newLibrary)
|
||||||
PlaybackStateDatabase.getInstance(this@IndexerService), newLibrary)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
musicStore.updateLibrary(newLibrary)
|
musicStore.updateLibrary(newLibrary)
|
||||||
|
|
|
||||||
|
|
@ -70,7 +70,7 @@ class PlaybackStateManager private constructor() {
|
||||||
notifyPlayingChanged()
|
notifyPlayingChanged()
|
||||||
}
|
}
|
||||||
/** The current playback progress */
|
/** The current playback progress */
|
||||||
private var positionMs = 0L
|
var positionMs = 0L
|
||||||
/** The current [RepeatMode] */
|
/** The current [RepeatMode] */
|
||||||
var repeatMode = RepeatMode.NONE
|
var repeatMode = RepeatMode.NONE
|
||||||
set(value) {
|
set(value) {
|
||||||
|
|
@ -81,7 +81,7 @@ class PlaybackStateManager private constructor() {
|
||||||
var isShuffled = false
|
var isShuffled = false
|
||||||
private set
|
private set
|
||||||
|
|
||||||
/** Whether this instance has been initialized */
|
/** Whether this instance has played something or restored a state. */
|
||||||
var isInitialized = false
|
var isInitialized = false
|
||||||
private set
|
private set
|
||||||
|
|
||||||
|
|
@ -141,10 +141,7 @@ class PlaybackStateManager private constructor() {
|
||||||
|
|
||||||
// --- PLAYING FUNCTIONS ---
|
// --- PLAYING FUNCTIONS ---
|
||||||
|
|
||||||
/**
|
/** Play a [song]. */
|
||||||
* Play a [song].
|
|
||||||
* @param playbackMode The [PlaybackMode] to construct the queue off of.
|
|
||||||
*/
|
|
||||||
@Synchronized
|
@Synchronized
|
||||||
fun play(song: Song, playbackMode: PlaybackMode, settings: Settings) {
|
fun play(song: Song, playbackMode: PlaybackMode, settings: Settings) {
|
||||||
val library = musicStore.library ?: return
|
val library = musicStore.library ?: return
|
||||||
|
|
@ -165,10 +162,7 @@ class PlaybackStateManager private constructor() {
|
||||||
isInitialized = true
|
isInitialized = true
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/** Play a [parent], such as an artist or album. */
|
||||||
* Play a [parent], such as an artist or album.
|
|
||||||
* @param shuffled Whether the queue is shuffled or not
|
|
||||||
*/
|
|
||||||
@Synchronized
|
@Synchronized
|
||||||
fun play(parent: MusicParent, shuffled: Boolean, settings: Settings) {
|
fun play(parent: MusicParent, shuffled: Boolean, settings: Settings) {
|
||||||
val library = musicStore.library ?: return
|
val library = musicStore.library ?: return
|
||||||
|
|
@ -321,11 +315,7 @@ class PlaybackStateManager private constructor() {
|
||||||
|
|
||||||
// --- STATE FUNCTIONS ---
|
// --- STATE FUNCTIONS ---
|
||||||
|
|
||||||
/**
|
/** Update the current [positionMs]. Only meant for use by [Controller] */
|
||||||
* Update the current [positionMs]. Will not notify listeners of a seek event.
|
|
||||||
* @param positionMs The new position in millis.
|
|
||||||
* @see seekTo
|
|
||||||
*/
|
|
||||||
@Synchronized
|
@Synchronized
|
||||||
fun synchronizePosition(controller: Controller, positionMs: Long) {
|
fun synchronizePosition(controller: Controller, positionMs: Long) {
|
||||||
if (BuildConfig.DEBUG && this.controller !== controller) {
|
if (BuildConfig.DEBUG && this.controller !== controller) {
|
||||||
|
|
@ -400,47 +390,41 @@ class PlaybackStateManager private constructor() {
|
||||||
withContext(Dispatchers.IO) { database.write(state) }
|
withContext(Dispatchers.IO) { database.write(state) }
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Sanitize the state with [newLibrary]. Writes the state to [database] */
|
/** Sanitize the state with [newLibrary]. */
|
||||||
suspend fun sanitize(database: PlaybackStateDatabase, newLibrary: MusicStore.Library) {
|
@Synchronized
|
||||||
val state =
|
fun sanitize(newLibrary: MusicStore.Library) {
|
||||||
synchronized(this) {
|
if (!isInitialized) {
|
||||||
if (!isInitialized) {
|
logD("Not initialized, no need to sanitize")
|
||||||
logD("Not initialized, no need to sanitize")
|
return
|
||||||
return
|
}
|
||||||
|
|
||||||
|
logD("Sanitizing state")
|
||||||
|
|
||||||
|
val oldSongId = song?.id
|
||||||
|
val oldPosition = positionMs
|
||||||
|
|
||||||
|
parent =
|
||||||
|
parent?.let {
|
||||||
|
when (it) {
|
||||||
|
is Album -> newLibrary.sanitize(it)
|
||||||
|
is Artist -> newLibrary.sanitize(it)
|
||||||
|
is Genre -> newLibrary.sanitize(it)
|
||||||
}
|
}
|
||||||
|
|
||||||
logD("Sanitizing state")
|
|
||||||
|
|
||||||
val oldSongId = song?.id
|
|
||||||
val oldPosition = positionMs
|
|
||||||
|
|
||||||
parent =
|
|
||||||
parent?.let {
|
|
||||||
when (it) {
|
|
||||||
is Album -> newLibrary.sanitize(it)
|
|
||||||
is Artist -> newLibrary.sanitize(it)
|
|
||||||
is Genre -> newLibrary.sanitize(it)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
_queue = newLibrary.sanitize(_queue).toMutableList()
|
|
||||||
|
|
||||||
while (song?.id != oldSongId && index > -1) {
|
|
||||||
index--
|
|
||||||
}
|
|
||||||
|
|
||||||
// Continuing playback while also possibly doing drastic state updates is
|
|
||||||
// a bad idea, so pause.
|
|
||||||
isPlaying = false
|
|
||||||
notifyNewPlayback()
|
|
||||||
|
|
||||||
// Controller may have reloaded the media item, re-seek to the previous position
|
|
||||||
seekTo(oldPosition)
|
|
||||||
|
|
||||||
makeStateImpl()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
withContext(Dispatchers.IO) { database.write(state) }
|
_queue = newLibrary.sanitize(_queue).toMutableList()
|
||||||
|
|
||||||
|
while (song?.id != oldSongId && index > -1) {
|
||||||
|
index--
|
||||||
|
}
|
||||||
|
|
||||||
|
// Continuing playback while also possibly doing drastic state updates is
|
||||||
|
// a bad idea, so pause.
|
||||||
|
isPlaying = false
|
||||||
|
notifyNewPlayback()
|
||||||
|
|
||||||
|
// Controller may have reloaded the media item, re-seek to the previous position
|
||||||
|
seekTo(oldPosition)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun makeStateImpl() =
|
private fun makeStateImpl() =
|
||||||
|
|
|
||||||
|
|
@ -221,6 +221,10 @@ class MediaSessionComponent(
|
||||||
playbackManager.seekTo(position)
|
playbackManager.seekTo(position)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override fun onFastForward() {
|
||||||
|
playbackManager.next()
|
||||||
|
}
|
||||||
|
|
||||||
override fun onRewind() {
|
override fun onRewind() {
|
||||||
playbackManager.rewind()
|
playbackManager.rewind()
|
||||||
playbackManager.isPlaying = true
|
playbackManager.isPlaying = true
|
||||||
|
|
|
||||||
|
|
@ -69,8 +69,6 @@ import org.oxycblt.auxio.widgets.WidgetProvider
|
||||||
*
|
*
|
||||||
* TODO: Android Auto
|
* TODO: Android Auto
|
||||||
*
|
*
|
||||||
* TODO: Attempt to re-unify delayed actions again
|
|
||||||
*
|
|
||||||
* @author OxygenCobalt
|
* @author OxygenCobalt
|
||||||
*/
|
*/
|
||||||
class PlaybackService :
|
class PlaybackService :
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue