playback: re-add index correction
Re-add index correction, albeit with a new system that accomodates the single queue mechanism. The issue with using the previous queue mechanism for the single queue was that it risked using the index of an incorrect duplicate song, as the search would always start at index 0. Fix this by implementing a sort of "wobbly" search that starts at the current index and moves back and forth, checking the closest items first and the furthest items last.
This commit is contained in:
parent
685d3af12f
commit
4d22b99577
3 changed files with 49 additions and 8 deletions
|
@ -566,6 +566,7 @@ class PlaybackStateManager private constructor() {
|
|||
unpackFromPlaybackState(playbackState)
|
||||
unpackQueue(queue)
|
||||
doParentSanityCheck()
|
||||
doIndexSanityCheck()
|
||||
}
|
||||
|
||||
logD("Restore finished in ${System.currentTimeMillis() - start}ms")
|
||||
|
@ -606,7 +607,7 @@ class PlaybackStateManager private constructor() {
|
|||
}
|
||||
|
||||
/**
|
||||
* Do the sanity check to make sure the parent was not lost in the restore process.
|
||||
* Do a sanity check to make sure the parent was not lost in the restore process.
|
||||
*/
|
||||
private fun doParentSanityCheck() {
|
||||
// Check if the parent was lost while in the DB.
|
||||
|
@ -622,6 +623,52 @@ class PlaybackStateManager private constructor() {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Do a sanity check to make sure that the index lines up with the current song.
|
||||
*/
|
||||
private fun doIndexSanityCheck() {
|
||||
if (mSong != null && mSong != mQueue[mIndex]) {
|
||||
val correctedIndex = mQueue.wobblyIndexOfFirst(mIndex, mSong)
|
||||
|
||||
if (correctedIndex > -1) {
|
||||
logD("Correcting malformed index to $correctedIndex")
|
||||
mIndex = correctedIndex
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Finds the index of an item through a sort-of "wobbly" search where it progressively searches
|
||||
* for item away from the [start] index, instead of from position zero. This is useful, as it
|
||||
* increases the likelihood that the correct index was found instead of the index of a
|
||||
* duplicate.
|
||||
*/
|
||||
private fun <T> List<T>.wobblyIndexOfFirst(start: Int, item: T): Int {
|
||||
if (start !in indices) {
|
||||
return -1
|
||||
}
|
||||
|
||||
var idx = start
|
||||
var multiplier = -1
|
||||
var delta = -1
|
||||
|
||||
while (true) {
|
||||
idx += delta
|
||||
|
||||
if (idx !in indices) {
|
||||
if (-idx !in indices) {
|
||||
return -1
|
||||
}
|
||||
} else if (this.getOrNull(idx) == item) {
|
||||
return idx
|
||||
}
|
||||
|
||||
delta = -delta
|
||||
multiplier = -multiplier
|
||||
delta += multiplier
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* The interface for receiving updates from [PlaybackStateManager].
|
||||
* Add the callback to [PlaybackStateManager] using [addCallback],
|
||||
|
|
|
@ -19,18 +19,12 @@
|
|||
package org.oxycblt.auxio.settings
|
||||
|
||||
import android.content.SharedPreferences
|
||||
import androidx.appcompat.app.AppCompatDelegate
|
||||
import androidx.core.content.edit
|
||||
import org.oxycblt.auxio.accent.ACCENT_COUNT
|
||||
import org.oxycblt.auxio.accent.Accent
|
||||
import org.oxycblt.auxio.playback.state.PlaybackMode
|
||||
|
||||
// A couple of utils for migrating from old settings values to the new
|
||||
// formats used in 1.3.2 & 1.4.0
|
||||
|
||||
// TODO: Slate these for removal eventually. There probably isn't that many left who have the
|
||||
// old values but 2.0.0 will probably convince most of those to update too.
|
||||
|
||||
fun handleAccentCompat(prefs: SharedPreferences): Accent {
|
||||
if (prefs.contains(OldKeys.KEY_ACCENT2)) {
|
||||
var accent = prefs.getInt(OldKeys.KEY_ACCENT2, 5)
|
||||
|
|
|
@ -109,7 +109,7 @@ class SettingsManager private constructor(context: Context) :
|
|||
/** What queue to create when a song is selected (ex. From All Songs or Search) */
|
||||
val songPlaybackMode: PlaybackMode
|
||||
get() = PlaybackMode.fromInt(sharedPrefs.getInt(KEY_SONG_PLAYBACK_MODE, Int.MIN_VALUE))
|
||||
?: PlaybackMode.ALL_SONGS
|
||||
?: PlaybackMode.ALL_SONGS
|
||||
|
||||
/** Whether shuffle should stay on when a new song is selected. */
|
||||
val keepShuffle: Boolean
|
||||
|
|
Loading…
Reference in a new issue