From a15bc79cc93f1a17b3c3ab178d8f7d50daa15a54 Mon Sep 17 00:00:00 2001 From: OxygenCobalt Date: Mon, 4 Jul 2022 11:20:02 -0600 Subject: [PATCH] music: more hypothetical fixes Fix a bunch of more hypothetical issues that could occur with runtime rescanning. It's still global mutable concurrent state though. Sigh. --- CHANGELOG.md | 2 +- .../java/org/oxycblt/auxio/music/Indexer.kt | 28 +++++++++++-------- .../org/oxycblt/auxio/music/IndexerService.kt | 18 ++++++------ .../auxio/music/backend/ExoPlayerBackend.kt | 1 - .../auxio/music/backend/MediaStoreBackend.kt | 17 ++++++++--- .../playback/state/PlaybackStateManager.kt | 10 +++---- 6 files changed, 44 insertions(+), 32 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index f57cd5492..edf861a3b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,7 +8,7 @@ - Added a shuffle shortcut - Widgets now have a more sleek and consistent button layout - "Rounded album covers" is now "Round mode" -- You can now customize what occurs when a song is played from an album/artist/genre [#164] +- Added option to customize what occurs when a song is played from an album/artist/genre [#164] #### What's Improved - Made "timeline" elements (like playback controls) always left-to-right diff --git a/app/src/main/java/org/oxycblt/auxio/music/Indexer.kt b/app/src/main/java/org/oxycblt/auxio/music/Indexer.kt index d6a25ea07..beb5d6b60 100644 --- a/app/src/main/java/org/oxycblt/auxio/music/Indexer.kt +++ b/app/src/main/java/org/oxycblt/auxio/music/Indexer.kt @@ -167,10 +167,9 @@ class Indexer { } /** - * "Cancel" the last job by making it unable to send further state updates. This should be - * called if an object that called [index] is about to be destroyed and thus will have it's task - * canceled, in which it would be useful for any ongoing loading process to not accidentally - * corrupt the current state. + * "Cancel" the last job by making it unable to send further state updates. This will cause the + * worker operating the job for that specific generation to cancel as soon as it tries to send a + * state update. */ @Synchronized fun cancelLast() { @@ -182,11 +181,17 @@ class Indexer { @Synchronized private fun emitIndexing(indexing: Indexing?, generation: Long) { if (currentGeneration != generation) { - // Not the running task anymore, cancel this co-routine - // We do this instead of using yield since it is *far* cheaper. + // Not the running task anymore, cancel this co-routine. This allows a yield-like + // behavior to be implemented in a far cheaper manner for each backend. throw CancellationException() } + if (indexing == indexingState) { + // Ignore redundant states used when the backends just want to check for + // a cancellation + return + } + indexingState = indexing // If we have canceled the loading process, we want to revert to a previous completion @@ -201,11 +206,14 @@ class Indexer { @Synchronized private fun emitCompletion(response: Response, generation: Long) { if (currentGeneration != generation) { - // Not the running task anymore, cancel this co-routine - // We do this instead of using yield since it is *far* cheaper. + // Not the running task anymore, cancel this co-routine. This allows a yield-like + // behavior to be implemented in a far cheaper manner for each backend. throw CancellationException() } + // Do not check for redundancy here, as we actually need to notify a switch + // from Indexing -> Complete and not Indexing -> Indexing or Complete -> Complete. + lastResponse = response indexingState = null @@ -284,9 +292,7 @@ class Indexer { "Successfully queried media database " + "in ${System.currentTimeMillis() - start}ms") - backend.buildSongs(context, cursor) { indexing -> - emitIndexing(indexing, generation) - } + backend.buildSongs(context, cursor) { emitIndexing(it, generation) } } // Deduplicate songs to prevent (most) deformed music clones diff --git a/app/src/main/java/org/oxycblt/auxio/music/IndexerService.kt b/app/src/main/java/org/oxycblt/auxio/music/IndexerService.kt index 598f166b5..3a828a0d2 100644 --- a/app/src/main/java/org/oxycblt/auxio/music/IndexerService.kt +++ b/app/src/main/java/org/oxycblt/auxio/music/IndexerService.kt @@ -112,17 +112,15 @@ class IndexerService : Service(), Indexer.Controller, Settings.Callback { // Load was completed successfully. However, we still need to do some // extra work to update the app's state. updateScope.launch { - // Invalidate the image cache, as there may be some covers that are - // no longer valid. - imageLoader.memoryCache?.clear() - if (musicStore.library != null) { - // This is a new library, so we need to make sure the playback state - // is coherent. This seems a bit muddly, but PlaybackService (or any - // other playback component capable of handling this) may not be - // capable of long-running background work as the library is being - // updated. The initialization steps on the other hand are firmly in - // the place of the playback module. + // This is a new library to replace a pre-existing one. + + // Wipe possibly-invalidated album covers + imageLoader.memoryCache?.clear() + + // PlaybackStateManager needs to be updated. We would do this in the + // playback module, but this service could is the only component + // capable of doing long-running background work as it stands. playbackManager.sanitize( PlaybackStateDatabase.getInstance(this@IndexerService), newLibrary) } diff --git a/app/src/main/java/org/oxycblt/auxio/music/backend/ExoPlayerBackend.kt b/app/src/main/java/org/oxycblt/auxio/music/backend/ExoPlayerBackend.kt index c5377e6fe..b91d24f12 100644 --- a/app/src/main/java/org/oxycblt/auxio/music/backend/ExoPlayerBackend.kt +++ b/app/src/main/java/org/oxycblt/auxio/music/backend/ExoPlayerBackend.kt @@ -242,7 +242,6 @@ class Task(context: Context, private val audio: MediaStoreBackend.Audio) { } private fun populateVorbis(tags: Map) { - logD(tags) // Title tags["TITLE"]?.let { audio.title = it } diff --git a/app/src/main/java/org/oxycblt/auxio/music/backend/MediaStoreBackend.kt b/app/src/main/java/org/oxycblt/auxio/music/backend/MediaStoreBackend.kt index 78b7ab7d2..854bf7dc4 100644 --- a/app/src/main/java/org/oxycblt/auxio/music/backend/MediaStoreBackend.kt +++ b/app/src/main/java/org/oxycblt/auxio/music/backend/MediaStoreBackend.kt @@ -177,13 +177,13 @@ abstract class MediaStoreBackend : Indexer.Backend { cursor: Cursor, emitIndexing: (Indexer.Indexing) -> Unit ): List { - // Note: We do not actually update the callback with a current/total value, this is because - // loading music from MediaStore tends to be quite fast, with the only bottlenecks being - // with genre loading and querying the media database itself. As a result, a progress bar - // is not really that applicable. val audios = mutableListOf