diff --git a/app/src/main/java/org/oxycblt/auxio/playback/state/PlaybackStateManager.kt b/app/src/main/java/org/oxycblt/auxio/playback/state/PlaybackStateManager.kt index fb9cf3092..0fe3b6348 100644 --- a/app/src/main/java/org/oxycblt/auxio/playback/state/PlaybackStateManager.kt +++ b/app/src/main/java/org/oxycblt/auxio/playback/state/PlaybackStateManager.kt @@ -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 List.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], diff --git a/app/src/main/java/org/oxycblt/auxio/settings/SettingsCompat.kt b/app/src/main/java/org/oxycblt/auxio/settings/SettingsCompat.kt index b25c240a5..7c678052e 100644 --- a/app/src/main/java/org/oxycblt/auxio/settings/SettingsCompat.kt +++ b/app/src/main/java/org/oxycblt/auxio/settings/SettingsCompat.kt @@ -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) diff --git a/app/src/main/java/org/oxycblt/auxio/settings/SettingsManager.kt b/app/src/main/java/org/oxycblt/auxio/settings/SettingsManager.kt index 4e8477d39..c2e3c311b 100644 --- a/app/src/main/java/org/oxycblt/auxio/settings/SettingsManager.kt +++ b/app/src/main/java/org/oxycblt/auxio/settings/SettingsManager.kt @@ -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