From 4d22b99577522c7fb36d5762d4e80feb40cffb01 Mon Sep 17 00:00:00 2001 From: OxygenCobalt Date: Sat, 5 Feb 2022 11:36:55 -0700 Subject: [PATCH] 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. --- .../playback/state/PlaybackStateManager.kt | 49 ++++++++++++++++++- .../oxycblt/auxio/settings/SettingsCompat.kt | 6 --- .../oxycblt/auxio/settings/SettingsManager.kt | 2 +- 3 files changed, 49 insertions(+), 8 deletions(-) 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